我的要求,简述:
我有一个提交记录,例如 HEAD
或 111abc111
,我想要一种优雅的方式来打印所有已修改的文件和仅已修改的文件以及它们的 SHA-1 哈希值。我该怎么做?
下面是使用 git-cat-file
的一个思路,它几乎可以工作,但它要么列出所有文件(包括未更改的文件),要么必须在批处理模式下使用。最初在批处理模式下使用似乎很有前途,但我无法使其正常工作。请参见下面关于我尝试过的使用 git-ls-tree
等方法的内容。
关于我的优先事项,请参见本问题下面的说明,或查看我自己编写的答案(我不会接受它,但也许你可以重构它)。
具体示例:
设置示例:
为了背景,让我们看一下我的 Git 工作树的样子:
$ ls
alice.txt
bob.c
carol.h
main.c
$ git status -s
# Nothing prints, the working copy is clean and untouched.
我现在只需要更改两个文件:
$ echo "Add one line." >> bob.c
$ echo "Add one line." >> carol.h
$ git add . # Add (stage) both changed files.
$ git status -s
M bob.c
M carol.h
$ git commit -m "Two changed files."
[master 111abc111] Two changed files.
2 files changed, 2 insertions(+), 0 deletions(-)
这个功能基本上满足我的要求:
$ git cat-file -p 111abc111:./
100644 blob 99c2e88ad312f1eac63afc908f64c370fac9d947 .gitignore
100644 blob 607f8ea764981fb3f92a8d91abc2b154d99bc39c alice.txt
100755 blob 5a297bd6931c1a70abbcab919815324258c08b0f bob.c
100644 blob c6c2dfd18d26c1cf71b21e9d4c0892157dd6ec33 carol.h
100755 blob d0802cd238a3e83f186bc5c24be7e23dfc69205f main.c
上述命令的问题在于它列出了指定路径(
./
)下的所有文件,而不仅仅是修改过的文件。我只想显示bob.c
和carol.h
。第二个问题是使用
111abc111:./
指定树对象只会显示该目录中的文件(blobs),而不会显示子目录中的文件。子目录将以以下方式显示:040000 tree b98f38763b689e8197c6129726d41169fceeaaa0 subdir
可能的想法:
我刚刚删除了一些我尝试过的内容。
我怀疑关键在于使用git-diff
来制作一个“git对象”(包括blob)的列表,这些对象在指定的提交中发生了变化,然后以某种格式将该列表传递给git-cat-file
。因此,像这样的魔术命令可能会起作用:
$ git diff 111abc111^ 111abc111 --magic-options-go-here | git cat-file --batch-check='%(objectname) %(objectsize)'
关键是找到--magic-options-go-here
的值。我也不确定git-cat-file
是否是我想要的管道符号右侧的内容,我可能需要其他东西。
谢谢。
编辑:我的优先事项
我更感兴趣的是“Git对象”,即在Git中存储并由SHA-1哈希标识的实体,如树、块、提交,以及我没有考虑过的其他东西,如标签。我对文件名和如果您检出提交后实际看起来的方式不太感兴趣。
我想要查看SHA-1哈希,以便我可以看到“哦,这个合并提交指向不同分支中的那个树”。对于大型仓库中的分支、合并和变基,每个提交对象都包含大量未更改的树和块,它们只是指针(引用),而它们所引用的东西在概念上可能会非常远。当您仅更改一行代码时,进行git-commit,然后进行git-push,并推送50 MiB的数据时,这一点可能会变得明显。在内部,Git只需解引用大量指针并创建新的增量、packfiles等即可。在工作目录(文件系统)中感觉像小变化的事情,在Git仓库二进制格式中实际上可能代表大量数据。
git diff --raw
命令得到你需要的大部分内容吗? - Hasturkun