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


21067

Я случайно передал неправильные файлы в Git , но я еще не отправил коммит на сервер.

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


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

92
Вы знаете, что нужно Git? git undo, это оно. Затем репутация Git по обработке ошибок, совершенных нами, простыми смертными, исчезает. Реализуйте, поместив текущее состояние в стек git перед выполнением любой gitкоманды. Это повлияет на производительность, поэтому было бы лучше добавить флаг конфигурации относительно того, включать ли его.
Иминь Ронг

11
@YiminRong Это можно сделать с помощью aliasфункции Git : git-scm.com/book/en/v2/Git-Basics-Git-Aliases
Edric,

3
@ RomainValeri - Отмена работает везде.
Иминь Ронг

1
@YiminRong Не покупаю это. Люди по-прежнему шарили и отменяли вещи, которые нельзя отменить. Но, что более важно, git reflogуже близко к тому, что вы описываете, но дает пользователю больше контроля над тем, что должно быть (не) сделано. Но, пожалуйста, нет, «отмена» не везде работает одинаково, и люди ожидают, что эта функция будет реализована по-разному. Отменить последний коммит? Отменить последнее действие? Если последнее действие было нажатием, отмените как (сбросить и нажать) или (повернуть и нажать)?
RomainValeri

Ответы:


22866

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

$ 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)
  1. Это то, что вы хотите отменить.
  2. Это никак не влияет на ваше рабочее дерево (состояние ваших файлов на диске), но отменяет фиксацию и оставляет внесенные вами изменения неизмененными (поэтому они будут отображаться как «Изменения не подготовлены для фиксации» git status, поэтому вам нужно добавьте их еще раз перед совершением). Если вы хотите только добавить больше изменений к предыдущему коммиту или изменить сообщение о коммите 1 , вы можете использовать git reset --soft HEAD~вместо этого, который похож на git reset HEAD~2, но оставляет ваши существующие изменения подготовленными.
  3. Внесите исправления в рабочие файлы дерева.
  4. git add все, что вы хотите включить в свой новый коммит.
  5. Зафиксируйте изменения, повторно используя старое сообщение. resetскопировал старую голову в .git/ORIG_HEAD; commitс -c ORIG_HEADоткроет редактор, который изначально содержит сообщение журнала от старого коммита и позволяет вам редактировать его. Если вам не нужно редактировать сообщение, вы можете использовать -Cопцию.

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

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

git push origin master --force

Вы также можете посмотреть на этот ответ:

Как я могу переместить ГОЛОВУ назад в предыдущее место? (Отдельная голова) & Отменить фиксацию

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


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

2 так HEAD~ же, как HEAD~1. Также смотрите Что такое HEAD в git? , Это полезно, если вы хотите отменить несколько коммитов.


472
И если коммит был в неправильной ветке, вы можете git checkout theRightBranchсо всеми этапами изменений. Как я только должен был сделать.
Фрэнк Шиарар

491
Если вы работаете в DOS, вместо этого git reset --soft HEAD^вам нужно будет использовать git reset --soft HEAD~1. ^ - это символ продолжения в DOS, поэтому он не будет работать должным образом. Кроме того, --softпо умолчанию, так что вы можете опустить его, если хотите, и просто сказать git reset HEAD~1.
Райан Ланди

119
Пользователи zsh могут получить: zsh: no matches found: HEAD^- вам нужно сбежать ^ iegit reset --soft HEAD\^
tnajdek

7
Ответ неверен, если, скажем, случайно, git commit -aбыл выпущен, когда -aдолжны были быть опущены. В этом случае лучше не пропускать --soft(что приведет к тому, --mixedчто это значение по умолчанию), и тогда вы сможете заново изменить изменения, которые вы намеревались зафиксировать.
Дмансфилд

6
@IcyBrk git add - это команда. git add [--verbose | -v] [--dry-run | -n] [--force | -f] [--interactive | -i] [--patch | -p] [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]] [--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing] [--chmod=(+|-)x] [--] [<pathspec>…​]
Ashraf.Shk786

10734

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

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

   (F)
A-B-C
    ↑
  master

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

git reset --hard HEAD~1

Результат:

 (F)
A-B
  ↑
master

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

