Что означает "древовидность" в Git?

122

Я очень не понимаю, как пользоваться 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, то что?

dkinzer
источник
2
master:fooдревовидный, но лучше использовать master fooкак i <tree-ish> <path>.
Якуб Наребски
1
Я истолковал <tree-ish> как прилагательное от [path]. Вот где я ошибся. И все примеры, которые я видел, использовали только часть команды <tree-ish>, поэтому я ошибочно предположил, что они использовали путь '<tree-ish>. Ох семантика :)
dkinzer
3
У меня проблема с этим вопросом, потому что заголовок спрашивает, какое дерево находится в git, но затем он запускается и, похоже, в основном связан с какой-то командой. Кроме того, принятый ответ, похоже, не отражает точного значения термина «древовидность». Либо название вопроса должно измениться, либо вопрос должен измениться. Я предлагаю, чтобы название было лучше адаптировано к тому, о чем действительно идет речь, и каков был принятый ответ. Или, возможно, изменить принятый ответ на то, что на самом деле представляет собой заголовок вопроса. Или ответ должен соответствовать названию вопроса.
Чарли Паркер
@CharlieParker, по-видимому, страницы git archiveруководства для команды больше не относятся к древовидному, но когда я задал этот вопрос, они сделали. И относительно принятого ответа; в то время никто не удосужился ответить на этот вопрос. Спустя более двух лет был даже опубликован другой ответ.
dkinzer

Ответы:

167

Краткий ответ (TL; DR)

«Древовидность» - это термин, относящийся к любому идентификатору (как определено в документации редакций Git ), который в конечном итоге ведет к (под) дереву каталогов (Git называет каталоги «деревьями» и «объектами дерева»).

В случае исходного плаката foo это каталог, который он хочет указать. Правильный способ указать (под) каталог в Git - использовать этот «древовидный» синтаксис (элемент № 15 из документации по редакциям Git ):

<rev>:<path>, Например HEAD:README, :README,master:./README

Суффикс, :за которым следует путь, называет большой двоичный объект или дерево по заданному пути в древовидном объекте, названном частью перед двоеточием.

Другими словами, master:fooэто правильный синтаксис, а не master/foo.

Другой "древовидный" (плюс коммит-иш)

