Здесь есть несколько важных моментов, которые помогут вам:
Коммиты идентифицируются по их уникальному хэш-идентификатору. Имена ветвей просто содержат хэш-идентификатор одного конкретного коммита, который будет рассматриваться как последний коммит в этой ветке. Каждый коммит хранит хеш-код (ы) своих родителей.
Каждый коммит является полным снимком. То есть, коммиты не содержат изменений , поэтому нет ничего особенного в корневом коммите, кроме того, что у него нет родителя (ей).
Никакая часть любого коммита не может быть изменена.
Однако можно извлечь любой коммит (разморозить в индекс и, как правило, также в рабочем дереве). Извлеченный незамерзший коммит можно изменить, а новый индекс можно использовать для создания нового коммита, который, конечно, будет иметь другой хэш-идентификатор.
Следовательно, если у вас есть:
A <-B <-C <-- master1
D <-E <-- master2
и вам не нравится снимок в коммите D
, вы можете просто извлечь коммит D
и сделать новый коммит F
без родителя, чтобы F
был новым корневым коммитом:
$ git checkout master2
$ git checkout --orphan master3
$ git rm ...
$ git commit -m 'make commit F'
в результате:
A <-B <-C <-- master1
D <-E <-- master2
F <-- master3
Обратите внимание, что теперь вы должны скопировать эффект коммита E
, если хотите заменить master2
на master3
:
$ git cherry-pick master2
дает:
A <-B <-C <-- master1
D <-E <-- master2
F <-E' <-- master3
Теперь вы можете удалить master2
и переименовать master3
в master2
. Для тех, кто не обращает внимания на хэш-идентификаторы, а смотрит только на имена веток, теперь кажется , как будто вы изменили коммит D
. (Вы этого не сделали, и любой, кто обратил внимание на хэш-идентификаторы , как это делает Git, узнает об этом.)