Расширяя то, что я написал в комментарии
Общее правило заключается в том, что вы не должны переписывать (изменять) историю, которую вы опубликовали, потому что кто-то мог основывать свою работу на этом. Если вы переписываете (изменяете) историю, у вас возникают проблемы со слиянием их изменений и их обновлением.
Таким образом, решение заключается в создании нового коммита, который отменяет изменения , от которых вы хотите избавиться. Вы можете сделать это с помощью git revert команду .
У вас следующая ситуация:
A <- B <- C <- D <- master <- HEAD
(здесь стрелки указывают направление указателя: ссылка «родитель» в случае фиксации, верхняя фиксация в случае заголовка ветви (ссылка на ветвь) и имя ветви в случае ссылки на HEAD).
Вам нужно создать следующее:
A <- B <- C <- D <- [(BCD) ^ - 1] <- master <- HEAD
где «[(BCD) ^ - 1]» означает коммит, который отменяет изменения в коммитах B, C, D. Математика говорит нам, что (BCD) ^ - 1 = D ^ -1 C ^ -1 B ^ -1, поэтому Вы можете получить необходимую ситуацию, используя следующие команды:
$ git revert --no-commit D
$ git revert --no-commit C
$ git revert --no-commit B
$ git commit -m "the commit message"
Альтернативным решением будет извлечение содержимого коммита A и принятие этого состояния:
$ git checkout -f A -- .
$ git commit -a
Тогда у вас будет следующая ситуация:
A <- B <- C <- D <- A '<- master <- HEAD
Коммит А 'имеет то же содержимое, что и коммит А, но это другой коммит (сообщение о коммите, родители, дата коммита).
Решение Джеффа Ферланд, модифицированное Чарльз Бейли основывается на ту же идею, но использует GIT сброс :
$ git reset --hard A
$ git reset --soft @{1} # (or ORIG_HEAD), which is D
$ git commit
git push -f HEAD~4:master
(при условии, что удаленная ветвь - master). Да, вы можете нажать любой коммит как этот.