the_endian
the_endian

Reputation: 2525

Which git commands can I use to find out which releases of a software are affected by a given bug?

I often need to navigate around a new git repo (one where I am not yet familiar with the codebase) and look into a bug in order to find out more info about the cause of the bug, and also which versions of the software are affected by the bug. Sometimes I do not have any initial commit information. E.G., I see a changelog which says "Fixed problem X in release Y". I then go clone the code and start looking for commit messages and code changes for clues. At some point, I'll find the commit that corresponds to the change.

Now, I need to answer the questions:

  1. "When was the original bug introduced?"
  2. "What is the last released version that does not have this bug?"

This means that I'm not just dealing with commits in a branch, but rather, across releases. I'm pretty new to git bisect and I've seen it used for a similar purpose between commits in a branch, but I'm not sure what's good to use across releases. Something that is rather useful is to see the state of any given file over time. For this, I've used gitk and git log [filename]. The toughest part for me is that most of the git tools are based off of commit hash and I need to map to release versions Which git commands would you use to accomplish this task?

Another way of looking at it would be - it would be useful if I could see e.g. the last 5 release states of a given part of a specific file side-by-side, so that I could see how the specific code area evolved between releases. Is there a way to do something like this?

Upvotes: 0

Views: 71

Answers (1)

bk2204
bk2204

Reputation: 76764

You can indeed use git bisect for this purpose; it will work fine across releases, and I've used it for that before. The general approach is this:

  1. Come up with a test case for the problem. Ideally this can be expressed as a shell script (e.g., ./script) that exits 0 if the commit is good and 1 if it fails (and if it cannot be tested, 125).
  2. Find a broken version, and call this commit BAD.
  3. Go back in the history, and guess a version that might not have had the bug. If it does, go back again; if it does not, then you're done, and call this commit GOOD. Note that it's fine to skip huge numbers of releases going back, because git bisect is O(log N).
  4. Run git bisect start BAD GOOD.
  5. If you were able to come up with a shell script, run git bisect run ./script; otherwise, test each individual item and use git bisect bad or git bisect good to test it (or git bisect skip if it cannot be tested).

That will result in a commit, call it RESULT. If you want to find the version that included it, run git describe --tags --contains RESULT, which will look at tags to show you the version which included it. If you want to find the last version that did not include it, run git describe --tags RESULT, which will show you the most recent version which didn't include it. Note that there will be additional data to specify your commit, but you can ignore that. For example, the version you're interested in here is v2.28.0: v2.28.0-310-gc4d891dc21.

In the next version of Git, there will be an option, --first-parent to track the first parent, which is helpful if you have a PR-based workflow where PRs have to pass tests but individual commits need not work.

If instead you want to know which commit fixed a commit, you can just reverse the sense of your shell script, swap the order of the arguments to git bisect start, and use git bisect good when the commit is broken and git bisect bad when the commit is good.

If it's really the case that you just want to look at the history of a given file, you can use git log -p REVISION -- FILENAME. There isn't a side-by-side view; that's something you'd need to do with an external tool of some sort. vimdiff can do this with two versions, but not with additional versions.

Upvotes: 3

Related Questions