Контекст Git Patch - PullRequest
       4

Контекст Git Patch

0 голосов
/ 24 апреля 2018

Если я наберу следующее

git show abckfirn49dj5ks94nsjy03hsev85esk9c32jt04

, где abckfirn49dj5ks94nsjy03hsev85esk9c32jt04 - хеш допустимого коммита, git покажет мне что-то вроде следующего

commit abckfirn49dj5ks94nsjy03hsev85esk9c32jt04
Author: Bob Jenkins <bjenkins@example.com>
Date:   Mon Apr 23 14:38:51 2018 -0700

    Commit message

diff --git a/somefile.txt b/agent/somefile.txt
index 54fc0544b..b7ce493a5 100644
--- a/somefile.txt
+++ b/somefile.txt
@@ -137,7 +137,6 @@ end:
 context
 context
+  an added line 
 context
 context
-  a deleted line

То есть - оно показываетхэш коммита, автор коммита, дата коммита, сообщение о коммите, и патч unix .

Я понимаю формат патча unix как описание различий междудва файла , представленные таким образом, что позволяет команде unix patch повторно применить эти различия

Когда я запускаю git show [commit hash] - какие два файла использует git для создания патча.Я достаточно уверен, что один - это файл с определенным хешем, но другой

  1. Файл с текущим заголовком?
  2. Файл, который непосредственно предшествует хешу притекущая ветка?
  3. что-то еще?

Ответы [ 3 ]

0 голосов
/ 24 апреля 2018

Когда я запускаю 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, по крайней мере, сначала.

0 голосов
/ 24 апреля 2018

Первый файл - это PFile (переменный термин, представляющий текущий файл в папке вашего проекта) перед тем коммитом. Второй файл - это файл PFile после применения этой фиксации.

Файл в текущем заголовке?

git log  <hash>...HEAD --stat <file>

Важны три точки, например:

git log  1c9fd7cb16df91a03dc43cea98ff05730ba51b5c...HEAD --stat gc/base/MemorySubSpace.cpp

Если он ничего не отображает, это означает, что файл представляет собой PFile (текущий заголовок), в противном случае он напечатает список коммитов, заменяющих Pfile.

Видя, как работает git (хэш идентичных файлов одинаков), второй файл не будет заменен во всех будущих коммитах, если PFile не будет изменен.

Для проверки замените <hash> на <hash>~1, и вы увидите свой текущий коммит в списке.

0 голосов
/ 24 апреля 2018

Каждый объект коммита ссылается на дерево (которое в конечном итоге сообщает ему, какая версия файла соответствует этому коммиту) и указатель на предыдущий объект коммита.

Хэш abckfirn49dj5ks94nsjy03hsev85esk9c32jt04 соответствует одному из этих коммитовобъекты, и этот объект будет иметь одно поле parent в своем заголовке, указывающее на предшественника.

Если вам интересно, как все это работает, я рекомендую эту страницу:

https://git -scm.com / book / ru / v2 / Git-Internals-Git-Objects

и, в частности, эта диаграмма:

https://git -scm.com / book / ru / v2 / images / data-model-3.png

(намеренно не содержит горячих ссылок)

РЕДАКТИРОВАТЬ: также книга сообщества git: http://shafiulazam.com/gitbook/1_the_git_object_model.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...