Начиная с мерзавцем 1,9 / 2,0 Q1 2014, вы не должны будете отмечать свой предыдущий филиал происхождения , прежде чем перебазирования его на переписанной вверх по течению ветви, как описано в Аристотель Pagaltzis «s ответ :
См совершать 07d406b и совершать 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
.
В этом режиме в качестве точки разветвления используется журнал 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>
.
Это не просто ищет общего предка двух коммитов, но также принимает во внимание рефлог, <ref>
чтобы увидеть, была ли история, ведущая к <commit>
разветвлению, от более раннего воплощения ветки<ref>
.
Команда « git pull --rebase
» вычисляет точку разветвления ветвления, для которой выполняется перебазирование с использованием записей рефлога base
ветви « » (обычно ветки удаленного отслеживания), на которой была основана работа ветки, чтобы справиться со случаем, когда «база» ветка была перемотана и перестроена.
Например, если история выглядела так, где:
- текущая вершина
base
ветки " " находится в точке B
, но более ранняя выборка заметила, что ее вершина была раньше, B3
а затем B2
и затем B1
до перехода к текущей фиксации, и
- перебазируемая ветка поверх последней "базы" основана на фиксации
B3
,
он пытается найти B3
, перейдя через выход « git rev-list --reflog base
» (т.е. B
, B1
, B2
, B3
) до тех пор , пока не найдет фиксации , что является предком текущего наконечника « Derived (topic)
».
Внутри у нас есть get_merge_bases_many()
способ вычислить это за один раз.
Нам нужна база Derived
для слияния и фиктивная фиксация слияния, результатом которой станет объединение всех исторических подсказок " base (origin/master)
".
Когда такая фиксация существует, мы должны получить единственный результат, который точно соответствует одной из записей рефлога " base
".
Git 2.1 (3 квартал 2014 г.) добавит, чтобы эта функция была более надежной: см. Commit 1e0dacd от 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*
), приводит к конфликту.
« --fork-point
» Режим « git rebase
» регресс , когда команда была переписана в С задней в 2.20 эре, которая была исправлена с Git 2,27 (Q2 2020).
См. Фиксацию f08132f (09 декабря 2019 г.) от Junio C Hamano ( gitster
) .
(Объединено Junio C Hamano - gitster
- в коммите fb4175b , 27 марта 2020 г.)
rebase
: --fork-point
исправление регрессии
Подписано: Алекс Торок
[jc: обновил исправление и использовал тесты Алекса]
Подписано: Junio C Hamano
" git rebase --fork-point master
" работал нормально, так как он внутренне называл " git merge-base --fork-point
", который знал, как обрабатывать короткое имя ссылки и сокращать его до полного имени ссылки перед вызовом базовой get_fork_point()
функции.
Это больше не верно после того, как команда была переписана на C, поскольку ее внутренний вызов, сделанный напрямую get_fork_point()
, не уменьшает краткую ссылку.
Переместите логику «dwim the refname to the full refname», которая используется в «git merge-base», в базовую get_fork_point()
функцию, чтобы другой вызывающий функцию в реализации «git rebase» вел себя так же, чтобы исправить это регресс.