Что означает древовидность в 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 отслеживает исходный код, используя четыре основных объекта:

  1. Аннотированные теги, которые указывают на коммиты.
  2. Коммиты, которые указывают на корневое дерево каталогов вашего проекта.
  3. Деревья, которые являются каталогами и подкаталогами.
  4. BLOB-объекты, которые являются файлами.

Каждый из этих объектов имеет свой собственный идентификатор хэша sha1, поскольку Линус Торвальдс разработал Git как файлово-адресуемую файловую систему, то есть файлы могут быть получены на основе их содержимого (идентификаторы sha1 генерируются из содержимого файла). В книге Pro Git приведен пример диаграммы:

Рисунок 9-3 из книги 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>,

Набор идентификаторов дерева, который не может использоваться в качестве коммита

  1. <rev>:<path>, что приводит непосредственно к деревьям каталогов, а не к фиксации объектов. Например, HEAD:subdirectory,

  2. 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, ссылку на ветвь, ссылку на тэг. Другой метод использует любой из упомянутых методов вместе с предками или родителями коммита. Пример предков:

Другие вопросы по тегам