Удалить коммиты из ветки в Git

Я хотел бы знать, как удалить коммит.

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

Я прочитал справку git и думаю, что мне следует использовать команду git reset --hard HEAD. Это верно?


person hap497    schedule 27.08.2009    source источник
comment
Я думаю, что это не дубликата Git undo last commit как он спрашивает, как удалить любую фиксацию из ветки. Я также думаю, что ни один из ответов не отвечает на этот вопрос. Все они перематывают последние коммиты, а не cherry-pick и delete одну фиксацию, которая могла произойти некоторое время назад.   -  person Chris    schedule 03.05.2015
comment
@Chris, ответ с git rebase -i HEAD~10 действительно отвечает на вопрос, поскольку позволяет произвольно выбирать коммиты для удаления. Git применяет коммиты в указанном вами диапазоне по очереди, игнорируя коммиты, удаленные из журнала. Я использовал эту команду сегодня, чтобы избавиться от второй и третьей из последних коммитов в моем репо, сохранив при этом верхнюю. Я согласен с тем, что ни один из других ответов не является удовлетворительным.   -  person MST    schedule 18.06.2015
comment
@MST да, я должен был сказать, ни один из вариантов в принятом ответе не отвечает на этот вопрос, но вы абсолютно правы - эта команда, похоже, работает   -  person Chris    schedule 10.07.2015
comment
Я думаю, git reset --soft HEAD~1 это именно то, что вам нужно. В таком случае вы отмените фиксацию и сохраните свою работу. reset --hard полностью удалит фиксацию.   -  person sergpank    schedule 18.05.2021
comment
команда: git log | голова -n 1 | git revert   -  person Amin Golmahalle    schedule 01.06.2021


Ответы (34)


Если вы еще никуда не отправляли фиксацию, вы можете использовать git rebase -i, чтобы удалить эту фиксацию. Во-первых, выясните, как далеко эта фиксация (приблизительно). Затем сделайте:

git rebase -i HEAD~N

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

В Git Book есть хороший раздел о перебазировании с изображениями и примерами.

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

