Как я могу отменить `git commit` локально и удаленно после` git push`

242

Я выполнил, git commitа затем git push. Как я могу отменить это изменение как в локальных, так и в удаленных репозиториях?

$ git log
commit 364705c23011b0fc6a7ca2d80c86cef4a7c4db7ac8
Author: Michael Silver <Michael Silver@gmail.com>
Date:   Tue Jun 11 12:24:23 2011 -0700
Майкл
источник

Ответы:

400
git reset --hard HEAD~1
git push -f <remote> <branch>

(Пример нажать: git push -f origin bugfix/bug123)

Это отменит последний коммит и отправит обновленную историю на удаленный компьютер. Вы должны передать, -fпотому что вы заменяете историю восходящего потока в удаленном.

Александр Грос
источник
25
В качестве альтернативы используйте git reset --hard <the-sha-you-want-to-return-to>.
Александр Грос
2
Ссылка называется HEAD (с учетом регистра)
dunni
26
Кроме того, будьте осторожны - AFAIK, вы не должны делать это, если другие люди вышли из репо.
Амадан
1
@BipinVayalu Это влияет на ветку, в которой вы сейчас находитесь. Точнее, ГОЛОВА. HEAD чаще всего «присоединяется» к ветви (указывая на имя ветви вместо прямого указания на коммит). Так что, вообще говоря, это повлияет на ветку, на которую указывает HEAD. Используйте, git log --decorate --onelineчтобы узнать, куда указывает ваша ГОЛОВА.
Александр Грос
4
git reset HEAD~1если вы не хотите, чтобы ваши изменения пропали (непроверенные изменения). Изменить, зафиксировать и нажать еще разgit push -f [origin] [branch]
softvar
161

Как правило, сделать «обратный» коммит, используя:

git revert 364705c

затем отправьте его на пульт как обычно:

git push

Это не удалит коммит: он делает дополнительный коммит, который отменяет то, что сделал первый коммит. Все остальное, не совсем безопасное, особенно когда изменения уже распространены.

Amadan
источник
9
Это более безопасный (и, вероятно, лучший) ответ, чем ответ Александра Гросса (выбранный ответ).
Грэк
6
@Graeck Каждое из решений имеет свои последствия и достоинства.
Александр Грос
5
Это должен быть принятый ответ, лучше никогда не переписывать историю, даже больше, если вы сотрудничаете с командой. git resetпринимается, только если вы еще не отправили изменения на сервер.
Хосе Александр Ибарра
17
@JosueIbarra Я не согласен во всех случаях. В большинстве случаев да, вы не должны перезаписывать историю. Тем не менее, я считаю, что есть законные случаи, когда вы абсолютно должны. Например, вы случайно фиксируете и открываете свой файл секретов. Это не должно быть в git-репо. Таким образом, вы можете быстро удалить его, используя принятый ответ здесь.
bfcoder
11
@bfcoder, если вы передали «секрет» удаленному репо, это больше не секрет. И правильное решение - создать новый секрет, а не пытаться скрыть свою ошибку.
erbsman
41

Прежде всего, Relax.

«Ничто не находится под нашим контролем. Наш контроль - просто иллюзия», «Человеку свойственно ошибаться»

Я понял, что вы непреднамеренно добавили свой код в remote-master. ЭТО будет в порядке.

1. Сначала получите SHA-1значение коммита, который вы пытаетесь вернуть, например, коммит в ветку master. запустите это:

git log

вы увидите кучу строк типа f650a9e398ad9ca606b25513bd4af9fe ... вместе с каждым коммитом. скопируйте этот номер из коммита, который вы хотите вернуть обратно .

2. Теперь введите следующую команду:

git reset --hard your_that_copied_string_but_without_quote_mark

Вы должны увидеть сообщение типа «ГОЛОВА сейчас». вы на свободном Что он только что сделал, это отразил это изменение на местном уровне.

3. Теперь введите следующую команду:

git push -f

вы должны увидеть как

"предупреждение: push.default не установлено; его неявное значение изменилось в ..... ... Всего 0 (дельта 0), повторно использовалось 0 (дельта 0) ... ... your_branch_name -> master (принудительное обновление) «.

Теперь с вами все ясно. Снова проверьте мастер с помощью «git log», ваш fixed_destination_commit должен быть в верхней части списка.

Добро пожаловать (заранее;))

ОБНОВИТЬ:

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

Для этого я бы посоветовал следить за этим блогом или этим постом .

kmonsoor
источник
Это хорошая мера, чтобы указать пульт и ветку тоже при выполнении "git push -f", но "git push -f" будет работать в любом случае большую часть времени
Робсон
8

git reset HEAD~1если вы не хотите, чтобы ваши изменения пропали (непроверенные изменения). Изменить, зафиксировать и снова нажатьgit push -f [origin] [branch]

softvar
источник
3

Вы можете сделать интерактивный ребаз:

git rebase -i <commit>

Это вызовет ваш редактор по умолчанию. Просто удалите строку, содержащую коммит, который вы хотите удалить, чтобы удалить этот коммит.

Вам, конечно, понадобится доступ к удаленному репозиторию, чтобы применить это изменение там же.

Смотрите этот вопрос: Git: удаление выбранных коммитов из репозитория

Джек Эдмондс
источник
3

Попробуйте использовать

git reset --hard <commit id> 

Пожалуйста, обратите внимание: здесь в качестве идентификатора фиксации будет указан идентификатор фиксации, к которому вы хотите перейти, но не идентификатор, который вы хотите сбросить это была единственная точка, где я тоже застрял.

затем нажмите

git push -f <remote> <branch>
Мохит Дхаван
источник
2

В качестве альтернативы:

git push origin +364705c23011b0fc6a7ca2d80c86cef4a7c4db7ac8^:master

Принудительная ветка master удаленного репозитория origin родительскому элементу последнего коммита

MicRum
источник