2009-01-20 12 views
28

ich eine Datei in den Index aufgenommen:Git - Suche nach einem Dateinamen von einer SHA1

git add somefile.txt 

Ich habe dann die SHA1 für diese Datei mit:

git hash-object somefile.txt 

Ich habe jetzt einen SHA1 und Ich möchte den Dateinamen des Objekts im Index mit dem SHA1 abrufen.

git show 5a5bf28dcd7944991944cc5076c7525439830122 

Dieser Befehl gibt den Dateiinhalt, aber nicht den Namen der Datei zurück.

Wie bekomme ich den vollständigen Dateinamen und Pfad zurück von der SHA1?

+0

[Verwandte Frage] (http://stackoverflow.com/questions/223678/which-commit-has-this-blob) – Albert

Antwort

23

Es gibt keine solche direkte Zuordnung in git, da der Name der Datei Teil des Baumobjekts ist, das die Datei enthält, nicht des Blob-Objekts, das den Inhalt der Datei darstellt.

Es ist keine übliche Operation, einen Dateinamen von einem SHA1-Hash abrufen zu wollen, also könnten Sie vielleicht einen realen Anwendungsfall dafür erweitern?

Wenn Sie sich aktuelle Dateien ansehen (z. B. HEAD commit), können Sie Folgendes versuchen.

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

Wenn Sie den Inhalt in früheren Commits finden möchten, müssen Sie etwas mehr wie folgt tun.

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

Danke dafür. Ich wusste nicht, dass Sie das tun könnten. – Jonathan

+5

Wenn Sie nicht wissen, was Sie für '' eingeben sollen, '--all' sucht über alle Zweige im Repository. – EoghanM

+1

Meine Version von 'git ls-tree' akzeptiert nur 1 Revision als Argument (git v1.7.4.4).Ich habe sie an 'for rev in $ angepasst (git rev-list --all); do git ls-tree -r $ rev | grep $ SHA; fertig uniq' –

1

Übergeben Sie die Datei und notieren Sie den sha1-Hash des Commit-Objekts. Danach

git ls-tree <commit-sha1> 

und Sie werden die Namen der Dateien mit den Hashes erhalten.

Überprüfen Sie die Handbuchseiten für weitere Optionen.

+0

dass die SHA commit ist, das OP fragt nach dem SHA der Datei. –

7

Das folgende Shell-Skript wird auf Which commit has this blob? und die Antwort von Aristoteles Pagaltzis bereitgestellt stark basiert.

#!/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 

Ich bin sicher, jemand könnte dieses Skript verschönern, aber es funktioniert. Die Idee ist, alle Bäume zu betrachten und nach Ihrem spezifischen Hash zu suchen.

2

git rev-list <commit-list> werden keine Commits umfassen, die durch rebase -i und nun entfernt zum Beispiel waren nur durch reflog referenziert werden, so dass, wenn Blob durch Befehl nicht über Sie auch reflog also wie folgt überprüfen sollten, gefunden wird:

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

Große Einzeiler, dies zu tun:

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