次のファイルをインデックスに追加しました。
git add somefile.txt
次に、このファイルのSHA1を次のように取得しました。
git hash-object somefile.txt
これでSHA1ができたので、SHA1を使用してインデックス内のオブジェクトのファイル名を取得したいと思います。
git show 5a5bf28dcd7944991944cc5076c7525439830122
このコマンドはファイルの内容を返しますが、ファイルの名前は返しません。
SHA1から完全なファイル名とパスを取得するにはどうすればよいですか?
ファイルの名前はファイルの内容であるblobオブジェクトではなく、ファイルを含むツリーオブジェクトの一部であるため、gitにはそのような直接マッピングはありません。
SHA1ハッシュからファイル名を取得するのは通常の操作ではないので、実際のユースケースを拡張できるでしょうか。
現在のファイル(つまり、HEAD commit)を確認している場合は、次のことを試すことができます。
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"
これを行うのに最適なワンライナー:
git rev-list --objects --all | grep <blob sha1>
次のシェルスクリプトは、 どのコミットにこのblobがありますか? とAristotlePagaltzisによって提供された回答に大きく基づいています。
#!/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
誰かがこのスクリプトを美化できると確信していますが、それは機能します。アイデアは、コミットされたすべてのツリーを調べて、特定のハッシュを検索することです。
git rev-list <commit-list>
には、たとえばrebase -i
によって削除され、reflogによってのみ参照されるコミットは含まれません。したがって、上記のコマンドでblobが見つからない場合は、reflogも確認する必要があります。
git reflog --all | \
cut -d\ -f1 | \
xargs -n1 -iX sh -c "git ls-tree -r X | grep <BLOB_SHA> && echo X"
ファイルをコミットし、コミットオブジェクトのsha1ハッシュをメモします。その後使用
git ls-tree <commit-sha1>
ハッシュ付きのファイルの名前を取得します。
その他のオプションについては、マニュアルページを確認してください。