Я обычно проверяю содержимое коммита с помощью "git diff commit ^!".
(Почему? Обычная команда: git show <commit>
.)
Однако, когда я применяю его к начальному коммиту, я вижу [что-то менее полезное]
Место, где можно найти (краткое) объяснение любого синтаксиса ревизий, - документация gitrevisons, который говорит это о суффиксе ^!
:
Запись r1 ^! включает в себя фиксацию r1 , но исключает всеего родители.Само по себе это обозначение обозначает единственный коммит r1 .
К сожалению, это объяснение слишком короткое .В этом случае более полезна подача ревизии на git rev-parse
:
$ git rev-parse HEAD
b5101f929789889c2e536d915698f58d5c5c6b7a
$ git rev-parse HEAD^1
a562a119833b7202d5c9b9069d1abb40c1f9b59a
Из этих двух выходных данных видно, что HEAD
представляет идентификатор хеша b5101f929789889c2e536d915698f58d5c5c6b7a
, а его первым родителем является a562a119833b7202d5c9b9069d1abb40c1f9b59a
,Вот что нам нужно для понимания:
$ git rev-parse HEAD^!
b5101f929789889c2e536d915698f58d5c5c6b7a
^a562a119833b7202d5c9b9069d1abb40c1f9b59a
Вывод здесь означает, по сути:
- начало в
b5101f929789889c2e536d915698f58d5c5c6b7a
... - но остановитесь на
a562a119833b7202d5c9b9069d1abb40c1f9b59a
.
(^
перед хеш-идентификатором означает «не»: коммит B, но не коммит A.)
Сравните это с:
$ git rev-parse HEAD^..HEAD
b5101f929789889c2e536d915698f58d5c5c6b7a
^a562a119833b7202d5c9b9069d1abb40c1f9b59a
Это тот же вывод!
Что это значит для git diff
немного хитро и тонко, потому что мы говорим о git rev-parse
здесь, а не git diff
,Но на самом деле, когда вы запускаете:
git diff <something>
Git внутренне передает <something>
на git rev-parse
.Поэтому, если вы введете:
git diff HEAD^..HEAD
git diff
, то внутренне передаст всю строку HEAD^..HEAD
внутренней версии git rev-parse
и получите идентификаторы "stop at" и "start at".Если вы наберете:
git diff HEAD^!
git diff
внутренне передает всю строку HEAD^!
во внутреннюю версию git rev-parse
и получит такие же «stop at» и «start»at "IDs.
То же самое происходит, когда вы используете хеш коммита для любого коммита, у которого есть один родитель: суффикс ^!
генерирует" not "для родительского хэша и" use "для хэша.
Но когда вы найдете root commit - в моем Git-репозитории для Git есть куча, так что я просто возьму первый:
$ git rev-list --max-parents=0 HEAD | head -1
0ca71b3737cbb26fbf037aa15b3f58735785e6e3
- когда мы дадим этот идентификатор хэша с суффиксом хет-бэнг для git rev-parse
, мы получим:
$ git rev-parse 0ca71b3737cbb26fbf037aa15b3f58735785e6e3^!
0ca71b3737cbb26fbf037aa15b3f58735785e6e3
То есть git rev-parse
сказал да для коммита, иНет всем его родителям, но родителей нет, поэтому он вообще сказал «нет»!
Если вы кормите этим git diff
- просто один хеш коммитов -команда git diff
думает: ах, вы хотите сравнить данный коммит с тем, что сейчас находится в вашем рабочем дереве .Итак, вот разница, которую вы получите.
Обратите внимание, что суффикс ^!
производит "not" для всех родителей коммита.Для фиксации слияния существует как минимум два (и обычно ровно два) родителя:
$ git show -s a562a11983
commit a562a119833b7202d5c9b9069d1abb40c1f9b59a
Merge: 7fa92ba40a ad6f028f06
Author: Junio C Hamano ...
Итак:
$ $ git rev-parse a562a11983^!
a562a119833b7202d5c9b9069d1abb40c1f9b59a
^7fa92ba40abbe4236226e7d91e664bbeab8c43f2
^ad6f028f067673cadadbc2219fcb0bb864300a6c
Когда вы задаете git diff
спецификатор ревизии, который расширяется до три или более фиксирует, иногда делает что-то другое.В этом конкретном случае, однако, он просто сравнивает коммит с первым родителем.Команда git show
вместо этого создаст комбинированный diff по умолчанию, который в этом случае вообще ничего не показывает, потому что комбинированные diff разработаны, чтобы показать вам, где слияния могли конфликтовать.