Я ищу команду, которую можно запустить без локального репо, точно так же, как мы можем выполнить git ls-remote без локальной копии репо.
Вам нужно будет запустить команду на на удаленном компьютере, т. Е. Иметь там доступ к оболочке или иметь кого-то внутри, кто даст вам черный ход для выполнения команды.Например, если удаленным является host2.example.com
, вы можете сделать:
ssh host2.example.com 'git -C /path/to/repo rev-parse ...'
Это, конечно, требует, чтобы вы могли войти на этот хост.Если вы не можете войти в систему на этом хосте, то нет, вам сначала нужно клонировать репозиторий.
Тем временем вернитесь к команде rev-parse
.В вашем случае это кажется достаточным, но в целом:
git rev-parse HEAD:path/to/subdir
очень отличается от команды, показанной в Хэш последнего коммита подкаталога (этобыл связан в какой-то момент, так что теперь это с помощью этого ответа):
git log -n 1 --format="%h %aN %s %ad" -- $directory
То, что git rev-parse HEAD:path/to/subdir
выводит на печать - это хэш-идентификатор внутреннего объекта Git tree , в котором хранится path/to/subdir
в пределах текущего коммита.Но то, что печатает git log -n 1 ... $directory
, это хэш-идентификатор некоторого коммита .Это никогда не является хеш-идентификатором любого объекта внутреннего дерева Git.
Фиксация, обнаруженная этим git log
, является первым коммитом, который удовлетворяет некоторому ограничению, в последовательности коммитов, сформированной перечислением коммитов, как git log
обычно так, по одному, начиная с HEAD
и работая в обратном направлении.Данное ограничение заключается в том, что, сравнивая (как с git diff
) (одиночный) родительский коммит некоторого коммита без слияния с самим коммитом, в этой паре коммитовнекоторые файлы в пределах path/to/subdir
изменены .
То есть предположим, что у нас есть следующий график частичного принятия:
...--F--G--H <-- master (HEAD)
, где H
некоторый хеш-идентификатор фиксации, G
является родителем H
, а F
является родителем G
.(Обратите внимание, что в этом фрагменте графа нет коммитов слияния.)
Предположим далее, что если мы сравним моментальный снимок в G
с моментальным снимком в H
, единственный файл изменено README.md
.Следовательно, git log -p
покажет, что в H
мы изменили README.md
.Однако при сравнении снимка в F
с снимком в G
файл path/to/subdir/foo.cc
изменился.Таким образом, git log -p
покажет, что в G
мы изменили файл в path/to/subdir
.
Поскольку git log
начинается с просмотра H
(и, таким образом, сравнивается G
-vs- H
), но затем продолжает смотреть на G
(и таким образом сравнивает F
-vs- G
), команда:
git log -n 1 --format="%h %aN %s %ad" -- $directory
напечатает сокращенный хеш (%h
)из коммита G
, имя автора (после применения .mailmap
, %aN
) из коммита G
, строка темы (%s
) из коммита G
и дата автора (%ad
) изcommit G.
Но при выполнении:
git rev-parse HEAD:path/to/subdir
печатает полный хэш-идентификатор объекта tree в commit H
, который содержит информацию о любых поддеревьях иBLOB-объекты, необходимые для моментального снимка, который является частью фиксации H
.
Если вы хотите перечислить (потенциально много) хеш-идентификаторов фиксации, с применением или без применения различных ограничений, вы используете git log
или git rev-list
следовать графику фиксации.В конце концов, именно это и делает команда git log
: проходит по графу фиксации, начиная с запрошенных вами начальных точек (или с HEAD
, если вы не запрашиваете какие-либо конкретные начальные точки) и показывая коммиты.
Если вам нужен один конкретный хэш-идентификатор коммита и вы достаточно знаете о , то вы можете использовать git rev-parse
.В некоторых случаях git rev-parse
может также обходить граф коммитов: в частности, он может найти коммиты, чье сообщение журнала коммитов содержит некоторую строку или регулярное выражение.Но он не достаточно умен, чтобы исследовать различия между родителями одного и того же коммита;для этого вам понадобится git log
или его сестринская команда, git rev-list
.
(Обратите также внимание, что по умолчанию git log
игнорирует различия всех коммитов слияния. Это потому, что дифференциал слияния усложняется тем фактом, что есть два или более родительских снимка: какой родитель должен Git использовать при создании различий? Чтобы избежать ответа на этот вопрос, git log
просто не удосуживается сделать различий, по умолчанию.)