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попробуйте примирить эти различия.

Дополнительное чтение:

Другие вопросы по тегам