Вот полный список идентификаторов фиксации и дерева (из документации по версиям 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 являются «фиктивными», потому что все они приводят к фиксации, но поскольку фиксации также указывают на деревья каталогов, все они в конечном итоге приводят к (под) объектам дерева каталогов и, следовательно, могут также использоваться как «дерево» -ish».

# 15 также может использоваться как древовидный, когда он относится к (под) каталогу, но его также можно использовать для идентификации определенных файлов. Когда он обращается к файлам, я не уверен, считается ли он по-прежнему «древовидным» или действует скорее как «блоб-иш» (Git называет файлы «блобами»).

Длинный ответ

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

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

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

Рисунок 9-3 из книги Pro Git

Многие команды Git могут принимать специальные идентификаторы для коммитов и (под) деревьев каталогов:

  • "Commit-ish" - это идентификаторы, которые в конечном итоге приводят к объекту фиксации. Например,

    tag -> commit

  • «Древовидный» - это идентификаторы, которые в конечном итоге приводят к объектам дерева (т. Е. Каталога).

    tag -> commit -> project-root-directory

Поскольку объекты фиксации всегда указывают на объект дерева каталогов (корневой каталог вашего проекта), любой идентификатор, который является «фиктивным», по определению также является «древовидным». Другими словами, любой идентификатор, ведущий к объекту фиксации, также может использоваться для перехода к объекту (под) дерева каталогов .

Но поскольку объекты дерева каталогов никогда не указывают на фиксации в системе управления версиями Git, не каждый идентификатор, указывающий на (под) дерево каталогов, также может быть использован для указания фиксации. Другими словами, набор идентификаторов типа "фиксация" является строгим подмножеством набора идентификаторов типа "дерево".

Как объясняется в документации ( спасибо Требору за помощь в его поиске ):

<tree>

Указывает имя объекта дерева.

<commit>

Указывает имя объекта фиксации.

<tree-ish>

Указывает имя объекта дерева, фиксации или тега. Команда, которая принимает <tree-ish> аргумент, в конечном итоге хочет работать с <tree>объектом, но автоматически разыменовывает <commit>и <tag>объекты, которые указывают на <tree>.

<commit-ish>

Указывает имя объекта фиксации или тега. Команда, которая принимает <commit-ish> аргумент, в конечном итоге хочет работать с <commit>объектом, но автоматически разыменовывает <tag>объекты, которые указывают на <commit>.

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

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

  2. Идентификаторы Sha1 объектов дерева каталогов .

Сообщество
источник
А как насчет записи 16 на вашем столе? Значит ли это, что вы не уверены, какое это дерево? 0 относится к состоянию слияния, и эта концепция применима только к BLOB-объектам, поскольку индекс даже не содержит каталогов. См. Stackoverflow.com/a/25806452/895245 . Итак, вопрос сводится к следующему: все ли кляксы также и деревья? Насколько я могу сказать , да: все страницы человека , которые используют <tree-ish>принимать как и man gitrevisionsопределяет: trees ("directories of files").
Чиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
Обратите внимание, что здесь git-archiveговорится, что требуется, <tree-ish>но не разрешается <sha1>. Поэтому я думаю, вместо этого следует запросить файл <tree-ish-ish>. stackoverflow.com/a/12073669/680464
juanitogan
Однако мне интересно, что происходит, когда я использую <rev>: (без пути ?. Он работает так, как пытался, но я не могу найти соответствующий раздел в документации.
Мартин Веймелка
49

Древовидный стиль - это способ наименования определенного дерева, которое может быть одним из следующих:

  • Ссылки вроде:
    • ГЛАВА
    • Теги
    • Названия филиалов
    • Имена веток с пультами, например 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отобразит справочный журнал, в котором вы можете увидеть все движения HEAD и правильно то, что @{1}и так будет разрешено.

Большинство из вышеперечисленного может быть дополнительно объединены до тех пор , как это имеет смысл в вашем хранилище, например: HEAD@{2}~3, somebranch^2~4, c00e66e~4^2, anotherbranch~^~^~^.

Таким образом, любое из описанных выше и их комбинаций - это то, что в документации понимается как древовидное, что является просто способом сказать, какое дерево (или ревизию) следует использовать для большинства команд git.

Подробнее см. В разделе «Выбор ревизии» книги Git .

LopSae
источник
1
Этот ответ объясняет исправления (фиксации) в целом и упускает из виду решающий случай:, master:path/to/directoryкоторый является древовидным, но не фиктивным. Cupcake's делает это яснее.
Чиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
11

Ты наверное хочешь

git archive master foo | tar -x -C ~/destination

Выражение master/fooне имеет смысла: masterэто имя ветки и foo, как я полагаю, имя каталога.

Изменить : (Удалена неработающая ссылка. См. Комментарии.)

Свен Марнах
источник
Слово «дерево» больше не встречается в вашей ссылке «Git Treeishes». К вашему сведению
Роберт
Treeish обычно относится к дереву ревизий, а не к структуре каталогов.
Jürgen Strobel
6
@ JürgenStrobel: Это неправда. Он не относится ни к одному из этих двух - в прошедшем времени, потому что этот термин больше не используется в текущей версии документации. (Вот почему ссылка не работает.) Раньше древовидное обозначение относилось к чему-то, что могло быть преобразовано в объект дерева в хранилище объектов git. Это включало любую спецификацию фиксации, поскольку каждая фиксация относится к одному объекту дерева. Объект дерева содержит информацию о дереве каталогов этого коммита - подробности см. В разделе об объектах git в «Pro Git» .
Sven Marnach
6

Определения <tree-ish>и <commit-ish>см. Справочную страницу git (1) . Вам придется искать условия. В общем случае <tree-ish>означает ссылку на объект дерева git, но если вы передаете тип объекта, который ссылается на дерево (например, фиксацию или ветвь), git автоматически будет использовать указанное дерево.

Trebor Rude
источник
И gitrevisions(7).
Xiong Chiamiov
0

Я новичок в системе управления версиями и git. Это то, что я знаю. Дерево - это структура файлов в репозитории. Он похож на каталог в файловой системе. См. - Какой инструмент git создал это древовидное представление?

«Дерево» означает «дерево». Он ссылается на часть или фиксацию дерева. Вы можете ссылаться на фиксацию, используя любой из них: полный или часть хэша SHA-1 фиксации, указатель HEAD, ссылку на ветвь, ссылку на тег. Другой метод использует любой из упомянутых методов вместе с предками или родителями коммита. Пример предков: введите описание изображения здесь

stack1
источник
0

Из Глоссария Git tree-ish - это «объект дерева или объект, который может быть рекурсивно разыменован на объект дерева». commit, HEAD и tag - это примеры древовидных объектов.

user2494386
источник