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

Я случайно совершил неправильные файлы в Git, но я еще не нажал фиксацию на сервер.

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

16493
задан Hamza Yerlikaya 29 мая '09 в 21:09
источник поделиться

77 ответов

  • 1
  • 2
  • 3

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

$ git commit -m "Something terribly misguided"              (1)
$ git reset HEAD~                                           (2)
<< edit files as necessary >>                               (3)
$ git add ...                                               (4)
$ git commit -c ORIG_HEAD                                   (5)
  • Это то, что вы хотите отменить
  • Это оставляет ваше рабочее дерево (состояние ваших файлов на диске) неизменным, но отменяет фиксацию и оставляет внесенные вами изменения неустановленными (поэтому они будут отображаться как "Изменения не поставлены для фиксации" в git status, и вы вам нужно будет добавить их еще до совершения). Если вы хотите добавить больше изменений в предыдущую фиксацию или изменить сообщение фиксации 1 вместо этого вы можете использовать git reset --soft HEAD~, что похоже на git reset HEAD~ (где HEAD~ совпадает с HEAD~1), но ваши текущие изменения будут утеряны.
  • Внести исправления в файлы рабочих деревьев.
  • git add все, что вы хотите включить в свой новый коммит.
  • Завершение изменений, повторное использование старого сообщения фиксации. reset скопировал старую голову в .git/ORIG_HEAD; commit с -c ORIG_HEAD откроет редактор, который изначально содержит сообщение журнала из старого фиксации и позволяет вам его редактировать. Если вам не нужно редактировать сообщение, вы можете использовать опцию -C.

1 Обратите внимание, что вам не нужно reset выполнять более раннюю фиксацию, если вы только что допустили ошибку в своем сообщении о фиксации. Самый простой вариант - git reset (чтобы просмотреть все изменения, которые вы сделали с тех пор), а затем git commit --amend, который откроет ваш текстовый редактор сообщений по умолчанию, предварительно заполненный с последним сообщением фиксации.

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

17513
ответ дан Esko Luontola 29 мая '09 в 21:13
источник поделиться

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

Скажите, что у вас есть это, где C - ваш HEAD и (F) - это состояние ваших файлов.

   (F)
A-B-C
    ↑
  master

Вы хотите выполнить nuke commit C и больше не видеть его. Вы делаете это:

git reset --hard HEAD~1

Результат:

 (F)
A-B
  ↑
master

Теперь B - HEAD. Поскольку вы использовали --hard, ваши файлы reset относятся к их состоянию при фиксации B.

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

   (F)
A-B-C
    ↑
  master

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

git reset HEAD~1

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

   (F)
A-B-C
  ↑
master

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

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

git reset --soft HEAD~1

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

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

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

git checkout -b someNewBranchName shaYouDestroyed

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

9295
ответ дан Ryan Lundy 29 июля '11 в 1:22
источник поделиться

Добавить/удалить файлы, чтобы получить то, что вам нужно:

git rm classdir
git add sourcedir

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

git commit --amend

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

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

1551
ответ дан bdonlan 29 мая '09 в 21:16
источник поделиться

Мне потребовалось некоторое время, чтобы понять, так что, возможно, это поможет кому-то...

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

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

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

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 выполнить commit до 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 Основы - Отменить вещи

1544
ответ дан Andrew 16 июня '11 в 20:27
источник поделиться
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 установит вашу рабочую копию в состояние фиксации до вашего неправильного фиксации.

783
ответ дан Lennart Koopmann 29 мая '09 в 21:13
источник поделиться

Чтобы изменить последнее commit

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

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

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

git commit --amend

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

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


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


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


Чтобы вернуть фиксацию

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

Вы можете 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

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

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


624
ответ дан Zaz 31 июля '10 в 12:39
источник поделиться

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

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

498
ответ дан Jaco Pretorius 25 мая '12 в 19:04
источник поделиться

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

git reset --hard HEAD^1

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

git reset --soft HEAD^1

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

git reset HEAD

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

Подробнее

401
ответ дан Madhan Ayyasamy 31 янв. '13 в 10:06
источник поделиться

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

397
ответ дан nickf 13 дек. '11 в 13:18
источник поделиться

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

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 git@bitbucket.org:thecompany/prometheus.git
 + 09a6480...5a74047 master -> master (forced update)
prompt>
366
ответ дан neoneye 06 апр. '12 в 16:58
источник поделиться

Я предпочитаю использовать 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 удалит коммиты для любой удаляемой строки.

355
ответ дан Steven Penny 25 окт. '12 в 6:41
источник поделиться

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

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

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

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

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

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

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

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

git revert --no-edit HEAD

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

316
ответ дан nobar 23 апр. '13 в 20:27
источник поделиться

