Простой способ сделать это - использовать интерактивное перебазирование .
Если вы запустите git log --oneline
в своей ветке, вы должны увидеть что-то похожее на это:
ccccccc (HEAD -> your-branch-name) Your (good) commit you want to keep
bbbbbbb bbbbbbb Your (bad) commit you want to remove from history
aaaaaaa (master) Commit from you or someone else

Вы говорите, что хотите удалить bbbbbbb
, заменив его на ccccccc
.
Поскольку ccccccc
содержит изменения, начиная с bbbbbbb
, его удаление может вызвать множество конфликтов, так как вам придется объединить ccccccc
в aaaaaaa
.
git
способ сделать это, это сквош ccccccc
в bbbbbbb
, создав новый коммит ddddddd
.И для этого вы должны сделать следующие шаги:
1 .Запустите git rebase -i aaaaaaa
, чтобы открыть интерактивную перебазировку, начиная с коммита, непосредственно перед тем, который вы хотите удалить
Это откроет ваш сконфигурированный текстовый редактор с чем-то вроде этого:
pick bbbbbbb Your (bad) commit you want to remove from history
pick ccccccc Your (good) commit you want to keep
# Rebase aaaaaaa..f5a9551 onto aaaaaaa (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
#
# Note that empty commits are commented out
В списке показано, что будет делать интерактивная перебазировка: с aaaaaaa
выберите bbbbbbb
, затем выберите ccccccc
2 .Как я уже говорил выше, вы хотите сквош ccccccc
в bbbbbbb
, поэтому замените слово pick
перед ccccccc
на squash
:
pick bbbbbbb Your (bad) commit you want to remove from history
squash ccccccc Your (good) commit you want to keep
3 .Сохраните файл и закройте текстовый редактор.
4 .Откроется другой текстовый редактор, который попросит вас указать сообщение о создании нового коммита, с комбинацией ccccccc
и bbbbbbb
, которую я называю ddddddd
для примера:
# This is a combination of 2 commits.
# This is the 1st commit message:
Your (bad) commit you want to remove from history
# This is the commit message #2:
Your (good) commit you want to keep
Здесь вы, вероятно, хотите удалить все, кроме последней строки, в которой есть сообщение о вашем последнем коммите, но вы можете настроить сообщение так, как вам нравится.
5 .Сохраните файл и закройте текстовый редактор.
Восстановление выполнено, и ваша история должна выглядеть следующим образом:
ddddddd (HEAD -> your-branch-name) Your (good) commit you want to keep
aaaaaaa (master) Commit from you or someone else

6 .Теперь все, что вам нужно сделать, - это отправить ветку обратно на ваш origin
(например, GitHub / BitBucket / GitLab) и т. Д., Чтобы обновить ваш pull-запрос.
Для этого выВам нужно будет сделать push --force
, чтобы ваша удаленная ветвь была заменена этой новой.
git push origin your-branch-name --force

Конечно, у вас всегда есть возможность закрыть предыдущий пул-запрос и вместо него открыть новый (с другим именем ветви).