Начиная с мерзавцем 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» вел себя так же, чтобы исправить это регресс.