Если вы совершили ошибку, но не нажали,

git reset --soft HEAD~1

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

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

ИЛИ

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

git revert HEAD

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

277
ответ дан santos_mgr 03 сент. '14 в 10:15
источник поделиться

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

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

git log 

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

git reset --hard <commit_id>

git push origin <branch_name> -f
269
ответ дан poorva 17 мая '13 в 16:02
источник поделиться

В 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.
229
ответ дан Varun Parakh 28 июня '13 в 13:18
источник поделиться

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

git reset --soft 'HEAD^' 

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

217
ответ дан Manish Shrivastava 05 марта '14 в 16:55
источник поделиться

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

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

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

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

    git reset --soft HEAD^
    

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

183
ответ дан Ranjithkumar Ravi 23 апр. '14 в 14:21
источник поделиться

Просто reset выполнив следующую команду, используя git:

git reset --soft HEAD~1

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

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

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

171
ответ дан Alireza 21 июня '17 в 12:33
источник поделиться

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

git reflog

reflog before REFLOG ДО RESET

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

git reset --hard f3cb6e2

После этого HEAD-репо будет reset с этим HEADid reset effect LOG ПОСЛЕ RESET

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

reflog after REFLOG FINAL

152
ответ дан Shubham Chaudhary 07 янв. '14 в 1:34
источник поделиться

Первый запуск:

git reflog

Он покажет вам все возможные действия, которые вы выполнили в своем репозитории, например, commit, merge, pull и т.д.

Тогда do:

git reset --hard ActionIdFromRefLog
138
ответ дан U. Ali 11 окт. '13 в 17:41
источник поделиться

"Reset рабочее дерево до последнего фиксации

git reset --hard HEAD^ 

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

git clean    

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

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

137
ответ дан Ravi_Parmar 03 окт. '13 в 15:43
источник поделиться

Другой способ:

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

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

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

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

122
ответ дан CommaToast 13 мая '13 в 20:12
источник поделиться

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

git reset <the previous co>
118
ответ дан user853293 15 мая '13 в 16:12
источник поделиться

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

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

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

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

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


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

git commit --amend -m "message"

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

116
ответ дан akshay_rahar 06 марта '16 в 14:53
источник поделиться

В моем случае я случайно совершил некоторые файлы, которых я не хотел. Поэтому я сделал следующее, и это сработало:

git reset --soft HEAD^
git rm --cached [files you do not need]
git add [files you need]
git commit -c ORIG_HEAD

Проверьте результаты с помощью gitk или git log --stat

115
ответ дан egridasov 18 июля '13 в 9:41
источник поделиться

Существуют два основных сценария

Вы еще не нажали фиксацию

Если проблема связана с дополнительными файлами, которые вы совершили (и вы не хотите их использовать в репозитории), вы можете удалить их с помощью git rm, а затем совершить с помощью --amend

git rm <pathToFile>

Вы также можете удалить целые каталоги с помощью -r или даже объединить с другими командами Bash

git rm -r <pathToDirectory>
git rm $(find -name '*.class')

После удаления файлов вы можете совершить, используя - изменить вариант

git commit --amend -C HEAD # the -C option is to use the same commit message

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

Вы уже нажали фиксацию

Вы можете применить одно и то же решение другого сценария, а затем сделать git push с опцией -f, но не рекомендуется, поскольку он перезаписывает удаленную историю с расходящимся изменением (it может испортить ваш репозиторий).

Вместо этого вам нужно выполнить фиксацию без --amend (помните об этом -amend`: эта опция перезаписывает историю последнего коммита).

103
ответ дан dseminara 12 сент. '14 в 17:51
источник поделиться

Используйте SourceTree (графический инструмент для Git), чтобы увидеть ваши коммиты и дерево. Вы можете вручную reset щелкнуть правой кнопкой мыши.

99
ответ дан iOS Coder 29 авг. '13 в 19:18
источник поделиться

Простой, запустите это в командной строке:

git reset --soft HEAD~ 
89
ответ дан ihue 06 янв. '16 в 17:10
источник поделиться

В reset к предыдущей ревизии, постоянно удаляя все незафиксированные изменения:

git reset --hard HEAD~1
82
ответ дан thestar 28 авг. '14 в 19:03
источник поделиться

В этой статье есть отличное объяснение о том, как перейти к различным сценариям (где совершена фиксация, а также нажатие ИЛИ просто фиксация перед нажатием):

http://christoph.ruegg.name/blog/git-howto-revert-a-commit-already-pushed-to-a-remote-reposit.html

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

git revert dd61ab32
77
ответ дан AmpT 07 февр. '14 в 1:08
источник поделиться
  • 1
  • 2
  • 3

Другие вопросы по меткам