Как узнать, является ли ветка локально отслеживаемой веткой или созданной пользователем локальной веткой? - PullRequest
2 голосов
/ 22 мая 2010

В моем локальном репозитории локально отслеживается удаленная ветка отслеживания с использованием 'git branch -b branch-name origin / branch-name'.Моя удаленная ветка - test2 / test2 (origin / branch-name), которая локально отслеживается как test2.

Источник также называется test2.Я не проверил свою локальную ветку отслеживания test2.

Когда я делаю 'удаленную ветку git pull origin: local-tracked-branch', я получаю эту ошибку

[test2]$ git pull test2 test2: test2 Из / gitvobs / git_bare / test2![отклонено] test2 -> test2 (не ускоренная перемотка вперед)

Принимая во внимание, что когда я проверяю свою локальную ветвь отслеживания test2 и выполняю команду pull 'git pull origin local-tracked-branch', я не получаю ошибкувытягивание с использованием 'git pull test2 test2'

From / gitvobs / git_bare / test2 * branch test2 -> FETCH_HEAD Auto-merging a.txt Ошибка автоматического объединения;исправить конфликты и затем зафиксировать результат.

я знаю, что добавление + (git pull test2 + test2: test2) поможет, но оно перезаписывает локальные изменения.

Так как же узнать, какой измои локальные ветки создаются мной локально с помощью 'git branch new-branch-name' или отслеживаются локально из удаленных веток с помощью git branch -b branch-name origin / branch-name '?

Ответы [ 2 ]

7 голосов
/ 23 мая 2010

git pull Путаница

Более Специфичность

Ваша команда git pull содержит слишком много информации.

[test2] $ git pull test2 test2: test2
От / gitvobs / git_bare / test2
! [отклонено] test2 -> test2 (не ускоренная перемотка вперед)

Я знаю, что добавление + (git pull test2 + test2: test2) помогло бы, но переписало локальные изменения.

Вот что означает ваша команда:

#             *------------ (1) remote repository name
#            /     *------- (2) ref in remote repository
#           /     /     *-- (3) ref in  local repository
#          /     /     /
git pull test2 test2:test2

# Means this: From remote repository `test2` (1),
# fetch branch `test2` (2), store it in local branch `test2` (3), then
# merge the fetched history into HEAD.

Вы говорите git pull перезаписать вашу локальную ветку test2 тем, что есть у пульта на ветке test2, а затем объединить ее с HEAD. Скорее всего, вы не хотите включать часть назначения в refspec (:test2).


Если локальная ветвь, которую вы выбрали, настроена на отслеживание чего-либо (см. «Филиалы:…» ниже), просто выполните

git pull

Если вам необходимо предоставить (или переопределить) удаленный сервер и репозиторий, просто укажите удаленное имя / URL и локальную ветвь на удаленном компьютере (не указывайте последнюю часть refspec):

git pull test2 test2

Потяните в ветку, которая еще не оформлена

git pull - это (как упомянуто выше) комбинация git fetch и git merge (или git rebase ).

Как правило, объединение может включать разрешение конфликтов. Разрешение конфликтов требует рабочего дерева. Следовательно, невозможно выполнить обычную операцию слияния без рабочего дерева. Это означает, что ваш текущий HEAD должен быть одним из родителей слияния (это будет первый родитель). Выполнение перебазировки также требует рабочего дерева для разрешения конфликтов.

Поскольку вытягивание включает слияние или перебазирование, невозможно вытянуть в локальную ветвь, которая не извлечена. Вы можете вытащить только проверенную ветку.

Филиалы: локальные, отслеживание, удаленное отслеживание

