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
,