Как мне отменить последние локальные коммиты в Git?

Я случайно зафиксировал не те файлы в Git , но еще не отправил фиксацию на сервер.

Как я могу отменить эти коммиты из локального репозитория?

Ответов (25)

Решение

Отменить фиксацию и повторить

$ git commit -m "Something terribly misguided" # (0: Your Accident)
$ git reset HEAD~                              # (1)
[ edit files as necessary ]                    # (2)
$ git add .                                    # (3)
$ git commit -c ORIG_HEAD                      # (4)
  1. Эта команда отвечает за отмену . Это отменит вашу последнюю фиксацию, оставив ваше рабочее дерево (состояние ваших файлов на диске) нетронутым. Вам нужно будет добавить их снова, прежде чем вы сможете снова зафиксировать их).

  2. Внесите исправления в рабочие файлы дерева.

  3. git add все, что вы хотите включить в свой новый коммит.

  4. Зафиксируйте изменения, повторно используя старое сообщение фиксации. resetскопировал старую голову в .git/ORIG_HEAD; commitwith -c ORIG_HEADоткроет редактор, который изначально содержит сообщение журнала из старого коммита и позволяет вам его редактировать. Если вам не нужно редактировать сообщение, вы можете использовать эту -Cопцию.

В качестве альтернативы, чтобы отредактировать предыдущую фиксацию (или просто ее сообщение фиксации) , commit --amend добавит изменения в текущем индексе к предыдущей фиксации.

Чтобы удалить (не возвращать) фиксацию, отправленную на сервер , необходимо переписать историю с помощью git push origin master --force .


Дальнейшее чтение

Как я могу переместить HEAD обратно в предыдущее место? (Отдельная голова) & Отменить коммиты

Приведенный выше ответ покажет вам git reflog, что вы можете использовать для определения SHA-1 для фиксации, к которой вы хотите вернуться. Получив это значение, используйте последовательность команд, как описано выше.


HEAD~ то же самое, что и HEAD~1 . Статья Что такое HEAD в git? полезно, если вы хотите отменить несколько коммитов.

Если у вас установлен Git Extras , вы можете запустить его, git undo чтобы отменить последнюю фиксацию. git undo 3 отменит последние три фиксации.

