Git: как перебазировать конкретную фиксацию в прошлом?

Я хотел бы переустановить конкретную фиксацию, которая не является HEAD другой ветки, а идет назад:

A --- B --- C          master
            \
             \-- D --- E   topic

to

A --- B --- C          master
      \
       \-- D --- E   topic

Как мне добиться этого элегантным и общим способом?

Под общим я подразумеваю, что целевая фиксация (B) не обязательно может быть прямым предком HEAD (я мог бы также перебазировать A или предыдущую фиксацию) и что может быть намного больше, чем просто две фиксации в тематической ветке. Я также мог бы захотеть перебазироваться с B на A.


person Krzysiek Karbowiak    schedule 08.11.2019    source источник
comment
Я думаю, что git rebase --onto B --root master должно работать. (просто используйте --onto A --root B при перемещении с B на A).   -  person Joachim Sauer    schedule 08.11.2019
comment
Делайте то, что предлагает @JoachimSauer, просто убедитесь, что вы находитесь в тематической ветке, когда делаете это.   -  person John Szakmeister    schedule 08.11.2019
comment
@JohnSzakmeister Или git rebase master topic --onto B.   -  person alfunx    schedule 08.11.2019
comment
@alfunx Это тоже сработает ... хотя лично мне это не нравится - я всегда чувствую, что аргументы следует поменять местами, - поэтому я предпочитаю другую версию, так как я никогда не могу вспомнить порядок из головы. :-)   -  person John Szakmeister    schedule 08.11.2019
comment
@JohnSzakmeister Я просто набираю команду, предполагая, что нахожусь в правильной ветке, а затем добавляю второй аргумент позже, если это не так. Но я согласен — это может сбивать с толку.   -  person alfunx    schedule 08.11.2019


Ответы (1)


Использование git cherry-pick

git rebase это git cherry-pick на стероидах.

Если у вас есть только несколько коммитов для перемещения: вы можете использовать git cherry-pick, чтобы выбрать их один за другим.

# move back to B
git checkout B

# start a branch here, and use it as the active branch
git checkout -b wip

# cherry-pick the commits you want to have
git cherry-pick D
git cherry-pick E

# if all went well : move the 'topic' branch to the current branch :
git checkout topic
git reset --hard wip

# delete the temporary 'wip' branch
git branch -d wip

Использование git rebase

Как упоминалось в комментариях: git rebase может использовать дополнительные параметры для перемещения только диапазона коммитов.

Вы можете сделать то же самое, что и в приведенной выше последовательности cherry-pick, используя:

git rebase --onto B master topic

Дополнительное примечание: git rebase -i

git rebase также имеет флаг --interactive|-i:

git rebase -i --onto B master topic

С флагом -i: прежде чем что-либо делать, git откроет для вас текстовый редактор, где будут перечислены все перебазированные коммиты.

Этот шаг имеет очевидное преимущество, поскольку показывает вам, что будет применено (до фактического применения), а также описывает больше действий, чем просто «выбор этой фиксации».

Вы можете поискать в Интернете более подробные руководства по git rebase -i, вот одно из них:
Git Interactive Rebase, Squash, Amend и другие способы перезаписи истории (thoughtbot.com)

person LeGEC    schedule 08.11.2019