person Greg Hewgill    schedule 27.08.2009
comment
Примечание. Если у вас есть какие-либо слияния --no-ff в этой последней партии коммитов, rebase разделит их :( Это упоминается в разделе -p на эта страница. Проблема в том, что если вы замените -i на -p, вы больше не увидите это всплывающее окно с варианты редактирования этого коммита, sqush этого и т. д. и т. д. Кто-нибудь знает решение? - person Bukov; 21.04.2013
comment
Это лучше, чем жесткий ответ сброса, поскольку он не удалит файлы, а только ошибочное сообщение фиксации? Потому что он, похоже, удалил мои файлы. Если предполагается удаление файла, добавьте это как четкое предупреждение! - person Darren Cook; 27.11.2013
comment
Что, если вы его подтолкнули? (только я использую удаленное репо) - person Costa Michailidis; 07.01.2015
comment
@Costa вы можете использовать push -f для принудительного нажатия и замены удаленной ветки на локальную. Если это просто ваше собственное удаленное репо, нет проблем. Проблема начинается, если кто-то тем временем пришел. - person Greg Hewgill; 07.01.2015
comment
Я добавил и зафиксировал файл данных, который был слишком большим для GitHub (да, вероятно, его в любом случае не должно быть в исходном репозитории; ну ладно). Когда я попытался нажать, GitHub отказал из-за слишком большого файла. Все, что я хотел сделать, это отменить эту фиксацию, сохранив при этом несколько других несвязанных коммитов, которые последовали за ней. Команда git rebase -i HEAD~5 была именно тем, что мне нужно, чтобы полностью удалить этот коммит из моего локального репо! Спасибо! - person aldo; 24.02.2015
comment
@Bukov В документации говорится, что вы можно использовать как -i, так и -p, но если вы это сделаете, Редактирование коммитов и изменение их сообщений о коммитах должны работать нормально, но попытки изменить порядок коммитов, как правило, приводят к противоречивым результатам. Я не уверен, насколько хорошо будет работать удаление коммитов, но вы можете попробовать это, а затем сделать reset --hard до перебазирования (используя журнал ссылок), если это не сработает должным образом. - person Max Nanasy; 04.03.2015
comment
Или git rebase -i 592d26e9131e0a5a9b6ada78ab1574688cbbf9b7^, а 592d26e9131e0a5a9b6ada78ab1574688cbbf9b7 - это идентификатор самого раннего коммита, который вы хотите удалить. - person McKelvin; 26.11.2015
comment
Когда он удаляет фиксацию, он также удаляет изменения (например, --hard в исходном сообщении) или оставляет их нетронутыми, но незафиксированными (см. --soft)? - person dumbledad; 10.05.2016
comment
@dumbledad: с rebase -i изменения, соответствующие удаленной фиксации, не сохраняются. - person Greg Hewgill; 10.05.2016

Другая возможность - одна из моих любимых команд:

git rebase -i <commit>~1

Это запустит перебазирование в интерактивном режиме -i в точке непосредственно перед фиксацией, которую вы хотите отменить. Редактор запустит список всех коммитов с тех пор. Удалите строку, содержащую коммит, который вы хотите стереть, и сохраните файл. Rebase выполнит остальную работу, удалив только этот коммит и воспроизведя все остальные обратно в журнал.

person 1800 INFORMATION    schedule 27.08.2009
comment
спасибо, кстати, если у вас возникнут какие-либо проблемы (например, пустые коммиты), вы можете использовать git rebase --continue - person realgt; 28.09.2012
comment
Еще проще: git rebase -i HEAD~1 - person mmell; 11.09.2013
comment
Wowzers. git rebase -i HEAD~1 действительно сильно очистили репо! Трудно сказать, что именно он сделал, но все выглядит намного аккуратнее. На самом деле, это немного настораживает. - person Charles Wood; 02.12.2014
comment
Когда фиксация пуста, git rebase отобразит эту закомментированную строку (#). Если вы не раскомментируете эту строку, git удалит фиксацию при перемещении. Удаление пустой фиксации - это именно то, что я пытался сделать, но если вы хотите сохранить свою, сначала не закомментируйте строку. - person Chris Middleton; 25.04.2015
comment
Думаю, стоит отметить, что коммит не стирается, а просто удаляется из списка. Если вы ошиблись, вы можете вернуть фиксацию с помощью рефлог. - person Zaz; 29.04.2015
comment
Удаление строки - это то же самое, что и d / drop? - person Leo; 25.05.2016
comment
@dragonmnl удаление или изменение нажатых коммитов - это то, что, как я понимаю, не рекомендуется - person 1800 INFORMATION; 07.02.2017
comment
Я слился вместо ребазинга, и мой запрос на перенос показал другие изменения, отличные от моих. запуск git rebase -i HEAD ~ 1 очистил его. Спасибо mmell - person user373201; 01.05.2019
comment
Впервые я осмелился использовать rebase, и он работал без сбоев. - person Farzad Yousefzadeh; 08.01.2020
comment
Это сработало, то есть я смог удалить фиксацию, но тогда я просто не могу продвинуть результаты, поэтому это просто совершенно бесполезно. Может потому, что я уже раньше нажимал? - person Alexis Wilke; 11.06.2020

Я добавляю этот ответ, потому что не понимаю, почему любой, кто только что попытался зафиксировать работу, захотел бы удалить всю эту работу из-за какой-то ошибки при использовании Git!

Если вы хотите сохранить свою работу и просто отменить эту команду фиксации (вы поймали ее перед нажатием на репо):

git reset --soft HEAD~1

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

person Rob    schedule 15.10.2012
comment
Вот пример того, почему: вы выполняете небольшой фрагмент работы на сервере разработки, который вы фиксируете. Затем выясняется, что у этого сервера нет исходящего доступа HTTPS, поэтому вы не можете никуда отправить фиксацию. Проще всего просто притвориться, что этого никогда не было, и повторить патч с вашего локального компьютера. - person Steve Bennett; 03.01.2013
comment
@KarthikBose всегда будет рефлог. даже после git reset --hard HEAD~1 ваш предыдущий последний коммит будет доступен через reflog (пока вы не истечете его срок); см. также здесь: gitready.com/intermediate/2009/ 09.02 / - person codeling; 06.06.2013
comment
Возможно, я неправильно использую git, но одна ситуация, в которой я бы хотел использовать параметр --hard, - это когда у меня есть несколько удаленных веток, и я нажимаю не на ту ветку. Скажем, у меня есть ветка master и ветка staging, я работаю в локальной ветке, но затем случайно сливаюсь и вставляю в мастер, а затем понимаю, что сделал не то. Затем я хотел бы восстановить HEAD мастера до второго последнего коммита и хочу удалить все следы этого ошибочного нажатия от мастера, поскольку он не должен находиться в мастере - person Goldentoa11; 17.06.2013
comment
вы могли бы так же легко сделать git commit --amend в этом сценарии, который намного менее запутан - person UpAndAdam; 25.07.2013
comment
Спасибо. Этот ответ должен быть оценен выше или включен в принятый ответ. Удаление фиксации! = Возврат фиксации. - person Alsciende; 05.03.2014
comment
@RandolphCarter: вы все равно потеряете все незафиксированные изменения. - person naught101; 01.09.2014
comment
@Rob, одним из примеров является случай, когда вы случайно фиксируете файл, содержащий секрет (например, пароль), который никогда не должен находиться в системе управления версиями. Локальная фиксация должна быть уничтожена, а не просто отменена, чтобы она никогда не была отправлена ​​на сервер. - person Bob Meyers; 15.11.2016
comment
Это отлично сработало! Я не хотел отменять все, только несколько папок в моей последней паре коммитов. HARD мог бы сработать, но мне бы пришлось сохранить все мои изменения, которые я хотел сохранить, и исправить их позже. СОФТ удалил локальные коммиты. И git reset HEAD -. Так же нужно было убрать постановочную замену. Тогда я мог удалить все плохое вручную, а все остальное - мои другие изменения - остались нетронутыми. - person Gabe Halsmer; 21.03.2017
comment
супер важно! tnx m8 - person Li3ro; 24.04.2018
comment
Думаю, это хороший вариант. - person arango_86; 13.01.2021

Удаление всего коммита

git rebase -p --onto SHA^ SHA

Очевидно, замените "SHA" ссылкой, от которой вы хотите избавиться. Знак «^» в этой команде буквальный.

http://sethrobertson.github.io/GitFixUm/fixup.html#change_deep

person raittes    schedule 31.08.2015
comment
как я могу проголосовать больше за этот ответ ??? другие решения просто показывают, как это сделать в интерактивном режиме или как удалить верхние коммиты. - person ribamar; 12.01.2018
comment
Спасибо за ссылку! Мне было интересно, после запуска этого, почему я все еще вижу коммит SHA в моем git reflog? - person bapors; 15.02.2018
comment
Зачем нам здесь -p? - person Serge Roussak; 26.06.2018
comment
-p, --preserve-merges Повторное создание коммитов слияния вместо того, чтобы сглаживать историю путем воспроизведения коммитов, вводит коммит слияния. Разрешение конфликтов слияния или ручные поправки к коммитам слияния не сохраняются. - person raittes; 27.06.2018
comment
В нем говорится: замените SHA ссылкой, от которой вы хотите избавиться, но в строке дважды присутствует SHA. Вот что я сделал. git rebase -p --onto 5ca8832c120 ^ 5ca8832c120 Но ничего не изменилось. Могу ли я использовать один и тот же SHA дважды? Если нет, то какой SHA должен быть удален и каким должен быть другой SHA? - person Rubicksman; 15.05.2019
comment
чтобы быть конкретным, этот метод удаляет ВЕСЬ коммит, включая файлы (в моем случае нежелательно) - person goofology; 11.07.2019
comment
@Rubicksman ^ должен быть экранирован (^^) в окнах (окно cmd) - stackoverflow.com/questions/1955985/ - person goofology; 11.07.2019
comment
на Mac: git rebase --onto SHA~ SHA - person dimpiax; 09.01.2020
comment
ТАК нужна кнопка, которая говорит, что это на самом деле ответ - person Cesar Varela; 22.07.2021

Скажем, мы хотим удалить коммиты 2 и 4 из репо. (Чем больше число новее фиксации; 0 - самая старая фиксация, а 4 - самая последняя фиксация)

commit 0 : b3d92c5
commit 1 : 2c6a45b
commit 2 : <any_hash>
commit 3 : 77b9b82
commit 4 : <any_hash>

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

  • git checkout b3d92c5 Извлечь последнюю использованную фиксацию.
  • git checkout -b repair Создайте новую ветку для работы.
  • git cherry-pick 77b9b82 Выполнить фиксацию 3.
  • git cherry-pick 2c6a45b Выполнить фиксацию 1.
  • git checkout master Кассовый мастер.
  • git reset --hard b3d92c5 Сбросить мастер до последней пригодной для использования фиксации.
  • git merge repair Слить нашу новую ветку с мастером.
  • git push -f origin master Отправить мастер в удаленное репо.
person tk_    schedule 05.09.2017
comment
последний шаг должен быть git push -f origin master нет варианта --hard - person vivex; 15.01.2018
comment
Думаю, commit 0 старше commit 1. Скажите, пожалуйста, почему сначала нужно пройти через commit 3 (по вишневому выбору), а затем через commit 1? После оформления заказа на b3d92cd (commit 0) я ожидал выбора вишни commit 1, затем commit 3. Спасибо. - person Jarek C; 05.11.2018
comment
@JarekC Я думаю, что самая верхняя фиксация - это самая новая фиксация здесь, если я не вижу что-то не так ... - person Jeff Huijsmans; 22.01.2019
comment
Это в основном правильно, но отчасти неправильно. Я просто следил за этим процессом, и мне пришлось его немного подправить. Уточнение: commit 0 - самая новая фиксация, commit 4 - самая старая. Начните с проверки commit 5 непосредственно перед фиксацией, которую вы не хотите. Затем cherry-pick commit 3, затем cherry-pick commit 1, затем сделайте это за commit 0. Затем выполните сброс мастера оформления заказа на commit 5 и выполните остальные шаги. - person Joshua Swain; 07.01.2021
comment
Хороший тщательный и безопасный подход. Управление изменениями в отдельной ветке означает, что вы даже можете выполнять интерактивную перебазировку в ветке repair и комбинировать коммиты перед повторным слиянием с master. Единственное, что у меня есть, это то, что вы можете объединить первые два шага: git checkout -b repair b3d92c5 - person camslice; 07.05.2021
comment
@JoshuaSwain Согласно моему пониманию этого ответа, фиксация 4 является последней, а фиксация 0 - самой старой. Одна из причин этого заключается в том, что в конце он объединяет мастер с ремонтной ветвью, чтобы окончательное дерево мастера выглядело так, как будто фиксации 2 и фиксации 4 не было. Все идет нормально? Теперь, прежде чем выполнять это слияние, он сбрасывает мастер на фиксацию 0, а затем объединяет два хороших коммита из ремонтной ветки. Если бы фиксация 4 была самой старой, тогда он бы не сбросил мастер на b3d92c5, а вместо этого сбросил бы на 77b9b82 - person utkarsh-k; 20.06.2021
comment
@ utkarsh-k Я добавил небольшое примечание к первой строке, чтобы прояснить вашу точку зрения. Не стесняйтесь улучшить свой ответ, используя функцию редактирования. Спасибо :) - person tk_; 21.06.2021

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

$ git reset --hard HEAD^

(обратите внимание, что это также удалит все незафиксированные изменения; используйте с осторожностью).

Если вы уже опубликовали коммит, подлежащий удалению, используйте git revert

$ git revert HEAD
person Jakub Narębski    schedule 27.08.2009
comment
Это не сработало. Когда я git log, все по-прежнему там, независимо от того, почему я это делаю, просто добавляет больше коммитов. Я хочу очистить историю. - person Costa Michailidis; 09.05.2014
comment
@Costa: Что не сработало (то есть какую версию вы использовали) и как вы прошли git log? - person Jakub Narębski; 09.05.2014
comment
Я перепробовал почти все в этом Q&A. (Я пробовал git revert HEAD, совсем недавно) Мой журнал git: tree = log --all --graph --format=format:'%C(bold blue)%h%C(reset) %C(dim black)%s%C(reset)%C(bold red)%d%C(reset) %C(green)by %an, %ar%C(reset)' - person Costa Michailidis; 09.05.2014
comment
@Costa: Обратите внимание, что с первой версией (с использованием git reset --hard HEAD^) вы удаляете фиксацию только из текущей ветки (фактически перемещаете указатель ветки), если бы была какая-то другая ветка, в которой была эта фиксация, она все равно была бы там. Удаление фиксации с помощью git reset просто перемещает указатель ветки назад, делая фиксацию висячей и доступной для сокращения ... если на нее не ссылается другая ссылка (другая ветка, ветка удаленного отслеживания или тег). Или вы использовали git revert HEAD? - person Jakub Narębski; 09.05.2014
comment
Я просто хочу удалить коммиты (как будто их никогда не было). Я отправился в какое-то странное приключение по программированию, сделал несколько новых коммитов, и все закончилось хламом. Как я могу просто стереть их из моего журнала git? - person Costa Michailidis; 09.05.2014
comment
Черт возьми, что-то волшебным образом сделало именно то, что я хотел .... какая из этих команд сделала это? !!?! - person Costa Michailidis; 09.05.2014

git reset --hard commitId

git push <origin> <branch> --force

PS: CommitId относится к тому, к которому вы хотите вернуться.

person sun34    schedule 16.10.2014
comment
git push --force ‹origin› ‹branchName›. поскольку без упоминания имени ветки он может изменить весь файл на удаленном компьютере. - person Sheelpriy; 22.06.2016

Принудительно изменить историю

Предполагая, что вы не просто хотите удалить последний коммит, но хотите удалить определенные коммиты из последних n коммитов, выполните:

git rebase -i HEAD~<number of commits to go back>, так что git rebase -i HEAD~5, если вы хотите увидеть последние пять коммитов.

Затем в текстовом редакторе измените слово pick на drop рядом с каждым коммитом, который вы хотите удалить. Сохраните и выйдите из редактора. Вуаля!

История дополнительных изменений

Попробуйте git revert <commit hash>. Revert создаст новую фиксацию который отменяет указанную фиксацию.

person IliasT    schedule 15.06.2017
comment
drop ключевое слово не определено. Чтобы удалить фиксацию, просто удалите всю строку. - person Shayan Salehian; 18.12.2018
comment
Для меня drop было определено как ключевое слово, но выполнение drop, похоже, не удаляло фиксацию из истории. Однако удаление строки из интерактивной перестановки произошло. - person Adam Parkin; 23.04.2019
comment
Это именно то, что мне нужно. Работает отлично; Благодарность! - person diekunstderfuge; 06.03.2020
comment
Я удалил строку, как предлагалось в нескольких местах: она ничего не сделала. Замена слова pick на drop удалила фиксацию. Примечание: инструкции находятся в выделенном разделе в нижней части содержимого текстового редактора. Использование git version 2.24.3 (Apple Git-128) - person leanne; 04.08.2020

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

git reset HEAD~1

Это вернет ваш репозиторий в состояние до того, как команды git add разместили файлы. Ваши изменения будут в вашем рабочем каталоге. HEAD ~ 1 относится к фиксации под текущей вершиной ветки.

Если вы хотите отменить N коммитов, но сохранить изменения кода в своем рабочем каталоге:

git reset HEAD~N

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

git reset --hard HEAD~1

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

git reset --hard HEAD~N
person Anurag-Sharma    schedule 31.05.2014
comment
Я попробовал это, и моя последняя фиксация была удалена, но теперь, когда я нажимаю на удаленный репозиторий, он говорит, что я должен вытащить перед нажатием. Итак, я потянул, а затем нажал, но когда я потянул, я снова получил фиксацию, которую я только что удалил, потому что я нажимал ее раньше на удаленный. Что мне теперь делать? - person an4s911; 11.08.2020

[Быстрый ответ]

У вас есть много альтернатив, например:

  • # P2 #
    git rebase -i <YourCommitId>~1
    
    # P3 #
  • # P4 #
    git reset --hard YourCommitId
    git push <origin> <branch> --force
    
    # P5 # # P6 #
  • # P7 #
    git reset --soft HEAD~1
    
    # P8 #
person Javier C.    schedule 30.10.2019

git rebase -i HEAD~2

Здесь «2» - это количество коммитов, которые вы хотите перебазировать.

'git rebase -i HEAD`

если вы хотите перебазировать все коммиты.

Тогда вы сможете выбрать один из этих вариантов.

p, pick = use commit

r, reword = use commit, but edit the commit message
e, edit = use commit, but stop for amending
s, squash = use commit, but meld into previous commit
f, fixup = like "squash", but discard this commit's log message
x, exec = run command (the rest of the line) using shell
d, drop = remove commit

Эти строки можно переупорядочить; они выполняются сверху вниз. Если вы удалите здесь строчку, КОМИТЕТ БУДЕТ УТЕРЯН. Однако, если вы удалите все, перебазирование будет прервано. Обратите внимание, что пустые коммиты закомментированы

Вы можете просто удалить эту фиксацию, используя опцию d или Удаление строки с вашей фиксацией.

person Siva Praveen    schedule 18.05.2016
comment
В последней версии git больше нет опции d. Вам нужно просто удалить строки с коммитами из rebase, чтобы удалить их. - person Oleg Abrazhaev; 18.01.2018

Чтобы удалить в локальной ветке, используйте

git reset --hard HEAD~1

Чтобы удалить в удаленной ветке, используйте

git push origin HEAD --force
person thestar    schedule 28.08.2014


Вот еще один способ сделать это:

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

git reset --hard COMMIT_ID

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

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

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

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

person CommaToast    schedule 13.05.2013

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

Я думаю, что нет никаких средств для удаления фиксации с помощью фарфоровых команд. Единственный способ - удалить его из журнала и reflog, а затем выполнить git prune --expire -now.

person Angelo Borsotti    schedule 04.10.2012
comment
Порядок, в котором ответы отображаются в StackOverflow, не фиксирован. Пожалуйста, не ссылайтесь на «Все приведенные выше команды». Сделайте свой собственный ответ самодостаточным. - person Pascal Cuoq; 16.01.2014
comment
Это не совсем правильный ответ. git prune на самом деле является одной из фарфоровых команд. Кроме того, вы редко хотите полностью очистить свой рефлог (один из вариантов использования - удалить конфиденциальную информацию из вашего репо, но, как я уже сказал, это редкий вариант использования). Чаще всего вы захотите сохранить старые коммиты в журнале ссылок на случай, если вам понадобится восстановить данные. См. Pro Git: 9.7 Git Internals - Обслуживание и восстановление данных. - person ; 14.05.2014

Ошибка:

Я git rebase -i --root редактировал свою ветку, невежественно думая, что могу переформулировать первую фиксацию, отличную от основной (представление по умолчанию GitHub для Windows - это сравнение с мастером, скрывающее его целиком).

Я отрастил бороду из Кремниевой долины, в то время как 900+ коммитов загрузились в Sublime. Выйдя без изменений, я зарядил батарею, а затем приступил к бритью, поскольку все 900+ отдельных коммитов небрежно перенастроили - сбросив время их фиксации на текущее время.

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

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

Исчерпывающие варианты:

Я не хотел git revert - это создаст дополнительную фиксацию, что даст Git преимущество.

git reset --hard HEAD ничего не сделал, после проверки reflog последним и единственным HEAD был клон - Git побеждает.

Чтобы получить самый последний SHA, я проверил удаленный репозиторий на github.com - небольшая победа.

Подумав, что git reset --hard <SHA> сработало, я обновил другую ветку до master и 1 ... 2 ... пуф! коммит вернулся - Git побеждает.

Возвращаюсь к мастеру, пора попробовать git rebase -i <SHA>, а затем удалить строку ... безрезультатно, к сожалению. "Если вы удалите здесь строчку, КОГДА БУДЕТ УТЕРЯНЫ". Ах ... замалчивается новая функция troll the n00b в Примечания к выпуску 2.8.3.

Решение:

git rebase -i <SHA>, затем d, drop = remove commit.

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

https://twitter.com/holman/status/706006896273063936

Хороший день для тебя.

person Leo    schedule 25.05.2016

Если вы хотите сохранить историю, показывая фиксацию и откат, вы должны использовать:

git revert GIT_COMMIT_HASH

введите сообщение с объяснением причины возврата, а затем:

git push  

Когда вы введете git log, вы увидите сообщения журнала как о «неправильной» фиксации, так и о возврате.

person Paulo Fidalgo    schedule 07.01.2015
comment
Да, но ОП было ясно, что они этого не хотят. - person Steve Bennett; 01.12.2015

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

git commit --amend -m "New message here"

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

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

Вы также можете передать параметр --no-edit вместо -m, если вы предпочитаете использовать сообщение предыдущей фиксации.

Документы: http://git-scm.com/docs/git-commit.html

person Pwnrar    schedule 26.05.2014
comment
OP просит не об этом. - person Steve Bennett; 01.12.2015

Что я обычно делаю, когда фиксирую и нажимаю (если кто-то подтолкнул свою фиксацию, это решит проблему):

git reset --hard HEAD~1

git push -f origin

надеюсь, что это поможет

person Chris Sim    schedule 14.06.2017

Я уже нажал. Необходимо вернуть некоторые коммиты обратно удаленно. Пробовали много вариантов, но только this из Justin через git bush у меня работает нормально:

git reset --hard $GIT_COMMIT_HASH_HERE
git push origin HEAD --force
person Serg Burlaka    schedule 08.02.2019

Если вы уже нажали, сначала найдите фиксацию, которую вы хотите разместить в HEAD ($ GIT_COMMIT_HASH_HERE), а затем выполните следующее:

git reset --hard $GIT_COMMIT_HASH_HERE
git push origin HEAD --force

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

git reset --hard origin/master
person Justin    schedule 30.01.2017

Сброс в локальном филиале

git reset --hard HEAD~<Number of commit> So git reset --hard HEAD~3

Принудительно нажать на исходную точку

git push -f origin
person Ashish Singh    schedule 29.05.2018

// display git commit log    
$ git log --pretty=oneline --abbrev-commit

// show last two commit and open in your default editor
// then delete second commit line and save it
$ git rebase -i HEAD~2

Ссылка: Как удалить совершить в git, локально и удаленно

person Shajed    schedule 26.06.2019

git reset --hard HEAD~1
Теперь вы будете в предыдущей главе. Вытащите ветку. Вставьте новый код. Фиксация будет удалена из git

person Jyotirmoy Upadhaya    schedule 20.01.2020
comment
Если вы уже не внесли изменения. В этом случае аппаратный сброс не очистит ваш пульт. В этом случае перебазирование - хороший вариант - person c0der512; 04.03.2020

Сделайте резервную копию вашего кода во временной папке. Следующая команда будет сброшена так же, как и сервер.

git reset --hard HEAD
git clean -f
git pull

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

git reset --soft HEAD^
git pull
person Lava Sangeetham    schedule 14.07.2016

удалить локальную фиксацию

Как вы можете видеть на изображении выше, я хочу удалить возврат «тестового изменения 2» фиксации (идентификатор SHA1: 015b5220c50e3dfbb1063f23789d92ae1d3481a2 (вы можете получить идентификатор SHA1 с помощью команды gitk в git bash)).

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

  1. git reset --hard 515b5220c50e3dfbb1063f23789d92ae1d3481a2 // он создает резервную копию этого коммита (SHA1 ID тестового изменения 4 фиксации - 515b5220c50e3dfbb1063f23789d92ae1d3481a2)
  2. git reset --hard HEAD~1 // оно создает резервную копию перед одной фиксацией.
  3. git reset --hard HEAD^ // Чтобы удалить последний коммит из git

после удаления:

после удаления фиксации

person ankit    schedule 03.07.2018

Здесь я просто публикую один чистый конвейер, чтобы сделать это

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

git log

введите описание изображения здесь

Шаг 2: используйте git reset, чтобы вернуться к предыдущей версии:

git reset --hard <your commit id>
person Frank    schedule 06.02.2021

git reset --hard

git push origin HEAD --force

Если одна или несколько фиксаций отмечены тегами, сначала удалите тег (ы). В противном случае помеченная фиксация не будет удалена.

person BillChan    schedule 24.07.2015

Для меня rebase помогло

$ git rebase -i HEAD~98

# Delete everything except for the most recent commit on the shown editor caused by "rebase"

$ git push origin -f production-static

ПРИМЕЧАНИЕ. После принудительного нажатия, чтобы уменьшить количество моих комментариев. Затем я отправил другой набор файлов, а затем попытался извлечь из того же репозитория и ветки на другом компьютере. На удивление конфликта нет. Это стало моим способом уменьшить размер репозитория, избегая при этом конфликтов с другими моими локальными пользователями, которые используют тот же git

person Dean Christian Armada    schedule 04.01.2021

используйте git revert https://git-scm.com/docs/git-revert Он вернет весь код, после чего вы сможете выполнить следующую фиксацию. Затем голова будет указывать на эту последнюю фиксацию. отмененные коммиты никогда не удаляются, но это не повлияет на вашу последнюю фиксацию.

person Uttam Rahane    schedule 01.03.2017

В моем случае мой волшебный код для этой цели таков:

git reset --hard @{u}

Протестируйте и расскажите мне. Я пробовал несколько разных, но только этот мне помог.

person Mauro Bilotti    schedule 13.11.2019

Если вы пользователь IntelliJ, интерфейс просто потрясающий. С помощью одного щелчка вы можете сразу увидеть эффект. Ярлык для этого места: Cmd + 9

введите описание изображения здесь

person Saurav Sahu    schedule 08.07.2021

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

person zacharydl    schedule 31.12.2014
comment
Очевидно, он помещается в репозиторий на основе OP. - person Lucas Huang; 16.04.2016
comment
@LucasHuang Нет, это не так: когда я делаю push в будущем, мои изменения не будут отправлены в удаленную ветку - person xhienne; 09.12.2016

person    schedule
comment
HEAD~1 или просто HEAD^. Если вы нажали, вы должны вместо этого использовать git revert. - person Jakub Narębski; 27.08.2009
comment
Очевидно, вы также можете использовать HEAD~n для возврата n коммитов из головы. Возможно, с этого момента вы можете интерпретировать ... --hard HEAD также как HEAD~0 = ›удаление незавершенной работы. - person nuala; 11.06.2012
comment
@ beamrider9 Вот что означает --hard. - person Chad; 31.08.2012
comment
@ beamrider9 imho git rebase почти всегда лучший способ удалить коммиты (как описано в ответе Грега Хьюгилла) - не в последнюю очередь потому, что rebase действительно включает большое предупреждение о том, что вы будете удалять материал 4realz. - person Noah Sussman; 26.10.2012
comment
может быть, это следует изменить, чтобы упомянуть --soft? - person rogerdpack; 21.12.2012
comment
это не удаляет изменения из дерева фиксации. OP запросил уже сделанную фиксацию. Если вы reset --hard и отметите log --oneline --all, коммиты все равно останутся в дереве. Как удалить эти коммиты из дерева? Спасибо. - person iGbanam; 17.03.2013
comment
Спасибо за подробную документацию. Единственное, что я бы добавил, это то, что rebase обычно используется для работы с несколькими ветвями, а не для удаления одной фиксации в одной ветке. - person Will Nielsen; 03.06.2013
comment
используйте reset --soft для удаления локального коммита БЕЗ отката выполняемой работы! - person ; 24.09.2013
comment
Рад, что прочитал комментарии, чтобы узнать, что этот ответ на самом деле не отвечает на вопрос, в репо не должно быть остатков, как если бы я не делал этого коммита. - person bradw2k; 16.01.2015
comment
Вы определенно заслуживаете голоса, потому что за последний год я просматривал это как минимум 5 раз. - person Akshat Agarwal; 18.07.2015
comment
Подтверждая, что в сентябре 2015 года это сработало для меня git reset --hard <sha1-commit-id>, чтобы сделать последнюю фиксацию, как будто этого никогда не было - person Eric Hepperle - CodeSlayer2010; 12.09.2015
comment
Я не понимаю, почему все рекомендуют git reset --hard ..., а затем продолжают объяснять, как следует следить за изменениями рабочего каталога и т. Д. Что ж, почему бы вместо этого не использовать более подходящий и менее опасный git reset [--soft] (т.е. мягкий или смешанный сброс)? - person amn; 18.05.2017
comment
Отказ от фиксации посредством перебазирования - менее агрессивное решение для достижения той же цели. См. Мой ответ для более подробной информации. - person IliasT; 27.06.2017
comment
Пожалуйста, поправьте меня, если я ошибаюсь: я всегда HEAD~1 означает «Перейти к предыдущей фиксации». Но «Перейти к» является результатом команды. HEAD~1 просто означает «предыдущая фиксация». Команда reset --hard HEAD~1 означает Перейти к ‹предыдущей фиксации› ` - person Honey; 21.09.2017
comment
HEAD - это ссылка на текущий извлеченный коммит. HEAD^ ссылается на своего родителя. HEAD^^ ссылается на его дедушку или бабушку. HEAD~N ссылается на своего N-го родителя. Если вы посмотрите на git log, вы увидите, что HEAD~3 является четвертой записью вниз. И да, их можно использовать в любой операции git, для которой требуется фиксация в качестве аргумента. Ветка, кстати, всего лишь еще одна ссылка на коммит :) - person gahooa; 26.09.2017
comment
Вы спасли мою жизнь. - person Mathiasfc; 10.07.2019
comment
если у меня есть неопубликованные коммиты и незафиксированные изменения, будут ли git reset --hard удалены мои коммиты? - person Daniel Springer; 01.11.2019
comment
@DanielSpringer, git reset --hard <commit> сбросит вашу HEAD до указанной фиксации и отменит любые изменения в вашем индексе. Все файлы рабочего дерева, которые не отслеживаются и не были добавлены в git, останутся. Вы можете использовать git clean -df, чтобы удалить их, однако выполняйте упражнения с большой осторожностью. - person gahooa; 10.11.2019
comment
Что, если я не укажу фиксацию? Будут ли потеряны неопубликованные коммиты? - person Daniel Springer; 10.11.2019
comment
Как я могу отклонить незафиксированные изменения? Я знаю только один способ git reset --hard - person Daniel Springer; 15.11.2019
comment
stackoverflow.com/a/32318688/2694784 лучше, поскольку он показывает, как удалить фиксацию, которая не находится наверху. - person Karan Bansal; 02.07.2020