Что означает древовидность в Git?
Я очень смущен тем, как использовать git archive
,
У меня есть git-репозиторий с папками Foo, Bar и Baz на верхнем уровне. Мне нужно экспортировать папку Foo в стиле SVN для быстрого тестирования.
Я узнал, что я мог бы использовать git-archive
в SVN-ишем способе экспорта.
Но вот в чем дело, следующее прекрасно работает:
git archive master | tar -x -C ~/destination
это приводит к папкам Foo, Bar, Baz в папке назначения.
Тем не менее, следующее будет ошибка с fatal not a valid object name
:
git archive master/foo | tar -x -C ~/destination
Документация
Выглядит как синопсис для git archive
Программа, которую я вижу, что это может занять <tree-ish> [path]
в качестве параметра (синопсис обобщен на соответствующие части):
git archive <tree-ish> [path...]
Если master/foo
не является tree-ish
тогда что это?
5 ответов
Краткий ответ (TL; DR)
"Tree-ish" - это термин, который относится к любому идентификатору (как указано в документации по ревизиям Git), который в конечном итоге приводит к (под) дереву каталогов (Git относится к каталогам как "деревья" и "объекты дерева").
В случае оригинального плаката, foo
каталог, который он хочет указать. Правильный способ указать (под) каталог в Git - это использовать синтаксис "tree-ish" (элемент № 15 из документации по ревизиям Git):
<rev>:<path>
например,HEAD:README
,:README
,master:./README
Суффикс
:
сопровождаемый путем именования большого двоичного объекта или дерева по данному пути в объекте tree-ish, названном частью перед двоеточием.
Итак, другими словами, master:foo
правильный синтаксис, а не master/foo
,
Другое "Tree-ish" (Plus Commit-ish)
Вот полный список идентификаторов commit-ish и tree-ish (из документации по ревизиям Git, спасибо LopSae за указание на это):
----------------------------------------------------------------------
| Commit-ish/Tree-ish | Examples
----------------------------------------------------------------------
| 1. <sha1> | dae86e1950b1277e545cee180551750029cfe735
| 2. <describeOutput> | v1.7.4.2-679-g3bee7fb
| 3. <refname> | master, heads/master, refs/heads/master
| 4. <refname>@{<date>} | master@{yesterday}, HEAD@{5 minutes ago}
| 5. <refname>@{<n>} | master@{1}
| 6. @{<n>} | @{1}
| 7. @{-<n>} | @{-1}
| 8. <refname>@{upstream} | master@{upstream}, @{u}
| 9. <rev>^ | HEAD^, v1.5.1^0
| 10. <rev>~<n> | master~3
| 11. <rev>^{<type>} | v0.99.8^{commit}
| 12. <rev>^{} | v0.99.8^{}
| 13. <rev>^{/<text>} | HEAD^{/fix nasty bug}
| 14. :/<text> | :/fix nasty bug
----------------------------------------------------------------------
| Tree-ish only | Examples
----------------------------------------------------------------------
| 15. <rev>:<path> | HEAD:README, :README, master:./README
----------------------------------------------------------------------
| Tree-ish? | Examples
----------------------------------------------------------------------
| 16. :<n>:<path> | :0:README, :README
----------------------------------------------------------------------
Все идентификаторы #1-14 являются "commit-ish", потому что все они приводят к коммитам, но поскольку коммиты также указывают на деревья каталогов, все они в конечном итоге приводят к (под) объектам дерева каталогов и поэтому могут также использоваться как "дерево". -ish".
# 15 также может использоваться как древовидная структура, когда он ссылается на (под) каталог, но он также может использоваться для идентификации конкретных файлов. Когда он ссылается на файлы, я не уверен, что он все еще считается "древовидной", или действует ли он как "blob-ish" (Git называет файлы "BLOB-объектами").
Длинный ответ
На самых низких уровнях Git отслеживает исходный код, используя четыре основных объекта:
- Аннотированные теги, которые указывают на коммиты.
- Коммиты, которые указывают на корневое дерево каталогов вашего проекта.
- Деревья, которые являются каталогами и подкаталогами.
- BLOB-объекты, которые являются файлами.
Каждый из этих объектов имеет свой собственный идентификатор хэша sha1, поскольку Линус Торвальдс разработал Git как файлово-адресуемую файловую систему, то есть файлы могут быть получены на основе их содержимого (идентификаторы sha1 генерируются из содержимого файла). В книге Pro Git приведен пример диаграммы:
Многие команды Git могут принимать специальные идентификаторы для коммитов и (под) деревьев каталогов:
"Коммит" - это идентификаторы, которые в конечном итоге приводят к объекту фиксации. Например,
tag -> commit
"Tree-ish" - это идентификаторы, которые в конечном итоге приводят к объектам дерева (т.е. каталога).
tag -> commit -> project-root-directory
Поскольку объекты коммитов всегда указывают на объект дерева каталогов (корневой каталог вашего проекта), любой идентификатор, который называется "commit-ish", по определению также является "tree-ish". Другими словами, любой идентификатор, который приводит к объекту фиксации, также может быть использован, чтобы привести к (под) объекту дерева каталогов.
Но поскольку объекты дерева каталогов никогда не указывают на коммиты в системе управления версиями Git, не каждый идентификатор, который указывает на (под) дерево каталогов, также может быть использован для указания на коммит. Другими словами, набор идентификаторов commit-ish является строгим подмножеством набора идентификаторов tree-ish.
Как объяснено в документации ( спасибо Trebor за помощь в ее поиске):
<tree>
Указывает имя объекта дерева.
<commit>
Указывает имя объекта фиксации.
<tree-ish>
Указывает имя дерева, коммита или тега. Команда, которая принимает
<tree-ish>
Аргумент в конечном итоге хочет оперировать<tree>
объект, но автоматически разыменовывается<commit>
а также<tag>
объекты, которые указывают на<tree>
,<commit-ish>
Указывает коммит или имя объекта тега. Команда, которая принимает
<commit-ish>
Аргумент в конечном итоге хочет оперировать<commit>
объект, но автоматически разыменовывается<tag>
объекты, которые указывают на<commit>
,
Набор идентификаторов дерева, который не может использоваться в качестве коммита
<rev>:<path>
, что приводит непосредственно к деревьям каталогов, а не к фиксации объектов. Например,HEAD:subdirectory
,Sha1 идентификаторы объектов дерева каталогов.
Tree-ish - это способ присвоения имени определенному дереву, которое может быть одним из следующих:
- Ссылки, такие как:
- ГОЛОВА
- Теги
- Названия филиалов
- Названия веток с пультами, вроде
origin/somebranch
- гашиш
- Короткие хэши
Кроме того, к любому из вышеперечисленного можно добавить ^
, ~
, Ссылки также могут использовать @{}
обозначение некоторых дополнительных функций:
HEAD^
или жеHEAD^1
будет решен с первым родителем HEAD.HEAD^2
разрешит второму родителюHEAD^3
разрешится к третьему родителю и так далее, что является более редким и продуктом слияния со стратегией осьминога.HEAD~
или жеHEAD~1
разрешит первому родителю головыHEAD~2
разрешится к первому родителю первого родителя HEAD. Это было бы так же, какHEAD^^
HEAD@{0}
разрешит текущую ГОЛОВУHEAD@{1}
разрешу к предыдущей главе. Это может использоваться только ссылками, так как в нем используется журнал ссылок. В случаеHEAD
Каждый коммит, слияние, извлечение изменят значение HEAD и, таким образом, добавят его в журнал.git reflog HEAD
отобразит журнал ссылок, где вы можете увидеть все движения ГОЛОВКИ и правильно, что@{1}
и так далее разрешат.
Большая часть вышеперечисленного может быть дополнительно объединена, если это имеет смысл в вашем хранилище, например: HEAD@{2}~3
, somebranch^2~4
, c00e66e~4^2
, anotherbranch~^~^~^
,
Таким образом, любое из описанного выше и его комбинации - это то, что подразумевается в документации как древовидная схема, которая является просто способом сказать, какое дерево (или ревизия) является тем, которое следует использовать для большинства команд git.
Больше информации в Revision Selection в Git book.
Вы, вероятно, хотите
git archive master foo | tar -x -C ~/destination
Выражение master/foo
не имеет смысла: master
это название филиала и foo
это имя каталога, как я полагаю.
Редактировать: (Удалена неработающая ссылка. См. Комментарии.)
Для определения <tree-ish>
а также <commit-ish>
см. справочную страницу git(1). Вам придется искать условия. В общем <tree-ish>
означает ссылку на объект дерева git, но если вы передадите тип объекта, который ссылается на дерево (например, коммит или ветвь), git автоматически использует ссылочное дерево.
Из Глоссария Git tree-ish - это "объект дерева или объект, который может быть рекурсивно разыменован на объект дерева".commit, HEAD и tag - это примеры древовидных объектов.
Я новичок в управлении исходным кодом и мерзавцем. Это то, что я знаю. Дерево - это структура файлов в хранилище. Это похоже на каталог в файловой системе. Смотрите - Какой инструмент git сгенерировал это древовидное представление?
Tree-ish означает как дерево. Он ссылается на часть или коммит дерева. Вы можете ссылаться на коммит, используя любой из них: полный или часть SHA-1 хэша коммита, указатель HEAD, ссылку на ветвь, ссылку на тэг. Другой метод использует любой из упомянутых методов вместе с предками или родителями коммита. Пример предков: