でファイルをチェックアウトし、git checkout $commit $filename
忘れ$commit
たがまだ覚えている$filename
場合、どうすれば何$commit
であったかを知ることができますか?
7 に答える
まず、非 git の回答です。シェル コマンドの履歴を確認します。コマンド履歴のあるシェルを使用しなかった場合は、そうではありません...
gitの答え。通常、 $commitは見つかりません。一般に、同じ内容が多くのコミットの一部である可能性があり、git はチェックアウトした単一ファイルのログを保持していないと思います (HEAD の以前の値のログを保持します)。
ブルート フォース スクリプト git-find-by-contents を次に示します。$filename をパラメーターとして呼び出すと、このファイルが含まれていたすべてのコミットが表示されます。その名の通り内容で検索します。そのため、内容が一致する限り、任意の名前のファイルが検索されます。
#! /bin/sh
tmpdir=/tmp/$(basename $0)
mkdir $tmpdir 2>/dev/null
rm $tmpdir/* 2>/dev/null
hash=$(git hash-object $1)
echo "finding $hash"
allrevs=$(git rev-list --all)
# well, nearly all revs, we could still check the log if we have
# dangling commits and we could include the index to be perfect...
for rev in $allrevs
do
git ls-tree --full-tree -r $rev >$tmpdir/$rev
done
cd $tmpdir
grep $hash *
rm -r $tmpdir
もっとエレガントな方法があっても驚かないでしょうが、これは同様の状況で数回うまくいきました。
編集:同じ問題のより技術的なバージョンがここに表示されます:どのコミットにこのブロブがありますか?
私はあなたができるとは思わない。Gitは、そのバージョンのファイルをインデックスと作業ディレクトリにロードするだけです。ロードしたバージョンを追跡する参照はありません
これが頻繁に行うことである場合は、git diff --cached
そのファイルを変更したすべてのコミットを使用して実行できるスクリプトを作成し、進行させることができます。
シンプルでエレガント:
$ git log -S"$(cat /path/to/file)"
コンテンツが一意である場合にのみ機能します。これは、以前のハッシュ比較の回答でも同じです。
また、すべてではなく、一致する最初のバージョンのみが表示されます。
運が良ければ、git 以外の方法を試すことができます。
history | grep "git checkout.*filename"
これを試してください(テストされていません;):
$ for commit in $(git log --format=%h $filename); do
> if diff <(git show $commit:$filename) $filename >/dev/null; then
> echo $commit
> fi
> done
同様の質問への回答として私が磨き上げたスクリプトの詳細を次に示します。ここで実際の動作を確認できます。
(出典: adamspiers.org )
使用できます
git log <filename>
チェックアウトするコミットを見つける