Git
Внутренности
Поиск…
Repo
git repository
представляет собой структуру данных на диске, в которой хранятся метаданные для набора файлов и каталогов.
Он живет в папке .git/
project вашего проекта. Каждый раз, когда вы передаете данные git, он хранится здесь. И наоборот, .git/
содержит все отдельные фиксации.
Это базовая структура:
.git/
objects/
refs/
Объекты
git
в основном является хранилищем ключей. Когда вы добавляете данные в git
, он создает object
и использует хэш SHA-1 содержимого object
в качестве ключа.
Поэтому любой контент в git
может быть просмотрен с помощью хэша:
git cat-file -p 4bb6f98
Существует 4 типа Object
:
-
blob
-
tree
-
commit
-
tag
HEAD ref
HEAD
- специальная ref
. Он всегда указывает на текущий объект.
Вы можете видеть, где он сейчас указывает, проверяя файл .git/HEAD
.
Обычно HEAD
указывает на другой ref
:
$cat .git/HEAD
ref: refs/heads/mainline
Но он также может указывать прямо на object
:
$ cat .git/HEAD
4bb6f98a223abc9345a0cef9200562333
Это то, что известно как «отсоединенная голова» - потому что HEAD
не привязан к (указывает на) какой-либо ref
, а скорее указывает непосредственно на object
.
Refs
ref
является по существу указателем. Это имя указывает на object
. Например,
"master" --> 1a410e...
Они хранятся в файлах .git / refs / heads / в текстовых файлах.
$ cat .git/refs/heads/mainline
4bb6f98a223abc9345a0cef9200562333
Обычно это называется branches
. Тем не менее, вы заметите, что в git
нет такой вещи, как branch
- только ref
.
Теперь можно ориентироваться в git
исключительно, перепрыгивая на разные objects
непосредственно своими хэшами. Но это было бы ужасно неудобно. ref
дает вам удобное имя для ссылки на objects
. Гораздо проще попросить git
перейти к определенному месту по имени, а не к хэшу.
Объект фиксации
commit
, вероятно, object
типа наиболее знакомый git
пользователей, так как это то , что они используются для создания с git commit
команд.
Однако commit
не содержит непосредственно никаких измененных файлов или данных. Скорее, он содержит в основном метаданные и указатели на другие objects
которые содержат фактическое содержимое commit
.
commit
содержит несколько вещей:
- хэш
tree
- хэш родительской
commit
- имя автора / адрес электронной почты, commiter name / email
- сообщение фиксации
Вы можете увидеть содержимое любого фиксации следующим образом:
$ git cat-file commit 5bac93
tree 04d1daef...
parent b7850ef5...
author Geddy Lee <[email protected]>
commiter Neil Peart <[email protected]>
First commit!
дерево
Очень важно отметить, что tree
объекты хранят в вашем проекте КАЖДЫЙ файл, и он хранит целые файлы, которые не отличаются друг от друга. Это означает, что каждая commit
содержит моментальный снимок всего проекта *.
* Технически сохраняются только измененные файлы. Но это более подробная информация об эффективности. С точки зрения дизайна, commit
должна рассматриваться как содержащая полную копию проекта .
родитель
parent
строка содержит хэш другого объекта commit
и может считаться «родительским указателем», который указывает на «предыдущий фиксатор». Это неявно образует граф коммитов, известный как граф фиксации . В частности, это ориентированный ациклический граф (или DAG).
Объект дерева
tree
основном представляет собой папку в традиционной файловой системе: вложенные контейнеры для файлов или других папок.
tree
содержит:
- 0 или более объектов
blob
- 0 или более объектов
tree
Так же, как вы можете использовать ls
или dir
для отображения содержимого папки, вы можете перечислить содержимое tree
объекта.
$ git cat-file -p 07b1a631
100644 blob b91bba1b .gitignore
100644 blob cc0956f1 Makefile
040000 tree 92e1ca7e src
...
Вы можете искать файлы в commit
, сначала обнаруживая хэш tree
в commit
, а затем глядя на это tree
:
$ git cat-file commit 4bb6f93a
tree 07b1a631
parent ...
author ...
commiter ...
$ git cat-file -p 07b1a631
100644 blob b91bba1b .gitignore
100644 blob cc0956f1 Makefile
040000 tree 92e1ca7e src
...
Объект Blob
blob
содержит произвольное содержимое двоичного файла. Как правило, это будет сырой текст, такой как исходный код или статья в блоге. Но так же легко могли быть байты PNG-файла или чего-то еще.
Если у вас есть хеш blob
, вы можете посмотреть его содержимое.
$ git cat-file -p d429810
package com.example.project
class Foo {
...
}
...
Например, вы можете просматривать tree
как указано выше, а затем посмотреть на один из blobs
в нем.
$ git cat-file -p 07b1a631
100644 blob b91bba1b .gitignore
100644 blob cc0956f1 Makefile
040000 tree 92e1ca7e src
100644 blob cae391ff Readme.txt
$ git cat-file -p cae391ff
Welcome to my project! This is the readmefile
...
Создание новых коммитов
Команда git commit
выполняет несколько действий:
- Создавайте
blobs
иtrees
чтобы представлять каталог проекта - хранится в.git/objects
- Создает новый объект
commit
с информацией об авторе, сообщением фиксации и корневымtree
с шага 1 - также сохраняется в.git/objects
- Обновляет
HEAD
ref в.git/HEAD
для хеша вновь созданногоcommit
Это приведет к добавлению нового снимка вашего проекта в git
который связан с предыдущим состоянием.
Перемещение HEAD
Когда вы запускаете git checkout
при фиксации (заданной хешем или ref), вы говорите git
чтобы сделать ваш рабочий каталог похожим на то, как это было сделано при создании моментального снимка.
- Обновите файлы в рабочем каталоге, чтобы они соответствовали
tree
внутриcommit
- Обновить
HEAD
чтобы указать на указанный хэш или ref
Перемещение ссылок
Запуск git reset --hard
перемещает refs в указанный хеш / ref.
Перемещение MyBranch
на b8dc53
:
$ git checkout MyBranch # moves HEAD to MyBranch
$ git reset --hard b8dc53 # makes MyBranch point to b8dc53
Создание новых Refs
Запуск git checkout -b <refname>
создаст новый ref, который указывает на текущую commit
.
$ cat .git/head
1f324a
$ git checkout -b TestBranch
$ cat .git/refs/heads/TestBranch
1f324a