GIT: получить все хэши объектов git блобов, добавленных в репозиторий посредством фиксации
Можно ли с помощью инструментов командной строки git получить список всех хэшей блобов git, которые были добавлены в репозиторий заданным хешем фиксации?
Я уже пробовал заархивировать это с помощью сантехнического инструмента git git-diff-tree
. Может это неправильный подход. Ниже представлен лучший результат, который я мог получить до сих пор. Но документация (очень длинная справочная страница) не помогла выяснить, как именно нужно интерпретировать вывод.
$ git diff-tree --no-commit-id 2b53d04dbb7cd35d030ddc59b13c0836a87daeb7
:100644 100644 03f15b592c7d776da37e3d4372c215b14ff8820f 6e0ed0b1ed56e9a35a3be52a9de261c8ffcccae8 M file1.ts
:100644 100644 b5083bdb9c31005ebd16835a0f49dc848d3f387a 4b7f9e6624a66fec0510d76823303017e224c9d7 M file2.ts
:100644 100644 368d64862e6aa2a0110f201c8a5193d929e2956d 0e51626a9866a8a3896489f497fbd745a5f4a9f2 M file3.ts
:040000 040000 c332b1e576af0dbb93cc875106bc06c3de6b74c8 f7f3478a9b0eaac85719699d97e323563a1b102b M some_folder
Отображают ли первый и второй хэши больших двоичных объектов git соответственно старый и новый объекты для измененного файла? В худшем случае я мог бы получить эту информацию, проанализировав вывод.
Моей основной целью было найти командную строку, которая работает следующим образом:
$ git <command> <option1> <option2> 368d64862e6aa2a0110f201c8a5193d929e2956d
6e0ed0b1ed56e9a35a3be52a9de261c8ffcccae8
4b7f9e6624a66fec0510d76823303017e224c9d7
0e51626a9866a8a3896489f497fbd745a5f4a9f2
Измените ниже в ответ на @torek
В ответ на ответ @torek я хочу быть более ясным в своих намерениях, потому что он абсолютно прав, указывая на то, что новое не обязательно новое.
Я планирую использовать git rev-list --reverse <branch>
чтобы получить список всех коммитов в этой ветке в порядке фиксации. Затем я хочу посетить каждую фиксацию в этом порядке и собрать впервые увиденные хэши BLOB-объектов в этой ветке для каждой фиксации.
Конечный результат должен быть примерно таким:
C:368d64862e6aa2a0110f201c8a5193d929e2956d
B:03f15b592c7d776da37e3d4372c215b14ff8820f
B:4b7f9e6624a66fec0510d76823303017e224c9d7
B:c332b1e576af0dbb93cc875106bc06c3de6b74c8
C:5521a02ce1bc4f147d0fa39a178512476764dd66
B:e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e
B:adc83b19e793491b1c6ea0fd8b46cd9f32e592fc
C:a3db5c13ff90a36963278c6a39e4ee3c22e2a436
B:4888920a568af4ef2d2f4866e75b4061112a39ea
.
.
.
C:
совершитьB:
капля
Если это нелегко сделать, можно сделать два прохода. В первом проходе капли могут упоминаться несколько раз в разных коммитах по причинам, которые вы указали:
- добавление файла с таким же содержимым в другой файл
- файл имеет то же содержимое после того, как он был изменен
Затем я мог бы сделать второй проход, пропустив файл через awk '!x[$0]++'
который удалит любые дубликаты. Это было бы не очень эффективно, но дало бы желаемый результат.
Надеюсь, теперь я ясно изложил свои намерения. Какие-нибудь мысли?
1 ответ
Можно ли с помощью инструментов командной строки git получить список всех хэшей блобов git, которые были добавлены в репозиторий заданным хешем фиксации?
Да и / или нет: вы должны точно определить, что вы имеете в виду под добавлением в репозиторий.
Предположим, например, что я начинаю с полностью пустого репозитория:
$ mkdir foo && cd foo && git init
Initialized empty Git repository in ...
Сейчас я создаю README.md
а также git add
это и зафиксировать:
$ echo for testing > README.md
$ git add README.md
$ git commit -m initial
[master (root-commit) 19278e9] initial
1 file changed, 1 insertion(+)
create mode 100644 README.md
README.md
представляет собой большой двоичный объект и его хэш-идентификатор:
$ git rev-parse HEAD:README.md
43b18adf702be62761e3affd85c4c3ee5c396be7
Позже напишу новый файл:
$ echo for testing > newfile.txt
$ git add newfile.txt
$ git commit -m 'add new file'
[master 5521a02] add new file
1 file changed, 1 insertion(+)
create mode 100644 newfile.txt
Если мы посмотрим на этот коммит, мы увидим новый файл. Если мы посмотрим на это сgit show --raw
мы увидим это в git diff-tree
формат:
$ git show --raw
commit 5521a02ce1bc4f147d0fa39a178512476764dd66 (HEAD -> master)
Author: Chris Torek <chris.torek gmail.com>
Date: Fri Oct 18 14:10:55 2019 -0700
add new file
:000000 100644 0000000 43b18ad A newfile.txt
Это похоже на каплю, добавленную в репозиторий, но подождите, есть что-то ужасно знакомое43b18ad
:
$ git rev-parse HEAD:newfile.txt
43b18adf702be62761e3affd85c4c3ee5c396be7
Да, это тот же хэш-идентификатор, что иREADME.md
:
$ git ls-tree -r HEAD
100644 blob 43b18adf702be62761e3affd85c4c3ee5c396be7 README.md
100644 blob 43b18adf702be62761e3affd85c4c3ee5c396be7 newfile.txt
Это один blob, но два файла. Это действительно недавно добавлено?
Если ваш ответ на вышеизложенный - "да, он новый, хотя и старый", вы можете ответить на второй вопрос. Если ваш ответ "нет, это не ново", как насчет фиксации, которая повторно вводит blob-объект, который был удален в предыдущей фиксации? Или, если два коммитятI
а также J
производится параллельно на двух ветках:
I <-- br1
/
...--G--H
\
J <-- br2
оба представляют один и тот же blob, который фактически добавляет его как совершенно новый, а какой просто дублирует другой?
В общем, если вам нужно все новое, вам придется пройти весь граф коммитов, проверяя дерево каждого коммита (см.git ls-tree -r
), и выберите, какие коммиты будут первыми, введите идентификатор объекта большого двоичного объекта, которого еще нет в каком-либо более раннем (родительском и / или по дате и времени) объекте фиксации. Если вы хотите "только что добавлен в этот коммит как новый файл", проверьте фиксацию и ее родительские элементы, возможно, используяgit diff-tree
или похожие. Обратите внимание, что у полностью нового файла есть режим "все нули" в его родительском элементе и буква статусаA
(добавлено), в то время как файл, измененный из родительского, имеет статусную букву M
(изменено) и два ненулевых хэша. Номинально удаленный файл - файл, который существовал в родительском, но больше не существует в дочернем - имеет статусное письмоD
(удалено). Если вы включите обнаружение переименования, вы получитеR
значения статусов и индекса сходства; вы можете отключить это или, по крайней мере, установить 100% проверку на подобие.