Я недавно писал на эту тему в блоге :
Как мы будем обновлять эту функциональную ветку? Слияние новейших коммитов восходящего потока легко, но вы хотите избежать создания коммитов слияния, так как это не будет оценено при передаче в восходящий поток: тогда вы эффективно повторно фиксируете изменения восходящего потока, и эти коммиты восходящего потока получат новый хэш ( когда у них появляется новый родитель). Это особенно важно, поскольку эти объединенные коммиты будут отражены в вашем запросе на перенос на GitHub, когда вы отправите эти обновления в свою личную ветку функций GitHub (даже если вы сделаете это после того, как отправили запрос на перенос).
Вот почему нам нужно перебазировать вместо слияния:
git co devel #devel is ansible's HEAD aka "master" branch
git pull --rebase upstream devel
git co user-non-unique
git rebase devel
И опция rebase, и команда rebase в git сохранят ваше дерево в чистоте и позволят избежать коммитов слияния. Но имейте в виду, что это ваши первые коммиты (с которыми вы выпустили свой первый запрос на перенос), которые перебазируются, и у которых теперь есть новый хэш фиксации, который отличается от исходных хэшей, которые все еще находятся в вашей удаленной ветке репозитория github. .
Теперь отправка этих обновлений в вашу личную функциональную ветку GitHub не удастся, поскольку обе ветви различаются: локальное дерево ветки и дерево удаленной ветки «не синхронизированы» из-за этих разных хэшей фиксации. Git скажет вам сначала git pull --rebase
, а затем нажмите еще раз, но это не будет простой перемоткой вперед, поскольку ваша история была переписана. Не делай этого!
Проблема здесь в том, что вы снова получите свои первые измененные коммиты в том виде, в каком они были изначально, и они будут объединены поверх вашей локальной ветки. Из-за состояния рассинхронизации это извлечение не применяется чисто. Вы получите неработающую историю, в которой ваши коммиты появляются два раза. Когда вы отправляете все это в свою ветку функций GitHub, эти изменения будут отражены в исходном запросе на перенос, который станет очень и очень некрасивым.
AFAIK, на самом деле нет абсолютно чистого решения для этого. Лучшее решение, которое я нашел, - заставить вашу локальную ветку переместиться в ветку GitHub (на самом деле принудительное обновление без быстрой перемотки вперед):
Согласно git-push (1):
Update the origin repository’s remote branch with local branch, allowing non-fast-forward updates. This can leave unreferenced commits dangling in the origin repository.
Так что не тяните, просто нажимайте с силой, вот так:
git push svg +user-non-unique
или:
git push svg user-non-unique --force
Это фактически просто перезапишет вашу удаленную ветку всем, что находится в вашей локальной ветке. Коммиты, которые находятся в удаленном потоке (и вызвали сбой), останутся там, но будут зависшими коммитами, которые в конечном итоге будут удалены с помощью git-gc (1). Ничего страшного.
Как я уже сказал, это самое чистое решение AFAICS. Обратной стороной этого является то, что ваш PR будет обновляться с учетом этих новейших коммитов, которые будут иметь более позднюю дату и могут отображаться не синхронизированно в истории комментариев PR. Нет большой проблемы, но это может сбивать с толку.