Сделайте разницу с 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 для копирования все родительские идентификаторы от старого наконечника ветви до Нового.)