Что означает древовидность в Git? - PullRequest
103 голосов
/ 28 октября 2010

Я очень озадачен тем, как использовать git archive.

У меня есть git-репозиторий с папкой Foo , Bar и Baz на верхнем уровне. Мне нужно экспортировать папку Foo в стиле SVN для быстрого развертывания тестов.

Я узнал, что могу использовать git-archive в виде экспорта SVN-ish .

Но вот в чем дело, Следующее прекрасно работает:

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

это приводит к Foo , Bar , Baz папок в папке destination .

Тем не менее, следующее сообщение об ошибке при 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 ]

145 голосов
/ 04 сентября 2013

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

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

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

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

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

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

Другое "Tree-ish" (Плюс коммит)

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

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

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

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

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

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

Figure 9-3 from Pro Git book

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

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

    tag -> commit

  • "Tree-ish" - это идентификаторы, которые в конечном итоге приводят к объектам дерева (т.е. каталога).

    tag -> commit -> project-root-directory

Потому что объекты коммитов всегда указывают на объект дерева каталогов (корень каталог вашего проекта), любой идентификатор, который является "commit-ish", является определение, также "дерево-иш". Другими словами, любой идентификатор, который приводит к объект commit также может быть использован для создания (под) дерева каталогов .

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

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

<tree>

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

<commit>

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

<tree-ish>

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

<commit-ish>

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

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

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

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

45 голосов
/ 07 декабря 2012

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

  • Ссылки, такие как:
    • ГОЛОВА
    • Метки
    • Названия филиалов
    • Имена веток с пультами, например origin/somebranch
  • Hash
  • Короткие хэши

Кроме того, к любому из вышеперечисленных можно добавить ^, ~. Ссылки могут также использовать обозначение @{} для некоторых дополнительных функций:

  • 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.

Подробнее в Выбор редакции в Git book .

11 голосов
/ 28 октября 2010

Возможно, вы хотите

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

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

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

5 голосов
/ 16 апреля 2013

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

...