TL; DR
Должен ли я явно ... нажать origin
Да, но не совсем так, как вы думаете. Тем не менее, это может быть наиболее удобным.
Long
Каждый репозиторий Git является независимой сущностью. Remotes (как в вашем собственном репозитории) или разветвления (как в GitHub или Bitbucket fork) записывают идентичность другого Git-репозитория, но эти два репозитория остаются отдельными объектами. Таким образом, у каждого есть свои собственные ветви, не используемые совместно с любым другим репозиторием Git.
То, что является общим для других репозиториев Git, но только в «время совместного использования» (git fetch
и git push
) являются коммитами . Они передаются с использованием их необработанных хэш-идентификаторов. Это также то, где имена веток действительно входят в рисунок, потому что репозиторий Git находит его коммиты по его именам веток (и другим ссылкам, но здесь мы сконцентрируемся только на именах ветвей).
Помните, что роль имени ветки в репозитории Git состоит в том, чтобы содержать хэш-идентификатор последнего коммита, который должен рассматриваться "в" этой ветке, т. Е. tip commit филиала. Когда вы используете git checkout <em>branch</em>
, за которым следует возможный git commit
, ваш Git:
- строит новый коммит
- при настройке родительского хеш-идентификатора нового коммита для хеш-идентификатора текущего коммита
- затем записывает новый идентификатор хеша коммита в текущее имя
, чтобы имя ветки снова указывало на последний коммит. Этот коммит наконечника указывает назад на предыдущий совет, который указывает назад на другой предыдущий коммит и т. Д.
Следовательно, git push
делает:
- передать некоторые коммиты, которые в идеале просто расширяют некоторые существующие ветки, тогда
- просит, чтобы другой Git установил свои имена веток, чтобы запомнить самые последние коммиты из этих добавленных коммитов.
(Расширение такой ветви - это ускоренная перемотка вперед .)
Если новый коммит (ы) не просто расширяет некоторые существующие ветки (и), эти конкретные обновления имени (ей) должны быть "принудительными": другой Git просто скажет "нет" те запросы на обновление, которые не являются операциями ускоренной пересылки и не являются принудительными.
Однако не требуется, чтобы эти изменения значения имени ветви соответствовали любым фактическим именам ветви в вашем собственном репозитории. Например, рассмотрим распространенный (по крайней мере для меня) случай, когда я работаю над какой-то функцией, и я пишу полдюжины или более коммитов. Исходя из этого, я определил, что определенно определенно хорошая идея, поэтому я запускаю git rebase -i feature
и ставлю эту задачу впереди. Тогда я могу запустить:
git push origin <hash>:for-review
и сделайте запрос на выборку на основе for-review
. Наглядно то, что у меня есть в моем собственном хранилище на данный момент, выглядит так:
...--o--o <-- origin/feature
\
* <-- origin/for-review
\
o--o--o--o--o <-- feature
Пять из шести коммитов остаются невыполненными; только один, помеченный *
здесь, был добавлен к имени for-review
в хранилище в origin
. Тем не менее я могу продолжать работать в своем собственном репозитории на своей ветке feature
, которая на шесть коммитов опережает origin/feature
и на пять комитетов опережает origin/for-review
. Мне просто нужно быть осторожным, чтобы помнить, что коммит *
теперь используется совместно (что достаточно просто: у него есть имя origin/
, которое может его достичь).
Это подводит нас к тому, что вы должны сделать в своем собственном репозитории, чтобы перенести коммиты из репозитория Git на mainline
в репозиторий на origin
. Сначала вы должны получить коммиты (и их имена, указывающие на подсказки) от mainline
:
git fetch mainline
Теперь у вас есть все коммитов ; теперь вы можете обновить origin
используя, например ::
git push origin mainline/2018.05.x:2018.05.x
, который будет отправлять любые коммиты, которые origin
не имеет, но нуждается в этом, чтобы выполнить эту работу, с последующим созданием имени 2018.05.x
для origin
, указывающего на тот же коммит, что и ваш mainline/2018.05.x
.
По общему признанию, все это немного грязно, но дело в том, что вам не нужно иметь имя ветви для коммитов, если у вас есть некоторое имя от который вы (и ваш Git) можете найти в своем собственном хранилище. Чтобы отправить эти коммиты на другой Git, вы можете git push
их по идентификатору хэша или origin/whatever
имени, или вы можете создать имя ветки, или делать все что угодно как Пока он определяет соответствующий наконечник коммит. Однако в правой части пары имен lhs:rhs
вы должны указать имя, с которым Git на origin
будет в порядке при создании или обновлении.
Удобство
С git push
(но не git fetch
!), Если вы запустите:
git push origin abc
, что "означает" то же самое, что и:
git push origin abc:abc
так что определенно удобно во многих отношениях иметь собственные локальные имена для каждой ветви.