Ах, но предположим, что commit 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. Вы ничего не потеряли!

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

git reset --soft HEAD~1

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

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

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

git checkout -b someNewBranchName shaYouDestroyed

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


15
BEWARE! Это может не сработать так, как вы ожидаете, если ваш ошибочный коммит (с ускоренной перемоткой) слился! Если ваша голова находится на коммите слияния (например: слитый элемент ветки в master), git reset --hard~1то ветка master будет указывать на последний коммит внутри ветви объекта. В этом случае вместо соответствующей команды следует использовать конкретный идентификатор фиксации.
Крис Керекс

90
Пропуск решающего момента: если указанный коммит был ранее «передан» на удаленный компьютер, любая операция «отмена», какой бы простой она ни была, причинит огромную боль и страдания остальным пользователям, которые имеют этот коммит в своей локальной копии, когда они сделают «мерзавец» в будущем. Итак, если фиксация уже была «отправлена», сделайте это вместо этого: git revert <bad-commit-sha1-id> git push origin:
FractalSpace

12
@FractalSpace, это не вызовет «огромной боли и страданий». Я сделал несколько толчков при использовании Git с командой. Все, что нужно, это общение.
Райан Ланди

14
@Kyralessa На моем рабочем месте испортить рабочий процесс всей команды, а затем рассказать им, как исправить sh * t, не называется «общение». Перезапись истории git - это разрушительная операция, которая приводит к уничтожению частей репо. Настаивать на его использовании при наличии четких и безопасных альтернатив просто безответственно.
FractalSpace

14
Я хотел уничтожить коммит и больше никогда его не видеть. Я использовал ваш пример с, --hardно я не осознавал, что все мои неустановленные изменения в моем рабочем дереве также были уничтожены! Я собирался зафиксировать эти файлы как часть последующего коммита. Теперь кажется невозможным вернуть эти файлы - я даже попробовал решение, о котором вы опубликовали, reflogно это не восстановило ранее неустановленные изменения.
Адам Берли

2130

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

Как отменить локальный коммит

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

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 .


101
Я нашел этот ответ самым ясным. git revert HEAD^это не предыдущий, это предыдущий из предыдущего. Я сделал: git revert HEADи затем снова нажал, и это сработало :)
nacho4d

Если Git спросит вас "Больше?" Когда вы попробуете эти команды, используйте альтернативный синтаксис в этом ответе: stackoverflow.com/a/14204318/823470
tar

1745

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

git rm classdir
git add sourcedir

Затем измените коммит:

git commit --amend

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

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


2
К вашему сведению: это удаляет все мои файлы, и я потерял изменения.
егорлитвиненко

UPD: Тем не менее, я восстановил его с помощью reflog. Но квитанция не сработала для первоначального коммита.
егорлитвиненко

1
Используйте git rm --cachedдля хранения файлов в файловой системе и только удаляйте их из индекса git!
xuiqzy

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

или

git reset --hard HEAD~1

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

Команда hard resetto HEAD-1установит вашу рабочую копию в состояние коммита до вашего неверного коммита.


19
git commit -a -m ""или git commit -am ""естественно! :]
Трейдер

Еще одно «быстрое» использование тайника; если вы хотите убрать из буфера все (отменить мерзавец надстройки), просто git stash, а затемgit stash pop
seanriordan08

778

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

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

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

Если вы запутались, вы всегда можете использовать 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



2
Для тех, кто читает в будущем - обратите внимание, что git revertэто отдельная команда - которая в основном «сбрасывает» один коммит.
BKSpurgeon

682

Использование git revert <commit-id>.

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


15
Что это значит, вишня выбрать коммит? В моем случае я находился не в той ветке, когда редактировал файл. Я совершил это, затем понял, что я был не в той ветке. Использование «git reset --soft HEAD ~ 1» вернуло меня непосредственно перед фиксацией, но теперь, если я извлекаю правильную ветвь, как мне отменить изменения в файле в неправильной ветке, но вместо этого внести их (с тем же именем файл) в правильной ветке?
astronomerdave

Я просто использовал git revert commit-idработал как шарм. Конечно, тогда вам нужно будет подтолкнуть ваши изменения.
Кейси Робинсон

