Здесь есть пара примечательных вещей, но давайте начнем с ответа:
git diff --name-only L R
сравнивает два конкретных коммита, используя ваши настроенные значения по умолчанию (например, diff.renames
и diff.renameLimit`), и выдает только имена файлов, которые отличаются коммитами L (слева) и R (справа). Если вы поменяете местами два имени, вы получите одинаковый вывод. Если обнаружение переименования действует, вы получаете имя, которое появляется в коммите R:
$ git diff 99177b34db^ 99177b34db --name-only
contrib/hooks/multimail/CHANGES
contrib/hooks/multimail/CONTRIBUTING.rst
contrib/hooks/multimail/README.Git
contrib/hooks/multimail/README.rst
contrib/hooks/multimail/doc/gitolite.rst
contrib/hooks/multimail/git_multimail.py
contrib/hooks/multimail/migrate-mailhook-config
contrib/hooks/multimail/post-receive.example
Переключение на --name-status
дает нам больше информации:
$ git diff 99177b34db^ 99177b34db --name-status
M contrib/hooks/multimail/CHANGES
M contrib/hooks/multimail/CONTRIBUTING.rst
M contrib/hooks/multimail/README.Git
R095 contrib/hooks/multimail/README contrib/hooks/multimail/README.rst
M contrib/hooks/multimail/doc/gitolite.rst
M contrib/hooks/multimail/git_multimail.py
M contrib/hooks/multimail/migrate-mailhook-config
M contrib/hooks/multimail/post-receive.example
Статус R
указывает, что Git обнаружил переименование. Теперь вы получаете оба имени: слева от L , а справа от R .
Двухточечная запись
Здесь я написал 99177b34db^ 99177b34db
вместо 99177b34db^..99177b34db
. Во многих командах Git они очень разные. Но для команды diff
они означают точно то же самое . Нет никаких оснований для использования двух точек, но также нет никаких причин для избегания двух точек. Правила для имен веток запрещают две соседние точки: имена веток, такие как feature.one
и feature.two
, являются законными, но feature..two
- нет.
(Не путайте двухточечную запись с трехточечной. Это также имеет особое значение в git diff
.)
Фиксация хэшей против имен ветвей
Я использовал 99177b34db
вместо имени ветви. Вы писали:
origin/oldbranch..origin/newerbranch
(одинарные кавычки здесь не нужны, поэтому я удалил их для простоты). Во многих командах Git имя ветки означает то же самое, что и идентификатор хеша коммита, к которому оно относится:
$ git rev-parse master
b5101f929789889c2e536d915698f58d5c5c6b7a
Вы можете использовать необработанный хэш-идентификатор или его сокращенную форму для обозначения этого конкретного коммита. Причина использования ветви name заключается в том, что идентификатор хеша фиксации, идентифицируемый с помощью , меняется с течением времени по мере добавления новых фиксаций в ветку. Идентификаторы в основном бесполезны для людей, а имена создаются людьми и для людей.
(Некоторые команды, такие как git checkout
, делают с именем что-то более интересное, поэтому для этих команд имя не взаимозаменяемо с хеш-идентификатором.)
Обнаружение переименования является опцией
То, что делает git diff
, сравнивает два снимка . Каждый коммит представляет собой полный, полный снимок каждого исходного файла. Git берет левый коммит и правый и сравнивает их. Для файлов, которые находятся в обоих коммитах и одинаковы в обоих коммитах, git diff
ничего не говорит. Для файлов, которые отличаются или находятся только в одном коммите или другом, git diff
что-то говорит.
С --name-only
то, что он говорит, - это имя (имена) файла (ов) в R , которые отличаются. С --name-status
он дает имена и , что отличало их: они могут быть изменены, т. Е. Представлены в обоих коммитах, но с другим содержимым, или добавлены заново, т. Е. В коммите R * Только 1082 * или удалено, т. Е. В коммите L только.
Когда вы включаете обнаружение переименования, если какой-либо файл удаляется в L , а в R создается * файл с другим именем, git diff
делает кучу дополнительных вычислений, чтобы решить действительно ли новый файл в R"совпадает" с файлом в L . Эта концепция одинаковости - или идентичность (см. https://en.wikipedia.org/wiki/Ship_of_Theseus)—is, на самом деле довольно сложная, хотя Git дает простой и непостижимый ответ: два файла одинаковы, если Git вычисляет индекс подобия соответствует некоторому пороговому значению. По умолчанию установлено значение «50% похоже».
Буквенный код для обнаруженного переименования: R
; за этим следует индекс сходства. Чем выше индекс, тем более похожи файлы. 100
зарезервировано для точно такого же , что является чем-то особенным в Git: если два файла абсолютно одинаковы, они на самом деле хранятся только один раз , и Git может обнаружить это точное совпадение очень быстро.
Если обнаружение переименования отключено, вы просто удалите файл из L и файл с другим именем добавлен в R , даже если два файла являются побитовымиидентичны.Поскольку обнаружение переименования является элементом конфигурации, два разных пользователя, выполняющих git diff
на одних и тех же двух коммитах, могут видеть разные результаты.