Устранение неполадок git Подмодуль резюме - PullRequest
0 голосов
/ 19 марта 2020

Я сталкиваюсь с некоторыми проблемами в понимании того, что точно делает git submodule summary? Как и когда мы используем эту команду? Я также не могу понять значение опции --files. Для меня не использовать тег выглядит так же, как использовать его.

Кроме того, чем он будет отличаться от git submodule status? Я очень смущен. Я читал Документацию команды, если она помогает.

Заранее большое спасибо за помощь! :)

1 Ответ

1 голос
/ 20 марта 2020

Для git submodule status:

$ git submodule status
hash-1 path-1 (describe-output-1)
hash-2 path-2 (describe-output-2)
   :
hash-n path-n (describe-output-n)

Это говорит вам, для каждого пути субмодуля, идентификатор ha sh фиксации, который был извлечен в пределах этого пути субмодуля, и результат выполнения git describe внутри этого подмодуля. Например, если вы увидели

 51ebf55b9309824346a6589c9f3b130c6f371b8f foo (v2.25.0-462-g51ebf55b93)

в качестве вывода, но затем сделали git checkout v2.15.0 в каталоге foo:

(cd foo; git checkout v2.15.0)

и запустили его снова, вы бы см .:

+cb5918aa0d50f50e83787f65c2ddc3dcb10159fe foo (v2.15.0)

вместо. (Знак + указывает, что он не синхронизирован; см. Ниже.)

Идентификатор ha sh является просто результатом выполнения git rev-parse HEAD в каждом подмодуле. Выходные данные описания - это просто результат запуска git describe в каждом подмодуле. Путь в середине - это аргумент, который вам нужно указать для команды cd (change-directory), чтобы переключиться с суперпроекта на данный подмодуль.

Для git submodule summary подробности немного сложнее. Это, в основном, запускает git log в каждом подмодуле.

Основы подмодулей

Помните, что подмодуль - это не что иное, как другой Git репозиторий - тот, который Git вызывает подмодуль - плюс немного клея в этом Git хранилище, которое Git вызывает суперпроект . «Клей» в суперпроекте состоит из очень небольшого числа элементов:

  • Информация, необходимая для git clone подмодуля, хранящаяся в файле с именем .gitmodules. Это используется, только когда вы сначала указываете суперпроекту Git сделать этот клон, например, через git submodule update --init.

  • имя пути подмодуля, как это появляется в суперпроекте. Суперпроект Git создаст пустой каталог / папку (какой бы термин вы ни выбрали) для хранения рабочего дерева для этого подмодуля. 1

  • A совершить га sh ID . Суперпроект Git примет этот коммит с идентификатором ha sh и, по сути, запустит (cd <em>path</em>; git checkout <em>hash</em>), чтобы перевести подмодуль Git в режим detached HEAD , с этой конкретной фиксацией.

Эти два последних элемента хранятся в каждом новом коммите, который вы делаете в суперпроекте (и уже сохранены в существующих коммитах). 2 Для get сохранено, имя пути и фиксация ha sh ID должны храниться в Git в index , потому что Git делает все новые коммиты из индекса.

( Если вам неясно различие между Git index и вашим рабочим деревом , см. В чем разница между HEAD, рабочим деревом и индексом, в Git? и Что означает git -rm под рабочим деревом и индексом? .)


1 В современном Git, .git для подмодуля, который появится в этом пути, является обычным файлом, содержимое которого будет путем, по которому подмодуль Git можно найти хранилище. Суперпроект Git выведет базу данных хранилища из подмодуля. Git называет это поглощением подмодулем. В более старых версиях Git подмодуль будет иметь собственную директорию .git / папку, содержащую базу данных репозитория подмодуля Git.

2 Фактически, первый элемент - файл .gitmodules - также должен присутствовать во всех этих коммитах, но, поскольку это обычный файл, в этом нет ничего особенного: вы просто работаете с ним, как с любым обычным файлом. Поскольку суперпроекту действительно требуется , он только один раз, при клонировании подмодуля, если вы случайно или намеренно пропустите его из новых коммитов, вы не заметите, пока кто-то другой не попытается использовать этот коммит в качестве отправной точки для клона super sh суперпроекта.

Так как изменить a .gitmodules файл довольно редко, и он переносит коммиты иначе, как и любой другой файл, это редко проблема. Это в основном проблема, только если вы создаете субмодуль, используя в первую очередь что-то отличное от * 1102. *