git rm yourfiles/*.class
git commit -a -m "deleted all class files in folder 'yourfiles'"

или

git reset --hard HEAD~1

Предупреждение. Приведенная выше команда навсегда удалит изменения в .javaфайлах (и любых других файлах), которые вы хотели зафиксировать.

Параметр hard reset to HEAD-1 установит вашу рабочую копию в состояние фиксации перед ошибочной фиксацией.

Я хотел отменить последние пять коммитов в нашем общем репозитории. Я нашел идентификатор ревизии, к которой хотел откатиться. Затем я ввел следующее.

prompt> git reset --hard 5a7404742c85
HEAD is now at 5a74047 Added one more page to catalogue
prompt> git push origin master --force
Total 0 (delta 0), reused 0 (delta 0)
remote: bb/acl: neoneye is allowed. accepted payload.
To [email protected]:thecompany/prometheus.git
 + 09a6480...5a74047 master -> master (forced update)
prompt>

Если вы хотите отменить его навсегда и клонировали какой-то репозиторий.

Идентификатор фиксации можно увидеть:

git log 

Тогда вы можете сделать что-то вроде:

git reset --hard <commit_id>

git push origin <branch_name> -f

Я предпочитаю использовать git rebase -i для этой работы, потому что появляется хороший список, в котором я могу выбрать коммиты, от которых нужно избавиться. Возможно, это не так прямо, как некоторые другие ответы здесь, но это просто кажется правильным .

Выберите, сколько коммитов вы хотите перечислить, затем вызовите так (чтобы зарегистрировать последние три)

git rebase -i HEAD~3

Список образцов

pick aa28ba7 Sanity check for RtmpSrv port
pick c26c541 RtmpSrv version option
pick 58d6909 Better URL decoding support

Затем Git удалит коммиты для любой удаляемой строки.

Если вы планируете полностью отменить локальную фиксацию, все, что вы изменили, вы сделали в фиксации, и если вас это не беспокоит, просто выполните следующую команду.

git reset --hard HEAD^1

(Эта команда проигнорирует всю вашу фиксацию, и ваши изменения будут полностью потеряны из вашего локального рабочего дерева). Если вы хотите отменить фиксацию, но хотите, чтобы ваши изменения были внесены в промежуточную область (перед фиксацией, как и после git add ), выполните следующую команду.

git reset --soft HEAD^1

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

git reset HEAD

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

Подробнее (ссылка не работает) ( Архивная версия )

В SourceTree (графический интерфейс для GitHub) вы можете щелкнуть фиксацию правой кнопкой мыши и выполнить « Обратную фиксацию ». Это должно отменить ваши изменения.

На терминале:

В качестве альтернативы вы можете использовать:

git revert

Или:

git reset --soft HEAD^ # Use --soft if you want to keep your changes.
git reset --hard HEAD^ # Use --hard if you don't care about keeping your changes.

"Сбросить рабочее дерево до последней фиксации"

git reset --hard HEAD^ 

«Очистить неизвестные файлы из рабочего дерева»

git clean    

см. - Краткий справочник Git

ПРИМЕЧАНИЕ. Эта команда удалит вашу предыдущую фиксацию, поэтому используйте ее с осторожностью! git reset --hard безопаснее.

Используйте git revert <commit-id> .

Чтобы получить идентификатор фиксации, просто используйте git log .

Одна команда:

git reset --soft 'HEAD^' 

Отлично работает, чтобы отменить последнюю локальную фиксацию!

Как отменить последний коммит Git?

Чтобы восстановить все, как было до последней фиксации, нам нужно выполнить сброс до фиксации перед HEAD.

  1. Если вы не хотите сохранять внесенные вами изменения:

    git reset --hard HEAD^
    
  2. Если вы хотите сохранить изменения:

    git reset --soft HEAD^
    

Теперь проверьте свой журнал git. Это покажет, что наша последняя фиксация была удалена.

Если вы совершили мусор, но не подтолкнули,

git reset --soft HEAD~1

HEAD ~ 1 - это сокращение от коммита перед головой. В качестве альтернативы вы можете обратиться к SHA-1 хэша, если хотите выполнить сброс. Параметр --soft удалит фиксацию, но оставит все ваши измененные файлы «Изменения, подлежащие фиксации», как выразился бы git status.

Если вы хотите избавиться от любых изменений в отслеживаемых файлах в рабочем дереве с момента фиксации перед заголовком, используйте вместо этого « --hard ».

ИЛИ

Если вы уже нажали, а кто-то потянул, что обычно бывает в моем случае, вы не можете использовать git reset . Однако вы можете сделать git revert ,

git revert HEAD

Это создаст новую фиксацию, которая отменяет все, что было внесено случайной фиксацией.

Другой путь:

Проверьте ветку, которую вы хотите вернуть, затем сбросьте локальную рабочую копию обратно до фиксации, которую вы хотите сделать последней на удаленном сервере (все, что будет после нее, будет до свидания). Для этого в SourceTree я щелкнул правой кнопкой мыши и выбрал «Reset BRANCHNAME to this commit».

Затем перейдите в локальный каталог вашего репозитория и выполните эту команду:

git -c diff.mnemonicprefix=false -c core.quotepath=false push -v -f --tags REPOSITORY_NAME BRANCHNAME:BRANCHNAME

Это удалит все коммиты после текущего в вашем локальном репозитории, но только для этой одной ветки.

Первый забег:

git reflog

Он покажет вам все возможные действия, которые вы выполнили в своем репозитории, например, фиксацию, слияние, извлечение и т. Д.

Затем сделайте:

git reset --hard ActionIdFromRefLog

Отменить последнюю фиксацию:

git reset --soft HEAD^ или git reset --soft HEAD~

Это отменит последнюю фиксацию.

Здесь --soft означает возврат к постановке.

HEAD~ или HEAD^ означает перейти к фиксации перед HEAD.


Заменить последнюю фиксацию на новую:

git commit --amend -m "message"

Он заменит последний коммит новым.

Во-первых, запустите эту команду, чтобы сбросить фиксацию: -

git reset --hard HEAD~1

Во-вторых, запустите эту команду, чтобы подтолкнуть новую фиксацию: -

git push upstream head -f

Используйте reflog, чтобы найти правильное состояние

git reflog

рефлог перед РЕФЛОГ ПЕРЕД СБРОСОМ

Выберите правильный журнал ссылок (в моем случае - f3cb6e2) и введите

git reset --hard f3cb6e2

После этого HEAD репо будет сброшен на этот HEADid LOG ПОСЛЕ СБРОСА. сбросить эффект

Наконец, рефлог выглядит как на картинке ниже

рефлог после РЕФЛОГ ФИНАЛ

Просто сбросьте его, выполнив команду ниже, используя git :

git reset --soft HEAD~1

Объясните: что git reset делает, это в основном reset для любого коммита, к которому вы хотите вернуться, тогда, если вы объедините его с --soft ключом, он вернется, но сохраните изменения в своих файлах, чтобы вы вернулись на сцену файл, который был только что добавлен, HEAD является заголовком ветки, и если вы объедините его ~1 (в этом случае вы также используете HEAD^ ), он вернет только одну фиксацию, которую вы хотите ...

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

Как отменить последние коммиты в Git?

Чтобы изменить последнюю фиксацию

Заменить файлы в индексе:

git rm --cached *.class
git add *.java

Затем, если это частная ветка, измените фиксацию:

git commit --amend

Или, если это общая ветка, сделайте новую фиксацию:

git commit -m 'Replace .class files with .java files'


( Чтобы изменить предыдущую фиксацию , используйте потрясающую интерактивную переадресацию .)


ProTip ™: добавьте *.class в gitignore, чтобы это больше не повторялось.


Чтобы отменить фиксацию

Изменение фиксации - идеальное решение, если вам нужно изменить последнюю фиксацию, но более общее решение reset .

Вы можете сбросить Git до любого коммита с помощью:

git reset @~N

Где N количество предыдущих коммитов HEAD, и @~ сбрасывается до предыдущего коммита.

Итак, вместо изменения фиксации вы можете использовать:

git reset @~
git add *.java
git commit -m "Add .java files"

Ознакомьтесь git help reset, в частности, с разделами о --soft --mixed и --hard, чтобы лучше понять, что это делает.

Reflog

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

$ git reset @~
$ git reflog
c4f708b [email protected]{0}: reset: moving to @~
2c52489 [email protected]{1}: commit: added some .class files
$ git reset 2c52489
... and you're back where you started


Добавляйте / удаляйте файлы, чтобы все было так, как вы хотите:

git rm classdir
git add sourcedir

Затем измените фиксацию:

git commit --amend

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

Обратите внимание, что вы должны делать это только в том случае, если вы еще не нажали. Если вы нажали, вам просто нужно будет зафиксировать исправление в обычном режиме.

Есть два способа «отменить» вашу последнюю фиксацию, в зависимости от того, сделали ли вы свою фиксацию общедоступной (отправленной в удаленный репозиторий):

Как отменить локальную фиксацию

Допустим, я совершил локальную фиксацию, но теперь я хочу удалить эту фиксацию.

git log
    commit 101: bad commit    # Latest commit. This would be called 'HEAD'.
    commit 100: good commit   # Second to last commit. This is the one we want.

Чтобы восстановить все, как было до последней фиксации, нам нужно выполнить предыдущую reset фиксацию HEAD :

git reset --soft HEAD^     # Use --soft if you want to keep your changes
git reset --hard HEAD^     # Use --hard if you don't care about keeping the changes you made

Теперь git log покажем, что наша последняя фиксация была удалена.

Как отменить публичную фиксацию

Если вы уже сделали свои коммиты общедоступными, вы захотите создать новый коммит, который «отменит» изменения, сделанные вами в предыдущем коммите (текущая HEAD).

git revert HEAD

Теперь ваши изменения будут отменены и готовы к фиксации:

git commit -m 'restoring the file I removed by accident'
git log
    commit 102: restoring the file I removed by accident
    commit 101: removing a file we don't need
    commit 100: adding a file that we need

Для получения дополнительной информации ознакомьтесь с Git Basics - Undoing Things .

Отменить фиксацию немного страшно, если вы не знаете, как это работает. Но на самом деле это удивительно просто, если вы понимаете. Я покажу вам 4 различных способа отменить фиксацию.

Опция 1: git reset --hard

Скажем, у вас есть это, где C - ваша ГОЛОВКА, а (F) - состояние ваших файлов.

   (F)
A-B-C
    ↑
  master

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

git reset --hard HEAD~1

Результат:

 (F)
A-B
  ↑
master

Теперь B - ГОЛОВА. Поскольку вы использовали --hard, ваши файлы сбрасываются в свое состояние при фиксации B.

вариант 2: git reset

Ах, но предположим, что фиксация C не была катастрофой, а просто немного ошиблась. Вы хотите отменить фиксацию, но оставьте свои изменения для небольшого редактирования, прежде чем вы сделаете лучшую фиксацию. Начнем снова с C в качестве ГОЛОВКИ:

   (F)
A-B-C
    ↑
  master

Вы можете сделать это, оставив --hard :

git reset HEAD~1

В этом случае результат:

   (F)
A-B-C
  ↑
master

В обоих случаях HEAD - это просто указатель на последнюю фиксацию. Когда вы делаете a git reset HEAD~1, вы говорите Git, что нужно переместить указатель HEAD на один коммит назад. Но (если вы не используете --hard ) вы оставляете свои файлы такими, какими они были. Итак, теперь git status показаны изменения, которые вы отметили в C. Вы ничего не потеряли!

вариант 3: git reset --soft

Для легкого прикосновения вы даже можете отменить фиксацию, но оставить свои файлы и индекс :

git reset --soft HEAD~1

Это не только оставляет ваши файлы в покое, но и оставляет в покое ваш индекс . Когда вы это сделаете git status, вы увидите, что в индексе находятся те же файлы, что и раньше. Фактически, сразу после этой команды вы могли бы сделать git commit и повторить тот же самый коммит, который только что сделали.

вариант 4: вы сделали, git reset --hardи вам нужно вернуть этот код

Еще одна вещь: предположим, вы уничтожили фиксацию, как в первом примере, но потом обнаружили, что она вам все-таки нужна ? Не повезло, правда?

Нет, еще есть способ вернуть его. Наберите, git reflog и вы увидите список (частичных) коммитов shas (то есть хэшей), в которые вы переместились. Найдите коммит, который вы уничтожили, и сделайте следующее:

git checkout -b someNewBranchName shaYouDestroyed

Теперь вы воскресили этот коммит. На самом деле коммиты не уничтожаются в Git в течение примерно 90 дней, поэтому вы обычно можете вернуться и спасти тот, от которого не собирались избавляться.

Введите git log и найдите последний хэш-код фиксации, а затем введите:

git reset <the previous co>

Как исправить предыдущую локальную фиксацию

Используйте git-gui (или аналогичный), чтобы выполнить git commit --amend . Из графического интерфейса вы можете добавлять или удалять отдельные файлы из фиксации. Вы также можете изменить сообщение фиксации.

Как отменить предыдущую локальную фиксацию

Просто верните ветку в предыдущее место (например, с помощью gitk или git rebase ). Затем повторно примените изменения из сохраненной копии. После сборки мусора в вашем локальном репозитории это будет похоже на то, что нежелательной фиксации никогда не было. Чтобы сделать все это одной командой, используйте git reset HEAD~1 .

Предупреждение : неосторожное использование git reset- хороший способ привести вашу рабочую копию в запутанное состояние. Я рекомендую новичкам в Git избегать этого, если они могут.

Как отменить публичную фиксацию

Выполните обратный выбор вишни ( git-revert ), чтобы отменить изменения.

Если вы еще не внесли другие изменения в свою ветку, вы можете просто сделать ...

git revert --no-edit HEAD

Затем отправьте обновленную ветку в общий репозиторий.

История коммитов покажет оба коммита по отдельности .


Дополнительно: Исправление частной ветки в публичном репозитории

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

Также обратите внимание: вы не хотите этого делать, если над веткой может работать кто-то другой.

git push --delete (branch_name) ## remove public version of branch

Очистите ветку локально, а затем заново ...

git push origin (branch_name)

В нормальном случае вам, вероятно, не нужно беспокоиться о том, что история коммитов вашей частной ветки будет нетронутой. Просто нажмите последующую фиксацию (см. «Как отменить публичную фиксацию» выше), а затем выполните сквош-слияние, чтобы скрыть историю.