Различные типы веток Git являются одним и тем же базовым объектом: refs. Реферы живут в refs/ пространстве имен в $GIT_DIR/refs/ и $GIT_DIR/packed-refs.

  • «Локальные» ветви находятся в пространстве имен refs/heads/.
    • Чтобы проверить test2 местное отделение ref:
      • git show-ref refs/heads/test2 или
        • cat .git/refs/heads/test2 или
        • grep -F refs/heads/test2 .git/packed-refs
  • «Удаленное отслеживание» находятся в пространствах имен refs/remotes/<remote-name>/.
    • Удаленные ветви отслеживания - это локальные копии филиалов из удаленного хранилища.
      • Название «удаленное отслеживание» имеет смысл, когда вы думаете об этом, но его можно спутать с к сожалению названной --track функциональностью git branch и git checkout (см. окончательный тип ветки).
    • Чтобы проверить ветку удаленного отслеживания * 1095, ссылка:
      • git show-ref refs/remotes/test2/test2 или
        • cat .git/refs/remotes/test2/test2 или
        • grep -F refs/remotes/test2/test2 .git/packed-refs
  • Локальные ветви, которые отслеживают другую ветку, являются обычными локальными ветвями (в refs/heads/), которые имеют дополнительную конфигурацию в $GIT_DIR/config:

    [branch "test2"]
            remote = test2
            merge = refs/heads/test2
    

    Важно отметить, что параметр конфигурации merge (или rebase) называет ref на удаленном . Таким образом, refs/heads/test2 здесь означает локальное отделение test2, найденное на удаленном test2. Специальное удаленное имя . можно использовать для ссылки на локальные ветви в локальном хранилище.

    • Цель локальных ветвей, которые «отслеживают» какую-то другую ветку, состоит в том, чтобы упростить просто набрать git pull и заставить его сливать (или перебазировать поверх) историю в какой-то другой ветке.

Вы сказали, что хотите отличить простые простые локальные ветви от локальных ветвей, которые отслеживают какую-то другую ветвь. Вы можете сделать это, посмотрев конфигурацию филиала в файле $GIT_DIR/config.

Вы можете использовать git config для этого:

branch_tracks_something() {
    {
        git config branch."$1".merge ||
        git config branch."$1".rebase
    } >/dev/null 2>&1
}
# test local branch 
branch_tracks_something test2 && echo 'test2 tracks something' || echo 'test2 does not track anything'

Или, если у вас Git 1.6.3 или новее, вы можете использовать формат %(upstream) git for-each-ref :

{ echo 'show_ref_desc() {
    case "$1" in
        refs/heads/*)
            t=''
            test -n "$2" && t=" (tracks $2)"
            echo "local: $1$t"
        ;;
        refs/remotes/*)
           echo "remote tracking: $1"
        ;;
        *)
            echo "other: $1"
        ;;
    esac
}'; git for-each-ref --shell --format='show_ref_desc %(refname) %(upstream)'; } |
sh

Вывод выглядит так:

local: refs/heads/test2 (tracks refs/remotes/test2/test2)
remote tracking: refs/remotes/test2/HEAD
remote tracking: refs/remotes/test2/test2
1 голос
/ 22 мая 2010

Независимо от списка отслеживаемых ветвлений (который вы можете увидеть с помощью git config -l), сообщение "non-fast-forward" означает, что не может объединить удаленную ветвь (то есть локальную копию извлеченного коммитаудаленная ветвь) в вашей ветке, потому что:

  • ваша ветвь имеет собственные коммиты
  • удаленная ветвь имеет новые коммиты с момента последнего нажатия

так:

  --last pull
  |
  v
x-x-x-x-x <--test2
  \
   -y-y-y <-- test2/test2

В то время как это было бы ускоренное слияние

  --last pull
  |
  v
x-x <--test2
  \
   -y-y-y <-- test2/test2

Итак:

git checkout test2
git fetch test2 test2 
git merge test2/test2
#fix conflicts
git commit

И, пожалуйста, позвоните в любое удаленное реподругое имя, чем test2.Здесь слишком много test2;)


Теперь список удаленных веток, отслеживаемых в вашем локальном репо:

git config --get-regexp branch..*
...