0

During git bisect I want to take a specific action if the commit being bisected is the member of a set of commits of interest. Specifically, consider this situation:

----------C-------- A
      \---B---/

B and C are both reachable from A but not from each other. During bisect I want to apply a patch to commits from which B is reachable because B introduced an unrelated bug and I want to filter out that noise. The patch should not be applied when examining C.

What's the best way, in general, to test if a commit C is in the set of commits from which B is reachable starting from commit A? Ideally it would be be an expression I can pass to git rev-list but I suspect it will require more than that.

David Greene
  • 394
  • 2
  • 12

1 Answers1

0

To test whether commit $QA (questionable ancestor) is in fact an ancestor of commit $PC (possible child):

git merge-base --is-ancester $QA $PC

The exit-code result of running this command is 0 (true) if $QA is in fact an ancestor of $PC, and nonzero (false) if $QA is not an ancestor of $PC. (If the two commits are the same, the exit-code is 0: a commit is considered its own ancestor. To separate out this case, simply resolve the two commit identifiers to hashes and test whether the hashes are equal. If the identifiers are already hashes, just use if [ $QA = $PC ] or similar, otherwise use git rev-parse to do the translation to hashes.)

During git bisect, the $PC commit to test is just HEAD, and you'll have to do two tests (against both B and C).

torek
  • 448,244
  • 59
  • 642
  • 775
  • Yes, I know how to test for ancestry. I'm looking for a way for a user to specify a set of commit and determine whether a given commit is in the set. In this example, I'd like to specify the set of commits reachable from A that are also ancestors of B. I was hoping rev-list would support such a thing so I wouldn't have to invent my own language for specifying sets of commits. – David Greene Aug 18 '16 at 20:22
  • Also, rev-list's --not is tricky because it's not a true set inverse. So if rev-list supports the set specifications I need, then I think I would have to grep its output for the commit being checked. Unless there is some rev-list trick of which I'm unaware. – David Greene Aug 18 '16 at 20:23
  • The full general case is hard, but if you want `git rev-list` to spit out commit IDs *x* where B < *x* <= A, that one is covered: `git rev-list --ancestry-path B..A`. (Here `<` stands in for subset, ⊂ if it comes out OK in your font.) But normally you don't have to do this during a bisect, normally you'd just dynamically test each commit as you go. – torek Aug 18 '16 at 20:54
  • Ah, I didn't know about --ancestry-path. Thank you! – David Greene Aug 19 '16 at 04:38