0

I have two git commits c1 and cn. In my case cn is the tip of my current branch. c1 is a great-great-ancestor of cn. Roughtly 20 commits are between them. My file test.py got corrupted somewhere on the way. Is there a way to figure out at which commit it got corrupted?

When I type

git diff c1 cn test.py

I do get all the differences between the two commits and indeed i see that it got changed to the worse. However, it doesnt tell me where it got changed! I would like to find the particular commit where i made the fatal change.

Edit: What I am really looking for is a verbose git diff. I can see what made the test.py buggy, but I want to know which commit was responsible for it. So a git diff with a verbose option would be great. One that adds the id and the message and the branch of the diffs.

Marlo
  • 207
  • 1
  • 4
  • 12
  • 4
    Have you tried `git bisect`? – jonrsharpe Jul 29 '20 at 16:31
  • 2
    Consider also `git log -S` and `git log -G`. If the mistake is easily grep-able, these two commands will be the fastest way to find which commit had the error. – torek Jul 29 '20 at 16:37
  • 2
    ... _and_ `git blame` – eftshift0 Jul 29 '20 at 16:38
  • When you say corrupted, do you mean the test is broken, or the file itself was corrupted and cannot be read? – Daly Jul 29 '20 at 16:57
  • Thanks for the quick replies. @jonrsharpe: it worked! I narrowed it down with git bisect. Thanks. If you like you can write an answer and I would accept it. Also thanks to at torek and at eftshift and at Daly! I havent tried those yet. – Marlo Jul 29 '20 at 17:28
  • In that case it's a dupe of e.g. https://stackoverflow.com/questions/10043816/find-commit-that-broke-a-test-without-running-every-test-on-every-commit – jonrsharpe Jul 29 '20 at 17:32
  • i guess its similar. But what i was really looking for is a verbose git diff – Marlo Jul 29 '20 at 18:02
  • Maybe I'm mis-reading the question, but it certainly seems that `git log test.py` tells you what you want. – William Pursell Jul 29 '20 at 21:37

1 Answers1

1

You should use git bisect for this. To find the issue:

  1. git checkout [cn]
  2. git bisect start
  3. git bisect bad
  4. git bisect good [c1]

Replace [cn] and [c1] with the respective commit SHA. This tells Git that cn is broken and c1 is not broken. Git will do a binary search for the broken commit. It checks out the commit in the middle of c1 and cn (roughly 10 commits away from each). Determine if this version is broken. If it is broken, run git bisect bad. If it is not broken, run git bisect good. Now Git will checkout another commit. Repeat until Git tells you the SHA and commit message of the broken commit.

Kevin Goslar
  • 357
  • 3
  • 8