Как работает git commit --amend?

Я видел GIT commit --amend в отдельном состоянии HEAD. Вопрос требует, чтобы ответ был более сложным, чем необходимо. Я хотел бы понять, как git commit --amend работает в нормальной ситуации HEAD.

4 ответа

Решение

Предположим, что вы находитесь в чистом рабочем состоянии и репо выглядит следующим образом:

Если вы тогда бежите

git commit --amend

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

  1. Ваша промежуточная область, которая, если вы не ставили никаких новых изменений, будет идентична для фиксации f42c5- используется для создания нового коммита: 31b8e, Его родитель (ы) будет таким же, как и родительский коммит: f42c5,
  2. master ссылка на ветку перемещается, чтобы указать на этот новый коммит (31b8e).
  3. HEAD ссылка следует master,

Обратите внимание, что исправленный коммит (f42c5) теперь недоступен из любой ссылки в вашем репо (отсюда и его "прозрачный" стиль на моем графике). Он по-прежнему живет в объектной базе данных вашего репозитория, но в конечном итоге будет удален навсегда, когда Git будет выполнять свою периодическую служебную работу или если вы запустите его явно, запустив git gc (вывоз мусора).


Приложение (на основе комментария Джейсона Бейкера): Обратите внимание, что, пока исправленный коммит, f42c5еще существует в вашем репо, и у вас есть способ узнать его идентификатор (например, выловив его из master Reflog), вы все еще можете проверить это. Бег

git checkout master # just to be sure that master is the current branch
git reset --hard f42c5

или (при условии, что вы не сделали ни одного нового коммита на master, сброс masterили иным образом переместил master ссылка на ветку)

git checkout master # just to be sure that master is the current branch
git reset --hard master@{1}

поставил бы вас в следующую ситуацию:

Но теперь, совершите 31b8e станет недоступным.


Скажи, что ты только что совершил "B"

... --- A --- B
              ^
              |
            master
             HEAD

Изменение "B" создаст параллельный коммит, который станет новым главой ветви.

        +---- B
        |
... --- A --- B'
              ^
              |
            master
             HEAD

B '- это коммит, полученный в результате комбинации изменений из B и изменений, которые вы сделали, когда вы выпустили git commit --amend,

По моим сведениям, ammend работает так:

За git commit --ammend работает, изменения должны быть внесены вStagging Area (SA)

  1. Это делаетgit reset -- softдля возврата изменений, зафиксированных в последнем коммите (commit to ammend) в SA, и перемещения индекса в предыдущий коммит (commit to commit to ammend). Все держи как было раньшеgit commitКоманда была использована.
  2. Это делаетgit addсо всеми файлами, добавляемыми в новый коммит (это будет исправленный коммит). Добавляемые файлы были в SA доgit reset --softПосле сброса эти файлы сохраняются в WD, поэтому необходимо добавить их в SA для созданияисправленного коммита.
  3. Делает мерзавец коммит. Он сгенерирует новый коммит и, следовательно, новый идентификатор для исправленного коммита. Для этого git commit --ammend не должен использоваться с push-коммитами

Если вы используете --no-edit комментарий повторно используется в исправленном коммите, в противном случае вы должны ввести новый комментарий (потому что это новый коммит, и каждый коммит нуждается в комментарии).

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

Предположим, вы создаете два файла test1.txt и test2.txt, затем запускаете

      git add test1.txt && git commit -m “test1.txt and test2.txt “

позже вы помните, что не добавили test2.txt Итак, вы хотите добавить отсутствующий файл test2.txt и изменить предыдущий коммит git add test2.txt

      git commit --amend -m "test1.txt & test2.txt added"

git log [to see that the previous commit message updated and test2.txt file added]
Другие вопросы по тегам