[英]git diff --name-only and SHA
我需要在兩次提交之間運行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。
不知道是否有內部git命令可以執行此操作,但是您始終可以循環遍歷文件並獲取第一個提交:
for file in `git diff [start-sha] [end-sha] --name-only`;
do echo -n "$file "; git log --pretty=short [start-sha] [end-sha] -- $file | /bin/grep commit | cut -b8- | head -n 1;
done
您的問題掩蓋了一個基本問題。 讓我們看一個典型的提交圖片段:
...--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
但然后說:
...結果應該是與相應的SHA一起引入的文件。
這些文件名出來的事實意味着所有三個文件都存在於提交E
和/或I
,但是如果您在工作樹中擁有提交E
並想對其進行修改以得到提交I
,那么這三個文件將需要一些某種更改:創建,修改,甚至刪除。 使用--name-status
會給你怎樣的變化,以及: A
對“的文件將被新成立的”, M
為“該文件將被修改”,並D
為“該文件將被刪除” 。 (有,當然,可能在這兩個文件中的幾十個或上千E
和I
是相同 ,因此在這里沒有打印出來。)
但是現在,您需要在引入此更改的位置輸入相應的哈希值。 可能沒有一個哈希值。 可能不止一個 。 (當然必須至少有一個)。 例如, test.txt
可能會被錯誤地完全刪除(而不是被更正)在F
,然后將其原封不動地放回H
,然后在I
更正。 同時,可以在G
和 I
中都修改code/snippet.c
。
您希望每個文件使用哪個提交哈希? 這個問題的答案決定了如何去發現它們。 (當然,如果只有一個這樣的哈希,問題就消失了。)
xxfelixxx的答案給出了一種獲取錯誤(提交錯誤,但易於修復和改進)的方法-第一個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
可以獲取接觸文件的最新提交,例如,在我們的示例中, G
和I
中的code/snippet.c
都為提交I
了哈希值。 這是因為Git從新的提交到舊的提交都向后工作。 如果要使用第一個,請使用tail -1
,如果要全部使用,則需要更高級的格式。 :-)
(這里在git log
和git rev-list
之間還有另一個細微的差別,涉及合並提交,但這可能不會影響您。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.