Сделайте разницу с amend commit
интересно, можно ли это показать diff между двумя фиксациями один из того, что изменить ? Другими словами, git сохраняет исправленные коммиты в истории где-то?
2 ответов
измененная фиксация ничем не отличается от любой другой фиксации. В этом смысле вполне возможно различать "нормальную" фиксацию и фиксацию, которая была изменена.
другими словами, git сохраняет исправленные коммиты в истории где-то?
нет некоторого списка, который содержит все коммиты, которые были изменены, нет. Измененные коммиты в истории так же, как и все другие коммиты.
когда вы изменяете фиксацию, она в основном удаляется и заменен новым (он также получает новый хэш фиксации), который имеет изменения от исходной фиксации + измененные изменения.
на git reflog
вы можете увидеть свои последние действия, и это показывает изменение коммитов. Ссылки оттуда можно использовать, например, для отмены git commit --amend
. Также смотрите как отменить "git commit --amend "вместо" git commit" для получения более подробной информации об этом.
я не думаю, что понимаю вопрос, но я думаю, что отчасти это потому, что я думаю, что у вас неправильное представление о том, что git commit --amend
делает.
фиксация в git фактически не может быть изменена. Все это git commit --amend
не писать новая commit с намеренно измененным идентификатором родителя.
давайте посмотрим на обычный процесс для создания нового коммита.
прежде чем вы сделаете новую фиксацию, вы измените некоторые файлы в своем рабочем дереве, а затем вы используете git add
для стадии этих изменений, так что новые версии файлов будут зафиксированы. Это git add
ставит новую версию файла в индекс git"", т. е. его плацдарма.
файлы, которые уже были в предыдущей фиксации, уже находятся в промежуточной области. Таким образом, новая фиксация, которую вы сделаете, будет иметь все исходные файлы, за исключением того, что все, что вы изменили, а затем git add
- ed будет новой версией вместо старой версии.
теперь вы бежите git commit
(без --amend
) и git делает следующее:
- собрать коммита (с
-m
,-F
, или запуск вашего редактора); - получите свое имя и адрес электронной почты, а также текущее время;
- получить идентификатор SHA-1 текущей фиксации (не новой);
- используйте промежуточную область для записи объекта" дерево": это исходное дерево, которое будет связано с новой фиксацией;
- создайте объект фиксации со всем этим информация (автор+коммиттер, дерево, Родительский идентификатор и ваше сообщение)-Этот новый объект commit имеет новый уникальный идентификатор SHA-1;
- и, наконец, запишите новый идентификатор в ветку, чтобы метка ветви указывала на новый идентификатор вместо того, что раньше было самой веткой.
последний шаг "выращивает ветку", так что если у вас были некоторые коммиты, что-то вроде этого:
... <- E <- F <- G <-- master
теперь у вас есть еще один:
... <- E <- F <- G <- H <-- master
название филиала (master
или что бы это ни было) теперь указывает на ваш новейший commit H
и H
указывает на то, что используется чтобы быть вашим новейшим commit G
.
если вы используете git commit --amend
, git изменяет эту последовательность всего на один крошечный бит: вместо того, чтобы делать новую фиксацию (H
) вернуться к текущему (G
), git делает новый один пункт обратно к родителю текущего (в этом случае, F
):
G
/
... <- E <- F <- H <-- master
теперь master
(или какую-то другую ветку вы на) указывает на H
, который указывает на F
и так далее.
если вы запустите git log
, git начинается с текущей фиксации (H
) и регистрирует его, а затем переходит к его родителю (F
) и регистрирует его, и так далее. Commit G
кажется, ушел.
идентификатор SHA-1 для G
is все еще вокруг (в течение 30 дней по умолчанию), в "reflogs". Есть reflog для HEAD
, и один для вашей текущей веткой. Если вы на ветке master
и вы только что сделали H
, потом master@{1}
предыдущая верхушка master
, который совершал G
. Или, если у вас есть идентификатор SHA-1, сохраненный где-то на экране, вы можете вырезать и вставить его, чтобы увидеть commit G
.
(The --amend
переключатель также может изменить фиксацию слияния. Это работает точно так же, как и выше, это просто означает, что Git для копирования все родительские идентификаторы от старого наконечника ветви до Нового.)