GIT: Получить все хиты объектов git, добавленные в репозиторий с помощью коммита - PullRequest
1 голос
/ 19 октября 2019

Можно ли получить список всех хэтов больших объектов 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 blob старые и новые объекты длямодифицированный файл соответственно? В худшем случае я мог получить эту информацию, проанализировав вывод.

Моя основная цель состояла в том, чтобы найти командную строку, которая работает следующим образом:

$ git <command> <option1> <option2> 368d64862e6aa2a0110f201c8a5193d929e2956d 
6e0ed0b1ed56e9a35a3be52a9de261c8ffcccae8 
4b7f9e6624a66fec0510d76823303017e224c9d7 
0e51626a9866a8a3896489f497fbd745a5f4a9f2 

Редактироватьниже в ответ на @ torek

В ответ на ответ @torek я хочу быть более ясным относительно моих намерений, потому что он абсолютно прав, указывая, что новое не является необходимым новым.

Я планирую использовать git rev-list --reverse <branch>, чтобы получить список всех коммитов в этой ветке в порядке коммитов. Затем я хочу посещать каждый коммит в этом порядке и собирать в первую очередь хэши больших двоичных объектов в этой ветке для каждого коммита.

Конечный результат должен выглядеть примерно так:

C:368d64862e6aa2a0110f201c8a5193d929e2956d
B:03f15b592c7d776da37e3d4372c215b14ff8820f
B:4b7f9e6624a66fec0510d76823303017e224c9d7
B:c332b1e576af0dbb93cc875106bc06c3de6b74c8
C:5521a02ce1bc4f147d0fa39a178512476764dd66 
B:e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e
B:adc83b19e793491b1c6ea0fd8b46cd9f32e592fc
C:a3db5c13ff90a36963278c6a39e4ee3c22e2a436
B:4888920a568af4ef2d2f4866e75b4061112a39ea
.
.
.

C:commit B: blob

Если это нелегко сделать, было бы хорошо сделать два прохода. В первом проходе BLOB-объекты могут упоминаться несколько раз в разных коммитах по указанным вами причинам:

  • добавление файла с таким же содержимым в другой файл
  • файл имееттот же контент после того, как он был изменен

Затем я мог бы сделать второй проход, пропустив файл через awk '!x[$0]++', который удалит все дубликаты. Это было бы не очень эффективно, но дало бы желаемый результат.

Надеюсь, теперь я ясно дал понять свои намеренияЕсть мысли?

1 Ответ

1 голос
/ 19 октября 2019

Можно ли получить список всех хэтов больших объектов git, которые были добавлены в хранилище с помощью данного хэша коммита, с помощью инструментов командной строки git?

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

Предположим, например, что я начинаю с полностью пустого хранилища:

$ mkdir foo && cd foo && git init
Initialized empty Git repository in ...

Теперь я создаю README.md и git add it и фиксирую:

$ 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 является BLOB-объектом и его хэш-идентификатором:

$ 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-объект, который был удален в предыдущем коммите? Или, если два коммита I и J, выполненные параллельно на двух ветвях:

          I   <-- br1
         /
...--G--H
         \
          J   <-- br2

оба представляют один и тот же BLOB-объект , который фактически добавляет его как полностью новый,а какой просто дублирует другой?

В общем, если вы хотите все новые , вам придется пройти весь граф коммитов, осматривая дерево каждого коммита (см. git ls-tree -r)и выберите, какие коммиты сначала вводят идентификатор объекта BLOB-объекта, которого нет в каком-либо ранее (родительском и / или дато-и-временном) объекте фиксации. Если вы хотите «вновь добавить как новый файл в этот коммит», проверьте коммит и его родителей, возможно, используя git diff-tree или аналогичный. Обратите внимание, что совершенно новый файл имеет режим «все ноль» в своем родительском элементе и букву состояния A (добавлено), в то время как файл, измененный из его родительского элемента, имеет буквенное состояние M (модифицированный) и два ненулевых хэша. Номинально удаленный файл - файл, который существовал в родительском элементе, но больше не существует в дочернем, - имеет статусную букву D (удалено). Если вы включите обнаружение переименования, вы получите R значения статуса и индекса сходства;Вы можете отключить это или, по крайней мере, заставить тестирование сходства на 100%.

...