Каким образом git commit -amend работает, точно?
Я видел GIT commit --amend в отдельном состоянии HEAD. Вопрос требует, чтобы ответ был более сложным, чем нужно. Я хотел бы понять, как git commit --amend
работает в нормальной ситуации с HEAD.
Ответы
Ответ 1
Предположим, что вы находитесь в чистом рабочем состоянии и что ваше репо выглядит следующим образом:
Если вы запустите
git commit --amend
записать сообщение о фиксации, сохранить и закрыть редактор, произойдет следующее:
- Ваша промежуточная область, которая, если вы не устроили никаких новых изменений, будет идентична commit
f42c5
- используется для создания нового фиксации: 31b8e
. Его родитель будет таким же, как и те (те) комманды, которую вы исправляете: f42c5
.
- Ссылка на ветку
master
перемещается, чтобы указать на новый фиксатор (31b8e
).
- Ссылка
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
, reset master
или иначе переместили ссылку на master
)
git checkout master # just to be sure that master is the current branch
git reset --hard [email protected]{1}
поставит вас в следующую ситуацию:
Но теперь commit 31b8e
станет недоступным.
Ответ 2
Скажите, что вы только что сделали "B"
... --- A --- B
^
|
master
HEAD
Изменение "B" создаст параллельную фиксацию, которая станет новой ветвью ветки.
+---- B
|
... --- A --- B'
^
|
master
HEAD
B '- это фиксация, полученная из комбинации изменений из B плюс изменения, которые вы поставили, когда вы выпустили git commit --amend
.
Ответ 3
По моим сведениям, ammend
работает таким образом:
В случае git commit --ammend
изменения изменений в амперметре должны быть в области Stagging (SA)
- Он делает
git reset -- soft
для возврата изменений, внесенных в последний коммит (commit to amend) в SA, и переводит индекс в предыдущее commit (commit перед фиксацией для изменения). Все хранится, как было до использования команды git commit
.
- Он делает
git add
со всеми файлами, которые нужно добавить к новому фиксации (это будет исправленная фиксация). Добавляемые файлы находятся в SA до того, как git reset --soft
был приземлен, после reset эти файлы попадают в WD, поэтому необходимо добавить их в SA для генерации исправленного коммита.
- Делает git commit. Он будет генерировать новую фиксацию и, следовательно, новый идентификатор для исправленного коммита. Для этого git commit -ammend не следует использовать с нажатыми коммитами
Если вы используете --no-edit
, комментарий повторно используется в исправленном коммите, иначе вы должны ввести новый комментарий (потому что это новый коммит, и каждый коммит требует комментария).
Для получения дополнительной информации о области оцепенения и рабочем каталоге см. Reset Demystified