Чтение gitlinks, а не связывание непосредственно с субмодулем

Сверхпроектный объект, который записывает и путь, и идентификатор sh, готовый к go в вашем следующем коммите, называется gitlink . Он существует только в индексе Git, поэтому его очень трудно увидеть. (Вы можете вывести содержимое индекса, используя git ls-files --stage, но обычно это слишком многословно.) Но оно всегда есть: здесь говорится , чтобы использовать этот коммит, извлечение, как отдельный HEAD , this ha sh ID в this подмодуле .

Предположим, что есть подмодуль по пути sub (в индексе, как :sub или :0:sub - номер здесь - промежуточный слот). Когда вы делаете коммиты в суперпроекте, эта ссылка превращается в коммиты. Вы можете прочитать его из индекса:

git rev-parse :sub

или прочитать из текущего коммита:

git rev-parse HEAD:sub

или прочитать из любого коммита:

git rev-parse <hash>:sub

чтобы получить сохраненный gitlink ha sh ID для sub из данного коммита ha sh -ID.

Если вы запустите git submodule update в своем суперпроекте, то Git сделает соответствующий (cd sub; git checkout <hash>) в зависимости от того, какой идентификатор ha sh находится в индексе прямо сейчас. Это git checkout, если репозиторий подмодулей «чистый», чисто проверит этот конкретный коммит.

Но каждый подмодуль является репозиторием a Git - рабочим деревом, индекс и базовая база данных хранилища. Вы можете cd sub и git checkout, что хотите, или испачкали его индекс (sub) и / или его рабочее дерево. И этот подмодуль может иметь свои собственные имена веток - это репозиторий Git, и каждый репозиторий Git имеет имена веток, верно? Предположим, вы cd sub; git checkout master, например. Теперь этот подмодуль в ветви , а не в режиме detached HEAD . Вы можете делать новые коммиты, запускать git merge и / или выполнять все виды других команд. Вы можете получить новые коммиты из некоторого верхнего хранилища. Вы можете делать все, что захотите: это Git репозиторий со всеми доступными Git командами.

Предположим, что вы что-то сделали - не имеет значения, что - для некоторых Git хранилище, которое действует как подмодуль для какого-то суперпроекта. Теперь вы возвращаетесь к суперпроекту (cd ..) и в суперпроекте, вы спрашиваете его: какой коммит вы порекомендовали проверить? То есть вы читаете gitlink запись в суперпроекте, из индекса суперпроекта или из коммита.

У вас есть два идентификатора ha sh. Они могут быть одинаковыми! Может быть, master в подмодуле - это идентификатор ha sh, хранящийся в gitlink суперпроекта. Или, может быть, они разные. Если вы только что сделали новый коммит в подмодуле, он определенно отличается, потому что каждый новый коммит ha sh ID является уникальным.

Если они разные, git submodule status выведет +<hash> ; ha sh, который он печатает, - это тот, который фактически проверен в sub. Если они совпадают, он печатает (одиночный) идентификатор ha sh без +.

Между тем, если вы запустите git submodule summary, ваш суперпроект Git:

  • захватывает рекомендуется га sh ID
  • захватывает фактически проверено га sh ID
  • использует git log в подмодуле, чтобы найти, какие коммиты находятся «между» этими двумя идентификаторами ha sh.

В частности, он использует git log --oneline --left-right <hash1>...<hash2> (обратите внимание на --oneline и три точки здесь; он также вызывает еще несколько вариантов, но они являются ключевыми). Значение hash1 - это рекомендуемое га sh, а значение hash2 - , фактически проверенное га sh. Результатом этого списка является отображение коммитов, которые доступны с hash1, но не hash2 (с префиксом <) и коммитов, которые доступны с hash2, но не hash1 (с префиксом >).

(Подробнее о достижимости см. Think Like ( а) Git.)

git submodule summary: --files против --cached

Я также не могу понять значение --files опция

Параметр --files используется по умолчанию. Опция --cached изменяется, когда git submodule summary получает два идентификатора ha sh. Вместо получения первого га sh из индекса (:sub), а затем перехода в подмодуль и считывания значения HEAD для второго он считывает первый идентификатор из текущего коммита (HEAD:sub) и получает секунду из индекса (:sub). Остальная часть его работы такая же: введите подмодуль и запустите git log с соответствующими параметрами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...