Давайте сделаем все шаг за шагом.
Каждый раз, когда вы добавляете файл в свой репозиторий, обычно, добавляя его в индекс и затем фиксируя, добавляется снимок всего файла. Вычисляется хеш, и этот хеш является идентификатором этого файла.
Однако, если вы 5-6 коммитов в конце строки сможете восстановить содержимое файла до того, каким оно было ранее, его новый хеш уже будет существовать в хранилище, и, следовательно, дополнительный файл не будет добавлен. Вместо этого все, что будет ссылаться на этот файл, будет использовать хеш, но при этом ссылается на «старый» файл.
Объекты дерева - это просто текстовые файлы, которые содержат хэши файлов в каталоге, а также хэши, которые идентифицируют поддеревья (подпапки). Хеш объектов дерева также вычисляется из содержимого дерева и, таким образом, зависит от хэшей файлов и хешей поддеревьев.
Другими словами, в вышеописанном сценарии, в котором мы восстановили файл, если мы в конечном итоге восстановим содержимое всех файлов в хранилище обратно в состояние, которое они имели в предыдущем коммите, хеш нового дерева уже существует, и новый объект дерева не будет добавлен. Вместо этого, что бы ни ссылалось на это дерево, коммит, скорее всего, будет использовать хеш и ссылаться на «старое» дерево.
В большинстве случаев это, вероятно, немного теоретически. Вероятно, это не тот сценарий, с которым вы столкнетесь очень часто, когда вы в конечном итоге восстановите все файлы в более старое состояние. Так что на практике каждый раз, когда вы создаете коммит, вы, скорее всего, будете также создавать и добавлять один или несколько новых объектов дерева.
Чтобы добавить коммит без изменений файла, известный как «пустой коммит», вы можете использовать эту команду git:
git commit --allow-empty
Вы можете выбрать такие вещи, как -m "message"
или тому подобное, как обычно.
Вот пример:
λ git init .
Initialized empty Git repository in D:/Temp/.git/
λ echo a >test.txt
λ git add .
λ git commit -m test1
[master (root-commit) dc613fe] test1
1 file changed, 1 insertion(+)
create mode 100644 test.txt
λ git commit -m test2 --allow-empty
[master c197192] test2
λ git lg
* c197192: (7 seconds ago) test2 (HEAD -> master)
| Lasse Vågsæther Karlsen <lasse@vkarlsen.no> (Sat, 20 Apr 2019 23:28:44 +0200)
|
* dc613fe: (17 seconds ago) test1
Lasse Vågsæther Karlsen <lasse@vkarlsen.no> (Sat, 20 Apr 2019 23:28:34 +0200)
Теперь, если я выведу содержимое этих двух коммитов:
λ git cat-file -p c197192
tree 35b422a71005d59dd6af858a3425b608b63f7b5a
parent dc613fe57276009b399d8152a657cb971fad605a
author Lasse Vågsæther Karlsen <lasse@vkarlsen.no> 1555795724 +0200
committer Lasse Vågsæther Karlsen <lasse@vkarlsen.no> 1555795724 +0200
test2
λ git cat-file -p dc613fe
tree 35b422a71005d59dd6af858a3425b608b63f7b5a
author Lasse Vågsæther Karlsen <lasse@vkarlsen.no> 1555795714 +0200
committer Lasse Vågsæther Karlsen <lasse@vkarlsen.no> 1555795714 +0200
test1
Вы можете видеть, что они оба ссылаются на один и тот же объект дерева, который выглядит следующим образом:
λ git cat-file -p 35b422a71005d59dd6af858a3425b608b63f7b5a
100644 blob f5eea678d87a8664e4c76e12d3ef5c4ff775ad58 test.txt