你的问题掩盖了一个基本问题。让我们来看看一个典型的承诺图形片段:
...--E--F--G--H--I--J <-- master
你挑两次提交,如E
和I
,并运行git diff --name-only
(或git diff --name-status
)比较他们:
$ git diff --name-only <hash-E> <hash-I>
myfolder/a.txt
code/snippet.c
test.txt
但是然后说:
......结果是d是与对应的SHA引入的文件。
事实上,这些文件的名称问世意味着,所有这三个文件都存在于提交E
和/或I
,但如果你有承诺在您的工作树E
,想修改它得到承诺I
,这三个文件需要进行某种更改:创建,修改或甚至删除。使用--name-status
也会给你种类的变更:A
为“新建文件”,M
为“文件将被修改”,D
为“文件将被删除”。 (有,当然,大概几十成千上万的文件,在这两个E
和I
是相同,因此这里不打印。)
但现在你问的相应的散列结果,其中这种变化是介绍。有可能不存在散列。可能有多于一个。 (当然必须有至少)。例如,test.txt
可能被F
完全删除(而不是被更正),在H
中放回完整但是错误,然后在I
中更正。同时code/snippet.c
可能在G
和I
中被修改。
哪个提交哈希(es)你想每个文件? 的答案是决定如何找到它们。 (当然,如果只有一个这样的散列,问题就消失了。)
xxfelixxx's answer给出了一个(slighlty错误但容易修复和改进)的方法来获得一个提交 - 第一个git log
打印。要修复一个漏洞,提高它一下,更换do
序列有:
do echo -n "$file "; git rev-list <starthash>..<endhash> -- "$file" | head -1
也就是说,我们要找到git rev-list
打印提交哈希值之一,当只在指定的开始运行/停止点和寻找对一个文件的更改。我们需要<starthash>..<endhash>
来执行初始提交限制,并且-- $file
只选择添加,修改或删除该一个路径的提交。请注意,如果文件名中有空格,则需要引用它(所以我做过),但是然后读取git diff
的输出本身也变得棘手。
使用head -1
让你的最近提交感动的文件,例如,我们的例子code/snippet.c
两个G
和I
,你会得到提交I
哈希值。这是因为Git向后工作,从较新的提交到较旧的提交。如果你想第一个之一,使用tail -1
,如果你想要所有这些,你将需要一个fancier格式。 :-)
(还有一种微妙的区别就在这里,git log
和git rev-list
之间,涉及合并的提交,但可能不会影响到你。)