Почему git иногда показывает, что файл был изменен, когда его нет?
DragonFly BSD использует git в качестве SCM, с одним репозиторием и ветвью как для ядра, так и для всего пользовательского пространства.
В 2011-11-26 кто-то сделал коммит, который каким-то образом затронул каждый файл в репозитории, хотя большинство файлов не были изменены вообще.
Это оскорбительный коммит с 2011-11-26:
http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/86d7f5d305c6adaa56ff4582ece9859d73106103
https://github.com/DragonFlyBSD/DragonFlyBSD/commit/86d7f5d305c6adaa56ff4582ece9859d73106103
С тех пор, с некоторыми инструментами, если вы посмотрите на историю файлов для любого файла в репозитории, вы увидите, что он был изменен в 2011-11-26 с этим коммитом, но он показан только в некоторых инструментах и не показан в другие.
Например, фиктивная фиксация 2011-11-26 не отображается со следующими инструментами:
git log sys/sys/sensors.h
https://github.com/DragonFlyBSD/DragonFlyBSD/commits/master/sys/sys/sensors.h
Тем не менее, фиктивный коммит ошибочно показан со следующим:
git whatchanged --pretty=%at sys/sys/sensors.h
1322296064 :000000 100644 0000000... 554cfc2... A sys/sys/sensors.h 1191329821 :000000 100644 0000000... 554cfc2... A sys/sys/sensors.h
Время 1322296064 является фиктивным, и обратите внимание, как файл был
A
дд, не удаляясь, и чтоdst
Sha1 такой же. Другой, более представительный пример, который показывает, чтоsrc
Sha1 всегда0000000...
в таких фиктивных коммитах, хотя это не имеет особого смысла, если учесть, что файл никогда не удалялся и по-прежнему имеет тот жеdst
sha1:% git whatchanged --pretty=%at sys/sys/sysctl.h | head -9 1322296064 :000000 100644 0000000... 6659977... A sys/sys/sysctl.h 1296826445 :100644 100644 94b8d96... 6659977... M sys/sys/sysctl.h 1292413105 :100644 100644 8c9deaa... 94b8d96... M sys/sys/sysctl.h
http://gitweb.dragonflybsd.org/dragonfly.git/history/HEAD:/sys/sys/sensors.h
Мои вопросы следующие:
Как было возможно, чтобы файлы были добавлены без предварительного удаления? Был ли это / это ошибка в git, чтобы позволить что-то подобное?
Почему некоторые инструменты уплотняют такие фиктивные коммиты (и скрывают их от пользователя), а некоторые нет?
Есть ли способ сделать
git-whatchanged
а такжеgitweb
игнорировать такие фиктивные коммиты на файлы, которые на самом деле не были изменены, так же какgit-log
а такжеgithub
делать?
1 ответ
Я посмотрел на коммит и нашел ответ:
Это "корневой коммит" - у него нет родителей. Обычно единственным коммитом в репо с таким свойством является первый коммит в истории.
Таким образом, каждый файл в этом коммите действительно новый, потому что не существует более старой версии.
git log
отфильтровывает этот коммит, потому что он не является первым родителем в точке слияния. Я не знаю логику, которая приводит git log
полагать, что есть что-то, что можно игнорировать в первую очередь.
Нет, нельзя заставить другие инструменты игнорировать такие коммиты, потому что они просто выполняют свою работу.
Что здесь пошло не так, так это то, что этот коммит никогда не должен был быть создан без родителя, и если кто-то создает коммит как этот, он никогда не должен нигде объединяться