2009-01-20 54 views
28

我添加了一個文件索引與找到的文件名:的Git從SHA1

git add somefile.txt 

然後我得到了這個文件與SHA1:

git hash-object somefile.txt 

我現在有一個SHA1和我想用SHA1檢索索引中對象的文件名。

git show 5a5bf28dcd7944991944cc5076c7525439830122 

此命令返回文件內容,但不返回文件的名稱。

如何從SHA1獲取完整的文件名和路徑?

+0

[相關問題](http://stackoverflow.com/questions/223678/which-commit-has-this-blob) – Albert 2014-04-05 12:26:24

回答

23

在git中沒有這樣的直接映射,因爲文件的名稱是包含該文件的樹對象的一部分,而不是該文件內容的blob對象的一部分。

想要從SHA1哈希中檢索文件名不是一種常用操作,因此您可能需要擴展真實世界的用例嗎?

如果您正在查看當前文件(即HEAD提交),則可以嘗試以下操作。

git ls-tree -r HEAD | grep <SHA1> 

如果你想在之前的提交中找到內容,你需要做更多的事情。

git rev-list <commit-list> | \ 
xargs -n1 -iX sh -c "git ls-tree -r X | grep <SHA1> && echo X" 
+0

謝謝你。我不知道你可以這樣做 – Jonathan 2009-01-20 09:01:02

1

提交該文件並記下提交對象的sha1哈希值。之後使用

git ls-tree <commit-sha1> 

並且您將得到與散列文件的名稱。

查看手冊頁以獲取更多選項。

+0

這是提交的SHA時,OP詢問文件的SHA。 – 2015-04-03 12:09:48

7

下面的腳本在很大程度上基於Which commit has this blob?和亞里士多德Pagaltzis提供了答案。

#!/bin/sh 

obj_hash=$1 

# go over all trees 
git log --pretty=format:'%T %h %s' \ 
| while read tree commit subject ; do 
    git ls-tree -r $tree | grep "$obj_hash" \ 
    | while read a b hash filename ; do 
     if [ "$hash" == "$obj_hash" ]; then 
      f=$filename 
      echo $f 
      break 
     fi 
     if $f ; then break; fi 
     done 
     if $f; then break; fi 
done 

我確定有人可以美化這個腳本,但它確實有效。 這個想法是查看所有提交的樹並搜索您的特定哈希。

2

git rev-list <commit-list>將不包括被例如通過rebase -i刪除,現在只能通過引用日誌引用,所以如果BLOB沒有被命令發現任何承諾上面,你也應該引用日誌即檢查這樣的:

git reflog --all | \ 
cut -d\ -f1 | \ 
xargs -n1 -iX sh -c "git ls-tree -r X | grep <BLOB_SHA> && echo X" 
20

大的一行做到這一點:

git rev-list --objects --all | grep <blob sha1>