Git: How can I find a commit that most closely matches a directory?

Viewed 3630

Someone took a version (unknown to me) of Moodle, applied many changes within a directory, and released it (tree here).

How can I determine which commit of the original project was most likely edited to form this tree?

this would allow me to form a branch at the appropriate commit with this patch. Surely it came from either the 1.8 or 1.9 branches, probably from a release tag, but diffing between particular commits doesn't help me much.

Postmortem Update: knittl's answer got me as close as I'm going to get. I first added my patch repo as the remote "foreign" (no commits in common, that's OK), then did diffs in loops with a couple format options. The first used the --shortstat format:

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;

The second just counted the line changes in a unified diff with no context:

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;

There were thousands of commits to dig through, but this one seems to be the closest match.

5 Answers

Some really great solutions here!

I used something similar, to try and find the closet source file revision (given a target file):

  1. iterate backwards through all commits in the branch merge
  2. looking for the closest match with file target.txt
  3. print out the git revision, and the number of differing lines of text

N.B. perform inside a new, throw-away branch - reset --hard is destructive (afaik).

for REV in $(git rev-list merge); do
    git reset --hard "$REV"
    echo "$REV" `comm -2 -3 source.txt ../target.txt | wc -l`
done

You'll get output like the following, which tells you which revision was the closest match (i.e. least differing lines):

1c58bd5925a1fc8233730626**************** 771
HEAD is now at ...
9b2c29b00f1b4541a4135906**************** 775
HEAD is now at ...
b8e0bf5ec4372ebbcbd4edd0**************** 342
HEAD is now at ...
ba0d474bf2aac40dae48923e**************** 342
HEAD is now at ...
6d96921d3e9ad760ce55e76c**************** 335 <-- Closest match
HEAD is now at ...
795cd4caae5a5b08563443c9**************** 396
HEAD is now at ...
8743f42b24dd77e3bcc897dd**************** 399
HEAD is now at ...
d1b74dd33074c17da3fff638**************** 929

Further reading:

  • comm - for outputing differing lines
  • wc - for counting lines of text

Credit:

Related