Если вы опубликовали, то вы правы, что не хотите переписывать историю master
. Вам нужно опубликовать коммит в master, который вернет его в состояние, в котором он был D
, сохранив его текущую историю, чтобы другие пользователи могли легко объединять или перебазировать свою работу.
Если вы планируете в какой-то момент в будущем объединить topic
в master
, то, вероятно, вы также захотите создать новую общую базу между master
и topic
, чтобы при затем объедините topic
, вы не потеряете коммиты, которые были возвращены в master
. Самый простой способ сделать это - сделать коммит 'redo' поверх коммита 'undo', который сбрасывает master
обратно в исходное состояние и основывает новую ветвь topic
поверх этого.
# checkout master branch (currently at G)
git checkout master
# Reset the index to how we want master to look like
git reset D
# Move the branch pointer back to where it should be, leaving the index
# looking like D
git reset --soft HEAD@{1}
# Make a commit (D') for the head of the master branch
git commit -m "Temporarily revert E, F and G"
# Create the new topic branch based on master.
# We're going to make it on top of master and the 'undo'
# commit to ensure that subsequent merges of master->topic
# or topic->master don't merge in the undo.
git checkout -b topic
# Revert the undo commit, making a redo commit (G').
git revert HEAD
В качестве альтернативы вы могли бы сделать коммиты E ', F' и G ', переделывая каждую часть в отдельности, но, поскольку E, F и G уже есть в вашей опубликованной истории, вероятно, более понятно, если вы просто ссылаетесь на коммит' undo 'и сказать, что этот коммит отменяется. Это то, что git revert
делает, так или иначе.
По сути, вы знаете, что это.
D -- E -- F -- G -- D' <-- master
\
\
G' <-- topic
Важно то, что вы не переписали историю, а тема основана на master, поэтому слияния не будут случайным образом применять любые 'отмены' коммитов. Теперь вы можете безопасно нажать master
и topic
в удаленном хранилище.