Когда я запускаю git show [commit hash]
- какие два файла использует git для создания патча?
Файлы, указанные в строке index
:
index 54fc0544b..b7ce493a5 100644
Хеш-идентификатор слева от двух точек - это (сокращенно, в данном случае) хеш-идентификатор файла, сохраненного как объект BLOB-объекта 1 в родительском коммите, а хэш-идентификатор справа соответствует идентификатору файла, хранящегося в дочернем коммите. (См. Ниже более подробную графическую диаграмму.) Дочерний коммит - это тот, чей ID вы передали git show
; родитель - это его (одинокий) родительский коммит. Если существует несколько родительских коммитов, git show
по умолчанию создаст комбинированный diff , а в строке index
будет отображено несколько левых хеш-идентификаторов.
Используйте --full-index
, чтобы получить полный хэш-идентификатор каждого большого двоичного объекта. Обратите внимание, что идентификаторы хеша (в настоящее время) 40 шестнадцатеричных символов, т.е. из набора [0-9a-f]
. Это результат 160-битного криптографического хэша, примененного к префиксу заголовка, за которым следует содержимое файла. Следовательно, два битовых идентичных файла всегда дают один и тот же хэш-идентификатор, что позволяет Git легко пропустить различие между двумя одинаковыми файлами. Коммит, который повторно использует большинство файлов из своего родительского коммита, просто повторно использует все эти BLOB-объекты.
1 Поскольку blob изначально, на жаргоне базы данных, сокращенно от Binary Large OBject, эта пара слов передана вам Департаментом резервирования.
Изображение может быть более объяснительным. Представьте коммит как блок, содержащий список хеш-идентификаторов. Хеш-идентификаторы определяют, где на складе находятся файлы. Сам ящик также имеет свои собственные данные: ваше имя (и адрес электронной почты и т. Д.), Его родительский коммит и т. Д .; и ящик получает хэш-идентификатор, так что ящик можно найти на складе:
fe0a9eaf31dd0c349ae4308498c33a5c3794b293 (a commit)
+--------------------------------------------------+
| parent: 8b026edac3104ecc40a68fd58b764fb3c717babb |
| author: ... |
| more stuff: ... |
| contents: (long list of hash IDs) |
+--------------------------------------------------+
8b026edac3104ecc40a68fd58b764fb3c717babb (a commit)
+--------------------------------------------------+
| parent: ... |
| ... |
+--------------------------------------------------+
...
f17af66a97c8097ab91f074478c4a5cb90425725 (a blob)
+--------------------------------------------------+
| Git - fast, scalable, distributed revision contr |
| ol system\n===================================== |
| ...
:
В полях commit в конечном итоге (фактически через промежуточные блоки) содержатся имена файлов и идентификаторы хешей. В полях blob содержатся фактические данные файла, как в приведенном выше Git README.md
. Два разных коммита с разными метками идентификатора ящика могут содержать один и тот же файл 1044 *, просто перечисляя один и тот же хэш-идентификатор под одним и тем же именем файла. Если два разных коммита перечисляют различное содержимое файла, но под одним и тем же именем, git diff
будет (обычно) 2 сравнивать эти два файла и создавать инструкции по исправлению для изменения одного файла в другой.
2 Git обычно предполагает, что файл README.md
в коммите A
является "тем же файлом", что и README.md
в коммите B
. Если вы переименовываете файл, Git должен найти файл, который имеет достаточно похожее содержимое, чтобы идентифицировать это как операцию переименования. Вы также можете указать git diff
- break ассоциации файлов, если они кажутся "слишком измененными". Ничего из этого не нужно знать, чтобы использовать Git, по крайней мере, сначала.