git diff --name-only和SHA

时间:2017-03-23 09:33:29

标签: git

我需要在两次提交之间运行git diff,结果应该是用相应的SHA引入的文件。

目前我可以这样做:

git diff --name-only [start-sha] [end-sha]

给出:

myfolder/a.txt
code/snippet.c
test.txt

但是如何在修改/添加每个文件时获取SHA,以便得到结果:

myfolder/a.txt     2314d344
code/snippet.c     gfhr76kl
test.txt           jk5534bf

图我可以这样做:

$files = git diff --name-only [start-sha] [end-sha]
foreach ($f in $files) {
     $sha = git log -n1 --format=format:%H $f
     print $f $sha
}

所以获取文件$ f被修改的最后一次提交/ SHA。

2 个答案:

答案 0 :(得分:1)

不确定是否有内部git命令来执行此操作,但您可以随时循环访问文件并获取第一次提交:

{{1}}

答案 1 :(得分:1)

你的问题掩盖了一个根本问题。我们来看一个典型的提交图片段:

...--E--F--G--H--I--J  <-- master

您选择了两个提交,例如EI,然后运行git diff --name-only(或git diff --name-status)进行比较:

$ git diff --name-only <hash-E> <hash-I>
myfolder/a.txt
code/snippet.c
test.txt

然后说:

  

...结果应该是使用 对应的SHA。

引入的文件

这些文件名出来意味着提交E和/或I中存在所有三个文件,但如果您在工作树中提交了E,想要修改它以获得提交I,这三个文件需要进行某种更改:创建,修改甚至删除。使用--name-status也会为您提供更改:A用于&#34;文件将是新创建的&#34;,M &#34;文件将被修改&#34;和D for&#34;文件将被删除&#34;。 (当然,EI中可能存在数十个或数千个相同的文件,因此不会在此处打印。)

但是现在你要求引入此更改的 对应的哈希值。可能没有 哈希。可能有多个。 (当然必须至少一个)。例如,test.txt可能会在F中被错误地删除(而不是被纠正),在H中放回完整但错误,然后在I中更正。同时,code/snippet.c G中可能会修改I

您希望为每个文件提供哪些提交哈希值? 的答案决定了如何找到它们。 (当然,如果只有一个这样的哈希,问题就会消失。)

xxfelixxx's answer给出一个(轻微的错误,但很容易修复和改进)方法来获得一个提交 - 第一个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和{{1} G你获得了提交I的哈希值。这是因为Git向后工作,从较新的提交到较旧的提交。如果您想要第一个,请使用I,如果您想要所有这些,则需要更高级的格式。 : - )

tail -1git log之间存在另一个微妙的区别,涉及合并提交,但这可能不会对您产生影响。)