Правильный и точный ответ немного сложен, но немедленный ответ - «да». Более конкретно:
[В выводе git log
это] первый коммит [показанный] текущий коммит ветви?
Да, это так.
Причина, по которой полный ответ сложен, заключается в том, что git log
показывает коммиты по одному, а иногда git log
имеет два коммита, которые он хочет показать одновременно. Он не может этого сделать, поэтому он должен выбрать один из двух и показать это. Тем не менее, работает:
git log
эквивалентно выполнению:
git log HEAD
, который говорит git log
начинать с проверки текущего коммита . Если имя HEAD
присоединено к имени ветви, т. Е. Если git status
скажет on branch <em>B</em>
для некоторого B , то текущий коммит является самым верхним коммитом ветви B . Всегда есть 1 только один текущий коммит: никогда не бывает два текущих коммитов, может быть только один. Таким образом, с git log HEAD
или git log
без дополнительных аргументов Git начинает с этого текущего коммита.
1 Ну, почти всегда. Есть необходимый особый случай. Предположим, вы создали пустой репозиторий, в котором нет коммитов. Какой коммит будет текущим коммитом? Там еще нет коммитов , поэтому Git нужен способ, чтобы no коммит был текущим. Когда есть коммиты, Git выберет один из них, чтобы быть текущим.
Вы можете вызвать особый случай и вернуться к нет текущего коммита, используя git checkout --orphan
, но это завершает набор случаев: есть либо один текущий коммит - обычный случай - или есть no текущий коммит, в новом пустом репозитории или в этом специальном режиме git checkout --orphan
(оба используют один и тот же трюк, чтобы разрешить ситуацию no current commit ).
Полный и точный полный рассказ
Как видите, к каждому коммиту прикреплена отметка даты и времени:
Date: Wed May 9 22:00:35 2018 +0800
Фактически, каждый коммит имеет две этих прикрепленных меток времени. Чтобы увидеть оба, запустите git log --pretty=fuller
. Однако команда git log
не использует эти отметки даты и времени напрямую. Гораздо важнее тот факт, что каждый коммит имеет хэш-идентификатор , и большинство коммитов содержат один или иногда два других хеш-идентификатора коммита. Вы можете увидеть некоторые из них здесь:
commit a57089b64890e5602a39dc33dc1f07d620d8a870
Merge: c57feb6 9116e2b
Author: ...
Date: ...
Обратите внимание на случайную строку цифр и букв a57089b64890e5602a39dc33dc1f07d620d8a870
. Это хэш-идентификатор этого конкретного коммита. Под ним находится слово Merge:
и еще две строки из цифр и букв: c57feb6
и 9116e2b
. Это сокращенные хэш-идентификаторы двух родительских коммитов коммита a57089b...
.
Первый большой безобразный хэш-идентификатор, a57089b...
, - это настоящее, истинное, внутреннее имя Git для коммита. Вот как Git получает доступ к коммиту. Но чтобы найти этот большой некрасивый хеш-идентификатор, Git нужна какая-то начальная точка или, скорее, конечная точка.
Конечной точкой, с которой начинается Git, является коммит 75a80c128ea8b28f946b1bd55afa65cc1802bee5
. Посмотрите на первую строку вывода git log
и увидите там хэш-идентификатор. Git нашел этот большой некрасивый хэш-идентификатор, прочитав текущее имя ветки , например master
(любую ветку, которую вы на самом деле извлекли). Это имя хранит хэш-идентификатор.
Тем временем commit 75a80c1...
сохраняет в качестве своего (единственного) родительского хеш-идентификатора идентификатор commit merge a57089b...
. Таким образом, показав, что вы совершаете 75a80c1...
, git log
переходит к совершению a57089b
. Он показывает вам этот коммит как показанный второй коммит. Но теперь Git имеет два коммитов, чтобы показать: c57feb6
и 9116e2b
.
Thegit log
команда должна выбрать один из этих двух коммитов для показа. Это делается путем помещения обоих коммитов в приоритетную очередь . Затем он выбирает из этой очереди фиксацию с самым высоким приоритетом. Но какой коммит это это? Ну, это зависит от параметров, которые вы передаете git log
. по умолчанию - сортировать содержимое очереди по CommitDate
отметке времени (снова используйте git log --pretty=fuller
, чтобы увидеть эти отметки времени), причем более старые коммиты имеют более высокий приоритет, чем более новые.
Date:
, который вы видите в обычном выводе git log
, это не CommitDate
, а AuthorDate
. Чтобы сделать git log
сортировку по этой дате, используйте --author-date-order
(но учтите, что это также подразумевает топологическую сортировку).
В любом случае, ключевым моментом здесь является то, что фактические метки времени имеют значение всякий раз, когда git log
имеет более одного коммита для показа . До этого момента в очереди приоритетов был только один коммит: Git удаляет коммит из очереди, показывает его, затем помещает родителя коммита в очередь, давая Git один коммит для показа. Git удаляет один коммит, показывает его, помещает родителя и т. Д. Когда вы нажимаете коммит слияния, этот процесс автоматически помещает в очередь как минимум два коммита.
Но если вы запускаете git log branch1 branch2 branch3
, Git начинает с помещения трех коммитов в приоритетную очередь. 2 Теперь Git отображает более одного коммита, и снова значения отметок времени вступают в силу. Это также применимо, когда вы запускаете git log --all
или git log --branches
, если есть несколько ссылок, с которых будет начинаться git log
.
Следовательно, здесь действует следующее правило: , пока вы начинаете с HEAD
, вы сначала видите текущий коммит. Это потому, что существует только один текущий коммит, поэтому на показе только один коммит. во-первых, даже если это коммит слияния.
2 Предполагается, что имена трех ветвей указывают на три разных коммита, что не всегда верно, но об этом стоит беспокоиться позже.