web-dev-qa-db-ja.com

Git-SHA1からファイル名を見つける

次のファイルをインデックスに追加しました。

git add somefile.txt

次に、このファイルのSHA1を次のように取得しました。

git hash-object somefile.txt

これでSHA1ができたので、SHA1を使用してインデックス内のオブジェクトのファイル名を取得したいと思います。

git show 5a5bf28dcd7944991944cc5076c7525439830122

このコマンドはファイルの内容を返しますが、ファイルの名前は返しません。

SHA1から完全なファイル名とパスを取得するにはどうすればよいですか?

38
git-noob

ファイルの名前はファイルの内容である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"
29
CB Bailey

これを行うのに最適なワンライナー:

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

次のシェルスクリプトは、 どのコミットにこの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

誰かがこのスクリプトを美化できると確信していますが、それは機能します。アイデアは、コミットされたすべてのツリーを調べて、特定のハッシュを検索することです。

7
nimrodm

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"
3
JaMa

ファイルをコミットし、コミットオブジェクトのsha1ハッシュをメモします。その後使用

git ls-tree <commit-sha1>

ハッシュ付きのファイルの名前を取得します。

その他のオプションについては、マニュアルページを確認してください。

0