Фраза сохранить историю коммитов в Git - нонсенс.
Причина в том, что коммиты являются историей;история ничто , но фиксирует.У вас либо есть коммиты, поэтому все сохранено, либо нет, поэтому нет.
Что обычно подразумевают люди под этим: Я переименовал какой-то файл, и теперь не могу найтиэто. Это не удивительно, потому что каждый коммит Git - это просто снимок всех файлов.В коммите A
есть файлы README.txt
и starter.py
, а в коммите Z
в конце - README.rst
и alldone.py
.Если README.rst
было переименованием (и, возможно, также изменением) где-то по пути, ну, единственный способ найти , который должен идти Git, один коммит за раз, от Z
назадна Y
обратно на X
до тех пор, пока, в некоторый момент - скажем, между M
и N
- сравнение содержимого двух коммитов показывает, что wha-hey , README.txt
in M
очень много, как README.rst
в N
, поэтому назовем это переименованием и перестанем искать README.rst
и начнем искать README.txt
вместо этого.Вот что делает git log --follow
.
Если вы прыгнете прямо с Z
на A
, содержимое этих двух файлов может отличаться слишком сильно, чтобы соответствовать им.Но это нормально в отношении Git : если вы спросите , как мне отредактировать файлы в A
, чтобы они выглядели как файлы в Z
, Git скажет, удалить README.txt
и создать новый README.rst
с этим содержимым и , эти инструкции работают .Они не говорят, что вы хотите, чтобы вы хотели знать, но они достаточно хороши для Git.
Когда вы перемещаете функции из одного файла в другой, некоторые части Git, включая git blame
, может выполнять сравнения по коммиту, искать все файлы в предыдущем коммите и находить это (для git blame
вам нужен параметр -C
, вместо --follow
для git log
).Другие части Git, в том числе дифференцирование раннего коммита непосредственно с поздним коммитом, часто не могут: при сравнении любой пары коммитов переименованный файл должен быть достаточно похож на исходный файл для опции -M
/ --find-renames
, чтобыРабота.Вы можете настроить порог нахождения переименования: -M
при включении без какого-либо порога использует индекс сходства 50%, то есть примерно половина файла должна быть одинаковой в двух коммитах для Gitназывать это переименованием операции.Но это обнаружение переименования также требует выполнения нескольких других условий.Как правило, перемещение функции из одного существующего файла в другой существующий файл приводит к сбою.Для git diff
иногда можно также использовать -B
(флаг разрыва пар, который принимает до двух значений индекса сходства), но полезность этого довольно быстро уменьшается.