Как мне отменить самые последние локальные коммиты в Git?
-
06-09-2019 - |
Вопрос
Я случайно передал неправильные файлы в Мерзавец, но я еще не отправил коммит на сервер.
Как я могу отменить эти коммиты из локального репозитория?
Решение
Отменить фиксацию и повторить
$ 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
вариант.
Однако имейте в виду, что если вы добавили какие-либо новые изменения в индекс, используя commit --amend
добавит их к вашему предыдущему коммиту.
Если код уже отправлен на ваш сервер и у вас есть разрешения на перезапись истории (перебазирование), то:
git push origin master --force
Вы также можете посмотреть на этот ответ:
Как переместить HEAD обратно в предыдущее местоположение?(Отсоединенная головка) и отмена фиксаций
Приведенный выше ответ покажет вам git reflog
который используется, чтобы выяснить, что такое SHA-1, к которому вы хотите вернуться.Как только вы нашли точку, до которой хотите отменить действие, используйте последовательность команд, как описано выше.
1 Однако обратите внимание, что вам не нужно возвращаться к более ранней фиксации, если вы просто допустили ошибку в своем сообщение о фиксации.Более простой вариант заключается в том, чтобы git reset
(чтобы отменить все изменения, внесенные вами с тех пор), а затем git commit --amend
, который откроет ваш редактор сообщений о фиксации по умолчанию, предварительно заполненный последним сообщением о фиксации.
Другие советы
Отмена фиксации немного пугает, если вы не знаете, как это работает.Но на самом деле это удивительно просто, если вы понимаете.
Допустим, у вас есть это, где C - ваша ГОЛОВА, а (F) - состояние ваших файлов.
(F)
A-B-C
↑
master
Ты хочешь уничтожьте код C и никогда больше его не увидите.Ты делаешь это:
git reset --hard HEAD~1
В результате получается:
(F)
A-B
↑
master
Теперь Б - это ГОЛОВА.Потому что ты использовал --hard
, ваши файлы будут возвращены в свое состояние при фиксации B.
Ах, но предположим, что фиксация C не была катастрофой, а просто немного отклонялась от нормы.Ты хочешь отмените фиксацию, но сохраните свои изменения для небольшого редактирования, прежде чем вы сделаете лучшую фиксацию.Начиная снова отсюда, с Си в качестве РУКОВОДИТЕЛЯ:
(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.Ты ничего не потерял!
Для легчайшего прикосновения вы можете даже отмените свой коммит, но оставьте свои файлы и Указатель:
git reset --soft HEAD~1
Это не только оставляет в покое ваши файлы, но даже ваш Указатель один.Когда ты это сделаешь git status
, вы увидите, что в индексе находятся те же файлы, что и раньше.На самом деле, сразу после этой команды вы могли бы сделать git commit
и вы бы повторили тот же самый коммит, который только что сделали.
И еще кое-что: Предположим, вы уничтожили коммит как и в первом примере, но потом обнаруживаешь, что тебе это все-таки было нужно?Не повезло, верно?
Нет, там есть все еще способ вернуть это обратно.Тип git reflog
и вы увидите список (частичных) фиксаций шас (то есть хэши), в которых вы перемещались.Найдите коммит, который вы уничтожили, и сделайте это:
git checkout -b someNewBranchName shaYouDestroyed
Теперь вы восстановили этот коммит.Коммиты на самом деле не уничтожаются в Git в течение примерно 90 дней, так что обычно вы можете вернуться и спасти тот, от которого не собирались избавляться.
Мне потребовалось некоторое время, чтобы разобраться, так что, возможно, это кому-то поможет...
Есть два способа "отменить" ваш последний коммит, в зависимости от того, сделали ли вы уже свой коммит общедоступным (отправили в удаленный репозиторий).:
Как отменить локальную фиксацию
Допустим, я совершил локальную фиксацию, но теперь хочу удалить эту фиксацию.
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
покажет, что наш последний коммит был удален.
Как отменить публичный коммит
Если вы уже сделали свои коммиты общедоступными, вам захочется создать новый коммит, который "вернет" изменения, внесенные вами в предыдущем коммите (текущий ЗАГОЛОВОК).
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 - Отмена действий
Добавляйте / удаляйте файлы, чтобы все было так, как вы хотите:
git rm classdir
git add sourcedir
Затем внесите изменения в коммит:
git commit --amend
Предыдущая ошибочная фиксация будет отредактирована, чтобы отразить новое состояние индекса - другими словами, все будет выглядеть так, как будто вы никогда не совершали ошибки с самого начала.
Обратите внимание, что вам следует делать это только в том случае, если вы еще не нажали кнопку.Если вы нажали кнопку, то вам просто нужно будет зафиксировать исправление в обычном режиме.
git rm yourfiles/*.class
git commit -a -m "deleted all class files in folder 'yourfiles'"
или
git reset --hard HEAD~1
Предупреждение:Приведенная выше команда безвозвратно удалит изменения в .java
файлы (и любые другие файлы), которые вы хотели зафиксировать.
Тот Самый hard reset
Для HEAD-1
установит вашу рабочую копию в состояние фиксации перед вашей неправильной фиксацией.
Чтобы изменить последнюю фиксацию
Замените файлы в индексе:
git rm --cached *.class
git add *.java
Тогда, если это частный филиал, изменить фиксация:
git commit --amend
Или, если это общая ветка, сделайте новый коммит:
git commit -m 'Replace .class files with .java files'
(чтобы изменить предыдущую фиксацию, используйте потрясающий интерактивная перебазировка)
ProTip™:Добавить *.class
к a гитиньор чтобы это больше не повторилось.
Чтобы отменить фиксацию
Изменение коммита является идеальным решением, если вам нужно изменить последний коммит, но более общим решением является 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 HEAD@{0}: reset: moving to @~
2c52489 HEAD@{1}: commit: added some .class files
$ git reset 2c52489
... and you're back where you started
Использование git revert <commit-id>
Чтобы получить идентификатор фиксации, просто используйте git log
Если вы планируете полностью отменить локальную фиксацию, независимо от того, какие изменения вы внесли при фиксации, и если вас это ни о чем не беспокоит, просто выполните следующую команду.
git reset --hard HEAD^1
(Эта команда проигнорирует всю вашу фиксацию, и ваши изменения будут полностью потеряны из вашего локального рабочего дерева).Если вы хотите отменить свой коммит, но хотите, чтобы ваши изменения находились в промежуточной области (до фиксации точно так же, как и после git add
) затем выполните следующую команду.
git reset --soft HEAD^1
Теперь ваши зафиксированные файлы попадают в промежуточную область.Предположим, если вы хотите изменить формат файлов, потому что вам нужно отредактировать какое-то неправильное содержимое, то выполните следующую команду
git reset HEAD
Теперь зафиксированные файлы будут поступать из промежуточной области в нестационарную.Теперь файлы готовы к редактированию, поэтому, что бы вы ни изменили, вы хотите пойти отредактировать, добавить это и сделать новый коммит.
Если у вас есть Дополнительные функции Git установленный, вы можете запустить git undo
чтобы отменить последнюю фиксацию. git undo 3
отменит последние 3 коммита.
Я хотел отменить последние 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>
Я предпочитаю использовать 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-gui (или аналогичный) для выполнения git commit --amend
.С помощью графического интерфейса вы можете добавлять или удалять отдельные файлы из коммита.Вы также можете изменить сообщение о фиксации.
Как отменить предыдущую локальную фиксацию
Просто верните свой филиал в предыдущее местоположение (например, используя gitk
или git rebase
).Затем повторно примените внесенные изменения из сохраненной копии.После сборки мусора в вашем локальном репозитории все будет выглядеть так, как будто нежелательной фиксации никогда не было.Чтобы сделать все это в одной команде, используйте git reset HEAD~1
.
Слово предупреждения: Неосторожное использование git reset
это хороший способ привести вашу рабочую копию в сбивающее с толку состояние.Я рекомендую новичкам Git избегать этого, если они могут.
Как отменить публичный коммит
Выполните обратный сбор вишни (git-вернуть), чтобы отменить изменения.
Если вы еще не внесли другие изменения в свою ветку, вы можете просто сделать это...
git revert --no-edit HEAD
Затем отправьте обновленную ветку в общий репозиторий.
В истории коммитов будут показаны оба коммита по отдельности.
Дополнительно:Коррекция Частное ветка в публичном репозитории
Это может быть опасно - убедитесь, что у вас есть локальная копия ветки для повторной загрузки.
Также обратите внимание:Вы не захотите этого делать, если кто-то другой может работать в ветке.
git push --delete (branch_name) ## remove public version of branch
Очистите свой филиал локально, затем повторите загрузку...
git push origin (branch_name)
В обычном случае вам, вероятно, не нужно беспокоиться о том, что история фиксаций вашей частной ветви нетронута.Просто нажмите на последующую фиксацию (см. "Как отменить публичную фиксацию" выше), а позже выполните сквош-слияние чтобы скрыть свою историю.
Если вы совершили выброс мусора, но не подтолкнули,
git reset --soft HEAD~1
ГОЛОВКА ~ 1 является сокращением для фиксации перед head.В качестве альтернативы вы можете обратиться к SHA-1 из хэша, если вы хотите сбросить значение. --мягкий опция удалит фиксацию, но оставит все ваши измененные файлы "Изменениями, подлежащими фиксации", как выразился бы git status.
Если вы хотите избавиться от любых изменений отслеживаемых файлов в рабочем дереве с момента фиксации перед использованием head "--жесткий- вместо этого.
или
Если вы уже нажали, а кто-то потянул, что обычно бывает в моем случае, вы не можете использовать сброс git.Однако вы можете сделать мерзавец возвращается,
git revert HEAD
Это создаст новый коммит, который отменит все, что было введено случайным коммитом.
Если вы хотите навсегда отменить это, и вы клонировали какой-то репозиторий
Идентификатор фиксации можно увидеть с помощью
git log
Тогда вы можете сделать -
git reset --hard <commit_id>
git push origin <branch_name> -f
Вкл . Исходное дерево (Графический интерфейс для 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 --soft 'HEAD^'
Это отлично работает, чтобы отменить последнюю локальную фиксацию!
Просто сбросьте его, выполнив приведенную ниже команду, используя git
:
git reset --soft HEAD~1
Объясните: что git reset
делает, это в основном reset
к любому коммиту, к которому вы хотели бы вернуться, затем, если вы объедините его с --soft
ключ, он вернется, но сохраните изменения в ваших файлах, чтобы вы вернулись к стадии, на которой файл был только что добавлен, HEAD
является руководителем филиала, и если вы объедините с ~1
(в этом случае вы также используете HEAD^
), он вернет только один коммит, который вам нужен...
Я более подробно описываю шаги на изображении ниже, включая все шаги, которые могут произойти в реальных ситуациях, и фиксирую код:
Как отменить последнюю фиксацию Git?
Чтобы восстановить все так, как это было до последнего коммита, нам нужно выполнить сброс к коммиту перед HEAD.
Если вы не хотите сохранять внесенные вами изменения:
git reset --hard HEAD^
Если вы хотите сохранить свои изменения:
git reset --soft HEAD^
Теперь проверьте свой журнал git.Это покажет, что наш последний коммит был удален.
Используйте reflog, чтобы найти правильное состояние
git reflog
ПОВТОРНЫЙ ЖУРНАЛ ПЕРЕД СБРОСОМ
Выберите правильный рефлог (в моем случае f3cb6e2) и введите
git reset --hard f3cb6e2
После этого заголовок репо будет сброшен на этот HEADid ВОЙТИ ПОСЛЕ СБРОСА
Наконец, рефлог выглядит как показано на рисунке ниже
ФИНАЛ РЕФЛОГА
"Сбросьте рабочее дерево до последней фиксации"
git reset --hard HEAD^
"Очистить неизвестные файлы из рабочего дерева"
git clean
видишь - Краткий справочник по Git
ПРИМЕЧАНИЕ: Эта команда удалит вашу предыдущую фиксацию, поэтому используйте ее с осторожностью! git reset --hard
безопаснее –
Первый запуск:
git reflog
Он покажет вам все возможные действия, которые вы выполнили в своем репозитории, например, фиксацию, слияние, извлечение и т.д.
Тогда делай:
git reset --hard ActionIdFromRefLog
Отменить последнюю фиксацию:
git reset --soft HEAD^
или git reset --soft HEAD~
Это отменит последнюю фиксацию.
Здесь --soft
означает сброс в промежуточный режим.
HEAD~
или HEAD^
означает перейти к совершению перед ГОЛОВОЙ.
Замените последнюю фиксацию на новую фиксацию:
git commit --amend -m "message"
Он заменит последнюю фиксацию новой фиксацией.
Другой способ:
Проверьте ветку, которую вы хотите отменить, затем сбросьте свою локальную рабочую копию обратно на коммит, который вы хотите сделать последним на удаленном сервере (все, что после этого, будет удалено).Чтобы сделать это, в SourceTree я щелкнул правой кнопкой мыши и выбрал "Сбросить имя ветки для этого коммита".
Затем перейдите в локальный каталог вашего репозитория и выполните эту команду:
git -c diff.mnemonicprefix=false -c core.quotepath=false push -v -f --tags REPOSITORY_NAME BRANCHNAME:BRANCHNAME
Это приведет к удалению всех коммитов после текущего в вашем локальном репозитории, но только для этой одной ветви.
Тип git log
и найдите хэш-код последней фиксации, а затем введите:
git reset <the previous co>
В моем случае я случайно зафиксировал некоторые файлы, которые не хотел делать.Итак, я сделал следующее, и это сработало:
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
Все просто, запустите это в своей командной строке:
git reset --soft HEAD~
Есть много способов сделать это:
Команда Git для отмены последнего коммита / предыдущих фиксаций:
Предупреждение: Не используйте --hard, если вы не знаете, что делаете.--тяжело - это слишком опасный, и это могло бы удалите свои файлы.
Основная команда для отмены фиксации в Git - это:
$ git reset --hard <COMMIT -ID>
или
$ git reset --hard HEAD~<n>
ИДЕНТИФИКАТОР ФИКСАЦИИ:Идентификатор для фиксации
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
Для получения более подробной информации вы можете обратиться и опробовать некоторые другие команды для возврата head в указанное состояние:
$ git reset --help
Чтобы вернуться к предыдущей редакции, безвозвратно удалив все незафиксированные изменения:
git reset --hard HEAD~1
Используйте SourceTree (графический инструмент для Git), чтобы увидеть ваши коммиты и дерево. Вы можете вручную сбросить его непосредственно щелкнув правой кнопкой мыши его.
Для локальной фиксации
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).