Как отменить «git commit --amend» вместо «git commit» - PullRequest
1105 голосов
/ 22 сентября 2009

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

Есть ли способ отменить этот последний коммит? Если я делаю что-то вроде git reset --hard HEAD^, первый коммит также отменяется.

(я еще не отправлял в удаленные каталоги)

Ответы [ 10 ]

1936 голосов
/ 22 сентября 2009

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

# Move the current head so that it's pointing at the old commit
# Leave the index intact for redoing the commit.
# HEAD@{1} gives you "the commit that HEAD pointed at before 
# it was moved to where it currently points at". Note that this is
# different from HEAD~1, which gives you "the commit that is the
# parent node of the commit that HEAD is currently pointing to."
git reset --soft HEAD@{1}

# commit the current tree using the commit details of the previous
# HEAD commit. (Note that HEAD@{1} is pointing somewhere different from the
# previous command. It's now pointing at the erroneously amended commit.)
git commit -C HEAD@{1}
117 голосов
/ 22 сентября 2009

используйте ref-log :

git branch fixing-things HEAD@{1}
git reset fixing-things

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

для просмотра полного списка предыдущих индексов наберите git reflog

52 голосов
/ 27 марта 2016

Найдите ваши исправленные коммиты:

git log --reflog

Примечание. Вы можете добавить --patch, чтобы увидеть текст коммитов для ясности. То же, что и git reflog.

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

git reset SHA1 --hard

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

Затем выберите другой коммит, который вам нужен:

git cherry-pick SHA1
23 голосов
/ 22 сентября 2009

Вы всегда можете разделить коммит, Из руководства

  • Начните интерактивное перебазирование с помощью git rebase -i commit ^, где commit - это коммит, который вы хотите разделить. Фактически подойдет любой диапазон фиксации, если он содержит этот коммит.
  • Отметьте коммит, который вы хотите разделить, с помощью действия «edit».
  • Когда дело доходит до редактирования этого коммита, выполните git reset HEAD ^. В результате HEAD перематывается на единицу, и индекс следует за ним. Однако рабочее дерево остается прежним.
  • Теперь добавьте изменения в индекс, которые вы хотите иметь при первом коммите. Для этого вы можете использовать git add (возможно, в интерактивном режиме) или git-gui (или оба).
  • Зафиксируйте текущий текущий индекс с любым подходящим сообщением.
  • Повторяйте последние два шага, пока ваше рабочее дерево не станет чистым.
  • Продолжить перебазирование с помощью git rebase --continue.
13 голосов
/ 03 марта 2017

Возможно, стоит отметить, что если вы все еще находитесь в своем редакторе с сообщением о коммите, вы можете удалить сообщение о коммите, и оно прервет команду git commit --amend.

13 голосов
/ 20 сентября 2016

Может быть, можно использовать git reflog, чтобы получить два коммита до изменения и после изменения.

Затем используйте git diff before_commit_id after_commit_id > d.diff, чтобы получить разницу между до и после изменения.

Следующее использование git checkout before_commit_id для возврата перед фиксацией

И последнее использование git apply d.diff, чтобы применить реальное изменение, которое вы сделали.

Это решает мою проблему.

3 голосов
/ 25 июня 2018

Вы можете сделать ниже, чтобы отменить ваш git commit —amend

  1. git reset --soft HEAD^
  2. git checkout files_from_old_commit_on_branch
  3. git pull origin your_branch_name

====================================

Теперь ваши изменения соответствуют предыдущим. Итак, вы сделали с отменой для git commit —amend

Теперь вы можете сделать git push origin <your_branch_name>, чтобы подтолкнуть к ветке.

2 голосов
/ 18 июня 2018

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

Поиск всех отсоединенных головок на ветке

git reflog show origin/BRANCH_NAME --date=relative

Тогда найдите хэш SHA1

Сброс к старому SHA1

git reset --hard SHA1

Затем поднимите его обратно.

git push origin BRANCH_NAME

Готово.

Это полностью вернет вас к старому коммиту.

(включая дату предыдущего перезаписанного отдельного коммита)

1 голос
/ 24 апреля 2019

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

git reset --soft <SHA BEFORE THE AMMEND>
#you now see all the changes in the commit and the amend undone

#save ALL the changes to the stash
git stash

git pull origin <your-branch> --ff-only
#if you issue git log you can see that you have the commit you didn't want to amend

git stash pop
#git status reveals only the changes you incorrectly amended

#now you can create your new unamended commit
1 голос
/ 04 марта 2016
  1. Извлечение во временную ветку с последним коммитом

    git branch temp HEAD@{1}

  2. Сброс последнего коммита

    git reset temp

  3. Теперь у вас будут все файлы вашего коммита, а также предыдущий коммит. Проверьте статус всех файлов.

    git status

  4. Сброс файлов коммитов со стадии git.

    git reset myfile1.js (т. Д.)

  5. Повторно прикрепить этот коммит

    git commit -C HEAD@{1}

  6. Добавить и зафиксировать ваши файлы для нового коммита.

...