2011-06-17 18 views
35

誰かがMoodleのバージョン(私に知られていない)をとり、ディレクトリ内で多くの変更を適用し、それをリリースしました(tree here)。Git:ディレクトリに最も近いコミットを見つけるにはどうすればよいですか?

元のプロジェクトのどのコミットがこのツリーを形成する可能性が最も高いと判断できますか?

これにより、このパッチで適切なコミットでブランチを形成することができます。確かにそれは1.8または1.9のブランチから来ています。おそらくはリリースタグから来ていますが、特定のコミット間の違いはそれほど役に立ちません。

死後更新:knittl's answer私は近くに私を得るつもりです。最初に私のパッチリポジトリをリモートの "foreign"(共通のコミットなし、OK)として追加し、次にいくつかのオプションを使ってループ内でdiffを実行しました。通じ掘るためにコミットの数千人がありましたが、あることをthis one思わ

for REV in $(git rev-list v1.9.0^..v1.9.5); do 
    git diff -U0 "$REV" f7f7ad53c8839b8ea4e7 -- mod/assignment | wc -l >> ~/rdiffs2.txt; 
    echo "$REV" >> ~/rdiffs2.txt; 
done; 

for REV in $(git rev-list v1.9.0^..v1.9.5); do 
    git diff --shortstat "$REV" f7f7ad53c8839b8ea4e7 -- mod/assignment >> ~/rdiffs.txt; 
    echo "$REV" >> ~/rdiffs.txt; 
done; 

秒ちょうどなしのコンテキストでunified diff形式で行の変更をカウント:最初--shortstat形式が使用最も近いもの

+1

か前者の後で、 'git bisect 'を使ってソースコミットを素早く開始することができます。スキニーのために 'git bisect --help'をチェックしてください。 –

+0

これは今大変成功しています。 'cat rdiffs。txt | grep -oe '[0-9] * insertions' |ソート-n | head -n 10'(と同様のもの)を使用して手動検索を行うことなく変更の最小量を絞り込むことができます。 追加情報が見つかると便利です。 –

答えて

11

リポジトリのリビジョン範囲に対して指定されたツリーと異なるスクリプトを書くことができます。

for REV in $(git rev-list 1.8^..1.9); do 
    git diff --shortstat foreign/master $REV; 
done 
:各リビジョンのために私たちが照合したい(短い形式で)

git remote add foreign git://… 
git fetch foreign 

我々は、出力diffstat:

は、我々が最初に私たち自身のリポジトリに(歴史なし)変更されたツリーを取得すると仮定します

最小の変更量でコミットを探します(またはいくつかのソートメカニズムを使用してください)

+0

ありがとうございます。私は正確に何をしたかで質問を更新しました。 –

-2

「git blame」の使用はどうですか?各行ごとに、誰がそれを変更したか、そしてどのリビジョンで表示されますか?

+3

これは履歴付きのコミットでのみ動作します。これはここでの問題です。履歴と分岐点がありません – knittl

0

1.8のすべてのバージョンからパッチを作成するにはどのようにgitを使用するのですか?この新しいリリースに1.9を追加しました。 次に、どのパッチがより意味をなさないかを確認することができます。

たとえば、パッチで多くのメソッドが削除された場合、おそらくこのリリースではなく、前のリリースである可能性があります。パッチに単一の編集として意味を持たないセクションが多数ある場合は、このリリースではないでしょう。

など...実際には、残念ながら、これを完全に行うアルゴリズムはありません。私はヒューリスティックでなければなりません。

1

これが私の解決策だった:あなたは特定に適用することができますいくつかの有意義なテストがMoodleのレポのコミットを見つけることができ、初期にはMoodleの-ルーブリックのコミットした場合、後者は前に起こったかどうかを判断するために

#!/bin/sh 

start_date="2012-03-01" 
end_date="2012-06-01" 
needle_ref="aaa" 

echo "" > /tmp/script.out; 
shas=$(git log --oneline --all --after="$start_date" --until="$end_date" | cut -d' ' -f 1) 
for sha in $shas 
do 
    wc=$(git diff --name-only "$needle_ref" "$sha" | wc -l) 
    wc=$(printf %04d $wc); 
    echo "$wc $sha" >> /tmp/script.out 
done 
cat /tmp/script.out | grep -v ^$ | sort | head -5 
+0

私は、ブランチ(マスタ)を指定しなければならなかったのですが、それはneedle_refも検索してゼロ差分を検索したためです。 – Kyle

+1

@kyleに言及すると、このスクリプトは最後の行を除いて、最後の行を除いて良いです - 日付範囲に比較しているチェックイン(つまりneedle_ref)が含まれていれば0のファイルで勝ちます。最後の行を "cat /tmp/script.out | grep -v^$ | sort | head -5"に変更することをお勧めします。これにより、ファイルチェンジが最も少ない5つのチェックインが表示されます。 – thetoolman

+0

@thetoolmanが編集されました。 – mattalxndr

関連する問題