4

でファイルをチェックアウトし、git checkout $commit $filename忘れ$commitたがまだ覚えている$filename場合、どうすれば何$commitであったかを知ることができますか?

4

7 に答える 7

2

まず、非 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

もっとエレガントな方法があっても驚かないでしょうが、これは同様の状況で数回うまくいきました。

編集:同じ問題のより技術的なバージョンがここに表示されます:どのコミットにこのブロブがありますか?

于 2011-08-05T16:45:42.053 に答える
1

私はあなたができるとは思わない。Gitは、そのバージョンのファイルをインデックスと作業ディレクトリにロードするだけです。ロードしたバージョンを追跡する参照はありません

これが頻繁に行うことである場合は、git diff --cachedそのファイルを変更したすべてのコミットを使用して実行できるスクリプトを作成し、進行させることができます。

于 2011-08-05T14:08:31.333 に答える
0

シンプルでエレガント:

$ git log -S"$(cat /path/to/file)"

コンテンツが一意である場合にのみ機能します。これは、以前のハッシュ比較の回答でも同じです。

また、すべてではなく、一致する最初のバージョンのみが表示されます。

于 2011-10-06T16:22:48.070 に答える
0

運が良ければ、git 以外の方法を試すことができます。

history | grep "git checkout.*filename"
于 2011-08-05T14:24:57.773 に答える
0

これを試してください(テストされていません;):

$ for commit in $(git log --format=%h $filename); do
>  if diff <(git show $commit:$filename) $filename >/dev/null; then
>    echo $commit
>  fi
> done 
于 2011-08-05T14:26:31.050 に答える
0

同様の質問への回答として私が磨き上げたスクリプトの詳細を次に示します。ここで実際の動作を確認できます。

git-ls-dir 実行のスクリーンショット
(出典: adamspiers.org )

于 2012-01-08T02:07:17.867 に答える
0

使用できます

git log <filename>

チェックアウトするコミットを見つける

于 2011-08-05T13:58:41.830 に答える