GIT:获取通过提交添加到存储库的 blob 的所有 git 对象哈希
GIT: Get all git object hashes of blobs added to the repository by a commit
是否可以使用 git 命令行工具获取已通过给定提交哈希添加到存储库的所有 git blob 对象哈希的列表?
我已经尝试使用 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>
获取该分支上所有提交的列表(按提交顺序)。然后我想按此顺序访问每个提交,并收集每个提交在该分支上首先看到的 blob 哈希值。
最终结果应该如下所示:
C:368d64862e6aa2a0110f201c8a5193d929e2956d
B:03f15b592c7d776da37e3d4372c215b14ff8820f
B:4b7f9e6624a66fec0510d76823303017e224c9d7
B:c332b1e576af0dbb93cc875106bc06c3de6b74c8
C:5521a02ce1bc4f147d0fa39a178512476764dd66
B:e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e
B:adc83b19e793491b1c6ea0fd8b46cd9f32e592fc
C:a3db5c13ff90a36963278c6a39e4ee3c22e2a436
B:4888920a568af4ef2d2f4866e75b4061112a39ea
.
.
.
C:
提交
B:
斑点
如果这不容易做到,那么做两遍就可以了。由于您指出的原因,在第一遍中,可以在不同的提交中多次提及 blob:
- 在另一个文件中添加具有相同内容的文件
- 文件修改后内容相同
然后我可以通过 awk '!x[[=19=]]++'
进行第二次管道传输文件,这将删除所有重复项。这不是很有效,但会得到我想要的结果。
我希望我现在表达了我的意图。有什么想法吗?
Is it possible to get a list of all git object hashes of blobs which have been added to the repository by a given commit hash using the git command line tools?
是 and/or 否:您必须准确定义 添加到存储库 .
的意思
例如,假设我从一个完全空的存储库开始:
$ 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
是一个 blob,它的哈希 ID 是:
$ 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
这似乎是 一个已添加到存储库的 blob,但是等等,43b18ad
:
有一些非常熟悉的东西
$ git rev-parse HEAD:newfile.txt
43b18adf702be62761e3affd85c4c3ee5c396be7
是的,那是与README.md
相同的哈希ID:
$ git ls-tree -r HEAD
100644 blob 43b18adf702be62761e3affd85c4c3ee5c396be7 README.md
100644 blob 43b18adf702be62761e3affd85c4c3ee5c396be7 newfile.txt
它是一个 blob,但有两个文件。真的是新增的吗?
如果您对上述问题的回答是 "yes, it's new, even though it's old",那么第二个问题可能就得到了解答。如果您的答案是 "no, it's not new",重新引入在上一次提交中删除的 blob 的提交怎么样?或者,如果两个提交 I
和 J
在两个分支上并行进行:
I <-- br1
/
...--G--H
\
J <-- br2
两者都引入了相同的 blob,哪一个实际上将其添加为全新的,哪一个只是复制了另一个?
一般来说,如果你想要全新的,你必须遍历整个提交图,检查每个提交的树(参见git ls-tree -r
),并且select 提交首先引入一个 blob 对象 ID,该 ID 不存在于较早的(父级 and/or 日期和时间)提交对象中。如果您想要 "newly added as a new file in this commit",检查提交及其父项,可能使用 git diff-tree
或类似的。请注意,一个全新的 文件 在其父级中具有全零模式,并且状态字母为 A
(已添加),而从其父级修改的文件具有M
(已修改)的状态字母和两个非零散列。名义上删除的文件——存在于父文件中但不再存在于子文件中的文件——的状态字母为 D
(已删除)。如果启用重命名检测,您将获得 R
status-es 和相似性索引值;您可能想要禁用它,或者至少将相似性测试强制为 100%。
是否可以使用 git 命令行工具获取已通过给定提交哈希添加到存储库的所有 git blob 对象哈希的列表?
我已经尝试使用 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>
获取该分支上所有提交的列表(按提交顺序)。然后我想按此顺序访问每个提交,并收集每个提交在该分支上首先看到的 blob 哈希值。
最终结果应该如下所示:
C:368d64862e6aa2a0110f201c8a5193d929e2956d
B:03f15b592c7d776da37e3d4372c215b14ff8820f
B:4b7f9e6624a66fec0510d76823303017e224c9d7
B:c332b1e576af0dbb93cc875106bc06c3de6b74c8
C:5521a02ce1bc4f147d0fa39a178512476764dd66
B:e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e
B:adc83b19e793491b1c6ea0fd8b46cd9f32e592fc
C:a3db5c13ff90a36963278c6a39e4ee3c22e2a436
B:4888920a568af4ef2d2f4866e75b4061112a39ea
.
.
.
C:
提交
B:
斑点
如果这不容易做到,那么做两遍就可以了。由于您指出的原因,在第一遍中,可以在不同的提交中多次提及 blob:
- 在另一个文件中添加具有相同内容的文件
- 文件修改后内容相同
然后我可以通过 awk '!x[[=19=]]++'
进行第二次管道传输文件,这将删除所有重复项。这不是很有效,但会得到我想要的结果。
我希望我现在表达了我的意图。有什么想法吗?
Is it possible to get a list of all git object hashes of blobs which have been added to the repository by a given commit hash using the git command line tools?
是 and/or 否:您必须准确定义 添加到存储库 .
的意思例如,假设我从一个完全空的存储库开始:
$ 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
是一个 blob,它的哈希 ID 是:
$ 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
这似乎是 一个已添加到存储库的 blob,但是等等,43b18ad
:
$ git rev-parse HEAD:newfile.txt
43b18adf702be62761e3affd85c4c3ee5c396be7
是的,那是与README.md
相同的哈希ID:
$ git ls-tree -r HEAD
100644 blob 43b18adf702be62761e3affd85c4c3ee5c396be7 README.md
100644 blob 43b18adf702be62761e3affd85c4c3ee5c396be7 newfile.txt
它是一个 blob,但有两个文件。真的是新增的吗?
如果您对上述问题的回答是 "yes, it's new, even though it's old",那么第二个问题可能就得到了解答。如果您的答案是 "no, it's not new",重新引入在上一次提交中删除的 blob 的提交怎么样?或者,如果两个提交 I
和 J
在两个分支上并行进行:
I <-- br1
/
...--G--H
\
J <-- br2
两者都引入了相同的 blob,哪一个实际上将其添加为全新的,哪一个只是复制了另一个?
一般来说,如果你想要全新的,你必须遍历整个提交图,检查每个提交的树(参见git ls-tree -r
),并且select 提交首先引入一个 blob 对象 ID,该 ID 不存在于较早的(父级 and/or 日期和时间)提交对象中。如果您想要 "newly added as a new file in this commit",检查提交及其父项,可能使用 git diff-tree
或类似的。请注意,一个全新的 文件 在其父级中具有全零模式,并且状态字母为 A
(已添加),而从其父级修改的文件具有M
(已修改)的状态字母和两个非零散列。名义上删除的文件——存在于父文件中但不再存在于子文件中的文件——的状态字母为 D
(已删除)。如果启用重命名检测,您将获得 R
status-es 和相似性索引值;您可能想要禁用它,或者至少将相似性测试强制为 100%。