Тема решения
Правильная команда для ответа на заданный вопрос может быть любой из следующих (при условии, что ветвь topic
уже извлечена):
git rebase --onto B master
git rebase --onto master~1 master
git rebase --onto B A
git rebase --onto B C
git rebase --onto B
Если topic
не отмечен, вы просто добавляете topic
к команде (кроме последней) следующим образом:
git rebase --onto B master topic
В качестве альтернативы сначала проверьте ветку с помощью:
git checkout topic
Перебазировать любую строку коммитов в целевой коммит
Базовая форма нужной нам команды, взятая из документации:
git rebase --onto <Target> [<Upstream> [<Branch>]]
<Branch>
является необязательным, и все, что он делает, - проверяет ветвь, указанную перед выполнением остальной части команды. Если вы уже отметили ветку, которую хотите перебазировать, то вам это не нужно. Обратите внимание, что вы должны указать <Upstream>
, чтобы указать <Branch>
, или git подумает, что вы указываете <Upstream>
.
<Target>
- это коммит, к которому мы прикрепим нашу строку коммитов. Предоставляя имя ветки, вы просто указываете главный коммит этой ветки. <Target>
может быть любым коммитом, который не будет содержаться в строке перемещаемых коммитов. Например:
A --- B --- C --- D master
\
\-- X --- Y --- Z feature
Чтобы переместить всю ветвь объекта, вы не можете выбрать X
, Y
, Z
или feature
в качестве <Target>
, поскольку все они являются коммитами внутри перемещаемой группы.
<Upstream>
особенный, потому что это может означать две разные вещи. Если это коммит, который является предком проверенной ветви, то он служит точкой вырезания. В приведенном мною примере это будет что-то, что не является C
, D
или master
. Все коммиты после <Upstream>
до тех пор, пока не будет перемещен заголовок извлеченной ветви.
Однако, если <Upstream>
не является предком, то git выполняет резервное копирование цепочки из указанного коммита до тех пор, пока if не найдет общего предка с извлеченной ветвью (и не прекратит работу, если не может его найти). В нашем случае <Upstream>
из B
, C
, D
или master
приведет к тому, что коммит B
будет служить точкой отсечения. <Upstream>
сама по себе является необязательной командой, и если она не указана, то git просматривает родителя извлеченной ветви, что эквивалентно вводу master
.
Теперь, когда git выбрал коммиты, которые он будет резать и перемещать, он применяет их для <Target>
, пропуская все, что уже применено к цели.
Интересные примеры и результаты
Используя эту отправную точку:
A --- B --- C --- D --- E master
\
\-- X --- Y --- Z feature
git rebase --onto D A feature
Применит коммиты B
, C
, X
, Y
, Z
для фиксации D
и пропустит B
и C
, поскольку они уже были применены.
git rebase --onto C X feature
Применит коммиты Y
и Z
для фиксации C
, эффективно удаляя коммит X