GIT commit --amend в отдельном состоянии HEAD

Я понимаю, что правильным способом изменения старого коммита GIT является использование rebase --interactive, но чтобы просто понять концепции, я хотел бы понять, что происходит, когда я делаю

  • git checkout <commit>
  • изменить что-то в файле
  • добавить измененный файл в индекс
  • а потом git commit . --amend

Когда я делаю это, вместо внесения изменений в коммит, он разветвляет новый коммит от РОДИТЕЛЯ того же коммита.

Это просто способ GIT сказать мне, что я не могу изменить коммит, в котором уже есть дочерние коммиты?

1 ответ

Решение

В Git, когда коммит создан, он помещается в камень; Вы не можете изменить это. Все, что вы можете сделать, это создать новый коммит, который "напоминает" его - путем внесения в него изменений, выбора вишни и т. Д.

Я понимаю ваше замешательство: "изменить" - это немного неправильно; это несколько вводит в заблуждение, поскольку предлагает изменить что-то на месте. В Git внесение изменений в коммит на самом деле заключается в создании нового коммита, у которого те же родительские элементы, что и у исходного коммита.

В качестве примера, давайте предположим, что после запуска git checkout B Вы находитесь в следующей ситуации:

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

(Ваш HEAD отсоединен, но это не относится к делу.) Независимо от того, вносите ли вы изменения и вносите изменения, работает git commit --amend поставит вас в такую ​​ситуацию:

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

совершить D может быть очень, очень похож на B; в частности, он может иметь точно такой же патч, точно такое же сообщение о коммите, как Bи т. д. Однако временные метки (коммит, автор) обычно отличаются ( если вы не можете изменить коммит менее чем за секунду!), что означает SHA-1 D будет отличаться от B; и если два коммита не имеют одинаковый SHA, это не тот же коммит.

Когда мы говорим B родительский коммит C мы имеем в виду совершить C ссылки совершают B его SHA. Тем не менее, совершить C не может ничего знать о SHA коммита D, потому что делаете D был создан после C, Следовательно, D не может быть C родитель. Вот почему совершают D уходит по касательной и не имеет потомков.


Если вы хотите приземлиться в следующем штате,

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

где B' даже немного отличается от B, вы должны использовать git rebase -i не git commit --amend,

Другие вопросы по тегам