Начиная с git 1.9 / 2.0 Q1 2014, вам не нужно будет отмечать свое предыдущее происхождение ветви, прежде чем перебазировать его в переписанной ветке upstream, как описано в Aristotle Pagaltzis ' answer :
См. commit 07d406b и commit d96855f :
После работы с веткой topic
, созданной с помощью git checkout -b topic origin/master
, историяветви удаленного отслеживания origin/master
, возможно, были перемотаны и перестроены, что привело к истории этой формы:
o---B1
/
---o---o---B2--o---o---o---B (origin/master)
\
B3
\
Derived (topic)
, где origin/master
используется для указания на коммиты B3
, B2
, B1
и теперь он указывает на B
, и ваша ветвь topic
была запущена поверх него, когда origin/master
был на B3
.
Этот режим использует reflog из origin/master
, чтобы найти B3
в качестве точки разветвления, так что topic
может быть перебазирован поверх обновленного origin/master
:
$ fork_point=$(git merge-base --fork-point origin/master topic)
$ git rebase --onto origin/master $fork_point topic
Поэтому в команде git merge-base
появилась новая опция:
--fork-point::
Найти точку, в которой ветвится(или любая история, которая приводит к <commit>
), разветвленная из другой ветви (или любая ссылка) <ref>
.
Это не просто ищет общего предка двух коммитов, но также учитываетReflog <ref>
, чтобы увидеть, если история, ведущая к <commit>
, разветвлена от более раннего воплощения ветви <ref>
.
"git pull --rebase
«команда вычисляет точку ветвления перебазируемой ветви с использованием записей reflog ветви« base
»(обычно ветки с удаленным отслеживанием), на которой была основана работа ветви, чтобы справиться со случаем, в котором« base »Филиал был перемотан и перестроен.
Например, если история выглядела следующим образом:
- текущая вершина ветви "
base
" находится на B
, но раньшеfetch заметил, что его наконечник имел обыкновение быть B3
, а затем B2
, а затем B1
до получения текущего коммита, и - ветвь, перебазируемая поверх последней "базы", основана наcommit
B3
,
пытается найти B3
, выполняя вывод "git rev-list --reflog base
" (то есть B
, B1
, B2
, B3
)пока он не найдет коммит, который является предком текущего наконечника "Derived (topic)
".
Внутренне, у нас есть get_merge_bases_many()
, который может вычислить это за один раз.
Мы бы хотели объединитьоснование между Derived
и вымышленным коммитом слияния, которое получилось бы в результате слияния всех исторических подсказок "base (origin/master)
".
Когда такой коммит существует, мы должны получить один результат, который точно соответствует одной из записей reflog"base
".
Git 2.1 (3 квартал 2014 г.) добавит сделать эту функцию более надежной: см. commit 1e0dacd by John Keeping (johnkeeping
)
правильно обрабатывает сценарий, в котором мы имеем следующую топологию:
C --- D --- E <- dev
/
B <- master@{1}
/
o --- B' --- C* --- D* <- master
где:
B'
- это исправленная версия B
, которая не идентична патчу с B
; C*
и D*
идентичны патчуC
и D
соответственно и конфликтуют текстуально, если применяются в неправильном порядке; E
зависит текстуально от D
.
Правильный результат git rebase master dev
означает, что B
идентифицируется как точка разветвления dev
и master
, так что C
, D
, E
являются коммитами, которые необходимо воспроизвести на master
;но C
и D
идентичны патчам с C*
и D*
и поэтому могут быть отброшены, так что конечный результат будет:
o --- B' --- C* --- D* --- E <- dev
Если точка разветвления не определеназатем выбор B
для ветви, содержащей B'
, приводит к конфликту, и если идентичные патчу коммиты не идентифицированы правильно, то выбор C
для ветви, содержащей D
(или эквивалентно D*
), приводит кконфликт.