8
Я считаю, что это будет git cherry-pick <<erroneous-commit-sha>>@astronomerdave. От, мистер почти 2 года опоздал на вечеринку.
Том Ховард,

@Kris: вместо вишневого пика используйте rebase. Потому что это продвинутый сбор вишни
Евгений Коньков

Я бы использовал возврат, только если я уже нажал на коммит. В противном случае сброс является лучшим вариантом. Не забывайте, что возврат создает новый коммит, и обычно это не цель.
Hola Soy Edu Feliz Navidad

532

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

git reset --hard HEAD^1

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

git reset --soft HEAD^1

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

git reset HEAD

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

Больше


13
@SMR, в вашем примере все указывают только на текущий HEAD. ГОЛОВА ^ = ГОЛОВА ^ 1. А также HEAD ^ 1 = HEAD ~ 1. Когда вы используете HEAD ~ 2, между символами ~ и ^ есть разница. Если вы используете ~ 2, значит «первый родитель первого родителя» или «прародитель».
Мадхан Айясами

501

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


470

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

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>

25
Переписывать историю в общем репозитории, как правило, очень плохая идея. Я предполагаю, что вы знаете, что делаете, я просто надеюсь, что будущие читатели тоже.
Брэд Кох

Да, откат опасен. Убедитесь, что ваша рабочая копия находится в желаемом состоянии, прежде чем нажать. При нажатии затем нежелательные коммиты удаляются навсегда.
neoneye

6
«Точно так же, как в реальном мире, если вы хотите переписать историю, вам нужен заговор: все должны быть« вовлечены »в заговор (по крайней мере, все, кто знает об истории, то есть все, кто когда-либо вырывался из ветви) «. Источник: stackoverflow.com/a/2046748/334451
Микко Ранталайнен,

440

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


422

Как исправить предыдущий локальный коммит

Используйте 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)

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


8
gitk --all $(git reflog | cut -c1-7)&может быть полезно для поиска предыдущей ревизии, если вы хотите отменить коммит '--amend'.
Нобар

4
Следует отметить, что если вы пытаетесь удалить секретную информацию, прежде чем отправлять ее в общий репозиторий, выполнение возврата не поможет вам, поскольку информация все еще будет в истории в предыдущем коммите. Если вы хотите, чтобы изменения никогда не были видны другим, вам нужно их использоватьgit reset
Jherico

Я думаю, что «приватный» / «публичный» будет правильнее «локальный» / «удаленный».
Нобар

Исправляя частный филиал в удаленном хранилище также может быть сделано простоgit push origin (branch_name) --force
nobar

336

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

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

git log 

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

git reset --hard <commit_id>

git push origin <branch_name> -f

Что если вы не используете «<commit_id>» и просто используете «git reset --hard»? Обычно я просто хочу избавиться от своих последних обновлений, которые я еще не зафиксировал, и вернулся к последнему принятому мною обновлению, и я всегда использую «git reset --hard».
Хайме Монтойя

3
@JaimeMontoya Чтобы отменить последние изменения, которые вы можете использовать git reset --hard, но если вам нужно жестко удалить последние коммиты "n", вы указываете SHA
плохое имя

334

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

git reset --soft HEAD~1

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

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

ИЛИ

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

git revert HEAD

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


Я во втором случае, но когда я делаю "git revert HEAD", он говорит: "ошибка: Commit [ID] - это слияние, но опция -m не была указана. Fatal: revert failed". Какие-либо предложения?
Метафорж

2
Вероятно, стоит упомянуть, что вместо HEAD~1вас можно использовать фактический хеш, отображаемый с помощью git log --statили git reflog- полезный, когда вам нужно «отменить» более одного коммита.
ccpizza

284

