Git отслеживание веток
Я создал локальный репозиторий и перенес все изменения в github. Позже я создал новую ветку ("git branch v2") под названием "v2", сделал некоторые изменения и перенес эту ветку в github. Позже, когда я выполнял команду "git remote show origin", я получаю следующий вывод.
* remote origin
Fetch URL: https://github.com/mayuran19/se24_P03.git
Push URL: https://github.com/mayuran19/se24_P03.git
HEAD branch: master
Remote branches:
master tracked
v2 tracked
Local branch configured for 'git pull':
master merges with remote master
Local refs configured for 'git push':
master pushes to master (local out of date)
v2 pushes to v2 (local out of date)
Но когда я выполнял команду "git branch -vv", он показывает, что ветка "v2" не является ветвью отслеживания.
master bad4ed9 [origin/master] Correct name
* v2 6ec46b0 Data files
Мой вопрос заключается в том, почему ветка v2 не отображается как отслеживаемая ветвь, даже если удаленная ветвь доступна в github, и я могу использовать эту ветвь?
Вывод команды "git branch -a" показывает следующий вывод
master
* v2
remotes/origin/master
remotes/origin/v2
Но не показывает отображение между локальной и удаленной ветвями.
2 ответа
Сначала нам нужно несколько определений.
Локальная ветвь (также называемая просто ветвью без модификатора) - это та, полное имя которой начинается с refs/heads/
, Когда используешь git branch
, вы увидите ваши локальные филиалы по умолчанию. git branch
командование снимает refs/heads/
часть, оставляя вас с такими именами, как master
а также v2
,
Ветвь удаленного отслеживания - это та, полное имя которой начинается с refs/remotes/
(а затем имеет имя удаленного после этого). Когда используешь git branch -r
, команда покажет вам ваши ветки удаленного отслеживания. git branch -r
командование снимает refs/remotes/
часть, оставляя вас с такими именами, как origin/master
а также origin/v2
,
Префикс-стриппинг работает в обоих направлениях: git branch
снимите его, и вы можете оставить его тоже. Это сделано для удобства и работает хорошо до тех пор, пока вы случайно не дадите названия своим (обычным, локальным) ветвям, начинающимся с origin/
, (Если вы случайно назвали местный филиал origin/abc
Например, вы можете запутаться, и полезное удаление git префиксов становится вредным.)
(Обратите внимание, что все эти объекты являются локальными для вашего собственного хранилища, несмотря на название "удаленное отслеживание". Могут также существовать дополнительные ссылки, и вы можете просмотреть их все с git for-each-ref
, который покажет вам все ссылки, используя свое полное имя. Большую часть времени вам это не нужно, и git branch
достаточно.)
(Обычная, локальная) ветка может быть настроена на отслеживание другой ветки. Создание одной ветви отслеживания другой делает для вас несколько вещей, таких как make git status
сообщать вам, когда вы впереди и / или отстаете, и включаете другую ветку в git branch -vv
выход. (Настройка отслеживания - это не то же самое, что ветка удаленного отслеживания. Опять же, локальная ветвь - это та, имя которой начинается с refs/heads/
и его имя не изменяется независимо от того, установлено оно для отслеживания другой ветви. Тем не менее, терминология, безусловно, сбивает с толку.)
Чтобы одна ветка отслеживала другую, сначала проверьте первую ветку (ту, которую вы хотите отслеживать). Затем беги git branch --set-upstream-to otherbranch
, Например, чтобы сделать v2
трек origin/v2
:
git checkout v2
git branch --set-upstream-to origin/v2
Чтобы локальная ветвь отслеживала другую локальную ветвь, просто используйте имя локальной ветки, а не имя удаленной ветки. Чтобы местный филиал прекратил что-либо отслеживать, используйте git branch --unset-upstream
,
Во всем этом есть еще один трюк,1 когда вы спрашиваете git checkout
проверить (но не создать) локальную ветку, которая не существует, git checkout
будет искать, чтобы увидеть, если есть ветка удаленного отслеживания с похожим именем. Если это так, он создаст локальную ветвь и настроит ее для отслеживания ветки удаленного отслеживания. То есть если ветка v2
не существует - например, если вы переименуете или удалите существующий локальный v2
-а также origin/v2
все еще существует, то:
git checkout v2
создает местное отделение v2
и устанавливает его для отслеживания origin/v2
, все сразу.
Ветвь не должна отслеживать другую ветвь, чтобы выдвинуть / извлечь / объединить / перебазировать / вытянуть, но ее настройка как отслеживание может сделать все эти операции более удобными.
1 Как обычно с git, на самом деле есть больше способов заставить локальные ветви отслеживать что-то еще. Вы можете настроить локальный филиал для отслеживания удаленного отслеживания ветви на успешном git push
добавляя -u
на толчок. Вы можете использовать (не рекомендуется) git branch --set-upstream
команда. Вы можете использовать флаги для git checkout
или же git branch
создать или заново создать ветку с набором трекинга. И вы можете использовать git config
(с двумя отдельными git config
команды), чтобы сделать локальную ветвь отслеживать другую ветку.
TL;DR v2
не отслеживаемая ветвь - восходящий поток не установлен. pull
не будет работать (как вы думаете). push
работает из-за правил push по умолчанию.
У меня вопрос, почему ветка v2 не отображается как отслеживаемая ветка
Если вы посмотрите на свой.git/config, вы увидите branch "master"
строфа с отслеживанием информации, но вы не увидите branch "v2"
строфа, т.е. v2
не является ветвью отслеживания.
хотя удаленная ветка доступна в github
Нажатие на ветку без отслеживания не делает ее автоматически отслеживаемой. Вам нужно добавить -u
на ваш толчок, чтобы сделать это. Вы, вероятно, хотели сделать это в первый раз, когда нажали на ветку без отслеживания:
$ git push -u origin v2
я могу сделать тягу и толчок этой ветви
pull
не будет делать то, что вы ожидаете, так как v2
не отслеживает вверх по течению. Это обновит ветку удаленного отслеживания origin/v2
в вашем локальном репо, но он не будет согласовывать (объединять или перебазировать) локальные коммиты в локальном репо v2
ветка с любыми новыми коммитами, сделанными на пульте. Однако, если никто не делает обновления для v2
ветвь на пульте, тогда вы, вероятно, не заметите проблему.
push
работает из-за правил push по умолчанию, которые совпадают на основе имен веток.
Remote branches: master tracked v2 tracked Local branch configured for 'git pull': master merges with remote master Local refs configured for 'git push': master pushes to master (local out of date) v2 pushes to v2 (local out of date)
Remote branches:
раздел показывает ветку удаленного отслеживанияorigin/v2
в вашем локальном репо отслеживает ветку пультаv2
, (Ветка удаленного слеженияorigin/v2
отличается от вашего местногоv2
ветка.)Local branch configured ...
раздел показывает только локальную веткуmaster
зависит отpull
т.е.master
треки дистанционныеmaster
,v2
нет в списке -pull
не повлияет на это, потому что у него нет восходящего набора.Local refs configured ...
раздел показывает вашv2
ветка будет нажимать / обновлять на пультеv2
(и обновитьorigin/v2
) - это основано на правилах соответствия по умолчанию для команды push (также в зависимости от того, какpush.default
конфиг установлен и какая версияgit
ты используешь).
Обратите внимание, что есть небольшое несоответствие или противоречивое поведение между push
а также pull
, Традиционно, push
без полностью указанного refspec arg по умолчанию не заботится об восходящем потоке - он просто выдвигает ветку с тем же именем на удаленном компьютере. Поскольку отслеживаемую удаленную ветку часто называют такой же, как у локальной ветви, все работает, и push
а также pull
Похоже, что обе команды используют настроенную ветвь отслеживания. Тем не мение, push
может не работать должным образом, если локальная ветвь и удаленная ветвь имеют разные имена. Определенные изменения в различных версиях git
в отношении push
а также push.default
т.е. tracking
, current
, а также simple
попробуйте примирить эти различия.
Дополнительное чтение: