В истории моей ветки C
есть один коммит master
, который, как мы решили, нуждается в доработке. Это не последний коммит. С тех пор было сделано более 10 коммитов. К счастью, ни один из последующих коммитов не затронул файлы, измененные C
.
Я хочу удалить этот коммит из ветки master и одновременно создать новую ветку test-c
из изменений в C
. Таким образом, над ним можно будет проделать больше работы, а затем его можно будет объединить в master
.
Итак, я хочу пойти от этого:
---A---B---C---D---E (master)
к этому
---A---B---D---E (master)
\
'---C (test-c)
или даже просто к этому было бы нормально (могу потом слить)
---A---B---D---E (master)
\
'---C (test-c)
единственный релевантный ответ, который я смог найти, звучит так, как будто мне нужно либо написать скрипт, либо вручную перебазировать каждый последующий главный коммит (после C
) на предыдущий. Я боюсь этого. Но этому ответу 9 лет, поэтому я надеюсь, что есть лучший способ.
Есть ли более простой способ сделать это в Visual Studio 2022 (или Tortoise Git, который я тоже использую)? Я посмотрел, что дал мне VS, когда я щелкнул правой кнопкой мыши по этому коммиту в истории веток master
. Я вижу следующие варианты
Что-то из этого то, что я хочу? Или я должен сделать все это перебазирование? В последнем случае я бы просто добавил реверсивную фиксацию в мастер, затем создал ветку с изменениями и пусть история выглядит загроможденной)
Вы можете отменить фиксацию (оставив ее в истории), создать новую ветку, а затем выбрать исходную фиксацию. Переписывание опубликованной истории имеет много проблем, поэтому предлагаю отменить изменения коммита.
Требуется сбор вишни, потому что в противном случае отмененные изменения не будут объединены снова.
git checkout master
git revert bad-commit
git checkout -b more-work
git cherry-pick bad-commit
Если вам действительно нужно избавиться от исходного коммита (удалить его из истории, а не просто отменить его изменения), вы можете использовать (интерактивную) перебазировку. Интерактивный:
git branch more-work bad-commit
git rebase -i bad-commit^ master
pick
на drop
(или удалите ее вообще`Не интерактивный:
git branch more-work bad-commit
git rebase --onto bad-commit^ bad-commit master
я бы сделал вот так
git rebase -i C~
# in the list of revisions, take the first line (C) and move it to be the last line. Save / exit
rebase должен запуститься, и теперь ветка должна быть A <- B <- D <- E <- C
с master
, указывающим на C
(ну, на самом деле, C'
. На самом деле это не оригинальная версия C).
Как обычно в этом случае, считайте, что вы переписывание истории ветки, и если эта ветка уже была разделена (другие люди уже работают с ней наверху), то попытка осуществить это вполне возможна, но болезненна, так что другие люди начнут использовать только что перебазированную ветка.
Ваш связанный ответ говорит о разных зависимых ветвях, ваш вопрос показывает только одну ветвь. Вот почему связанный ответ сложнее