На SourceTree (GUI для 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.

263

Единственная команда:

git reset --soft 'HEAD^' 

Это прекрасно работает, чтобы отменить последний локальный коммит!


11
Мне нужно было написать git reset --soft "HEAD ^" с двойными кавычками, потому что я пишу это из командной строки Windows.
Эна

253

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

git reset --soft HEAD~1

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

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

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


239

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

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

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

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

    git reset --soft HEAD^
    

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


193

«Сбросить рабочее дерево до последнего коммита»

git reset --hard HEAD^ 

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

git clean    

смотри - Git Quick Reference

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


190

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

git reflog

рефлог раньше РЕФЛОГ ДО СБРОСА

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

git reset --hard f3cb6e2

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

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

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


164

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

git reflog

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

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

git reset --hard ActionIdFromRefLog

155

Отменить последний коммит:

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

Это отменит последний коммит.

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

HEAD~или HEAD^означает двигаться, чтобы совершить перед ГОЛОВОЙ.


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

git commit --amend -m "message"

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


153

Другой путь:

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

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

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

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


144

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

git reset <the previous co>

139

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

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


133

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

git reset --soft HEAD~ 

126

Есть много способов сделать это:

Команда Git для отмены последнего коммита / предыдущих коммитов:

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

Основная команда для возврата коммита в Git:

$ git reset --hard <COMMIT -ID>

или

$ git reset --hard HEAD~<n>

COMMIT-ID : идентификатор для фиксации

n: количество последних коммитов, которые вы хотите вернуть

Вы можете получить идентификатор фиксации, как показано ниже:

$ **git log --oneline**

d81d3f1 function to subtract two numbers

be20eb8 function to add two numbers

bedgfgg function to mulitply two numbers

где d81d3f1 и be20eb8 являются идентификатором коммита.

Теперь давайте посмотрим на некоторые случаи:

Предположим, вы хотите отменить последний коммит 'd81d3f1'. Вот два варианта:

$ git reset --hard d81d3f1

или

$ git reset --hard HEAD~1

Предположим, вы хотите отменить коммит 'be20eb8':

$ git reset --hard be20eb8

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

$ git reset --help

5
git reset --hard HEAD~1это слишком опасно ! Это не только «отменит последний коммит», но и полностью вернет репо к предыдущему коммиту. Таким образом, вы потеряете все изменения, совершенные в последнем коммите!
Арнис Юрага

Вы правы, чтобы отменить это, вы можете использоватьgit push -f <remote> HEAD@{1}:<branch>
Бенни

К сожалению, я использую --hard, и мои файлы удалены! Сначала я не проверял комментарий, потому что он свернут. Не используйте --hard, если вы не знаете, что делаете!
анонимно

125

Для локального коммита

git reset --soft HEAD~1

или если вы точно не помните, в каком именно коммите это происходит, вы можете использовать

git rm --cached <file>

Для толкаемого коммита

Правильный способ удаления файлов из истории хранилища использует git filter-branch. Это,

git filter-branch --index-filter 'git rm --cached <file>' HEAD

Но я рекомендую вам использовать эту команду с осторожностью. Узнайте больше на странице руководства git-filter-branch (1) .


125

Есть два основных сценария

Вы еще не выдвинули коммит

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

git rm <pathToFile>

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

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

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

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

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

Вы уже нажали коммит

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

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


125

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

git reset --hard HEAD~1

23
Возможно, вы могли бы заметить / предупредить, что его команда отбросит коммит и изменения в рабочем каталоге, не спрашивая больше.
cr7pt0gr4ph7

6
Если вам случится сделать это случайно, не все потеряно. См. Stackoverflow.com/questions/10099258/… , stackoverflow.com/questions/15479501/… и stackoverflow.com/questions/7374069/undo-git-reset-hard/7376959 .
cr7pt0gr4ph7

13
Используйте, --softчтобы сохранить ваши изменения как uncommitted changes, полностью --hardсбросить коммит и вернуться к нему. Не забывайте делать такие операции только с изменениями, которые еще не переданы.
Юнус Недим Мехел

@Zaz: вы правы; возможно я должен был уточнить это. Только файлы / изменения, которые были либо добавлены в индекс (/ staged), либо были зафиксированы, могут быть восстановлены. Незафиксированные, unstaged изменения являются , как вы сказали, полностью отброшены git reset --hard.
cr7pt0gr4ph7

1
Как примечание: Каждый раз, когда файл находится в стадии размещения, gitсохраняет его содержимое в своей объектной базе данных. Сохраненное содержимое удаляется только при выполнении сборки мусора. Поэтому возможно восстановить последнюю поэтапную версию файла, который в данный момент не git reset --hardбыл подготовлен к моменту запуска (дополнительную информацию см. В сообщениях, ссылки на которые приведены выше).
cr7pt0gr4ph7
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.