views:

63

answers:

1

I'm trying to find the source of a bug that's come up since a commit in the past day on a long lived branch (which will be released much much later) called feature-x.

There's a bug though. I find behavior that I don't expect from my script which might have been introduced in any of the commit's up till now, specifically because features of master are used heavily in feature-x, but less so on Master itself.

To test this behavior, I have to run my script, dependent.pl. But when bisect jumps half way down the code, my script doesn't exist on Master and so it's impossible to test.

I believe this is because bisect pulls you out into a headless state, but in this case I really want to be in the context of this other history/changeset, and not floating in the ether.

Before anyone jumps to hit the you're doing it wrong buzzer, our team likes merging branches in these situations as the metaphor works well for this situation, not rebase-ing.

I'll demo this by creating a sample repo:

git init

echo 'sub f { print $_; }' > main.pl
git add .
git commit -a -m "inital commit"

git branch feature-x
git checkout feature-x
echo 'main::f(1)' > dependent.pl
git add .
git commit -a -m "Starting work on feature X"
git tag dev-1.0

git checkout master
echo "sub f { return 1; }" > main.pl
git commit -a -m "sub f { return 1; }"
echo "sub f { return 2; }" > main.pl
git commit -a -m "sub f { return 2; }"
echo "sub f { return 3; }" > main.pl
git commit -a -m "sub f { return 3; }"

git tag release-1.0

git checkout feature-x
git merge master

echo 'print main::f();' > dependent.pl
git commit -a -m "Updating call to f"

So now you get a repo that looks like this:

o Updating call to f ( Head of branch 'feature-x' )
o Merge branch master onto feature-x
|\
| o sub f { return 3; } (TAG release-1.0) ( Head of branch 'master' )
| o sub f { return 2; }
| o sub f { return 1; }
o | Starting work on feature X ( TAG 'dev-1.0' )
 \|
  o initial commit

So I run the command git bisect start feature-x dev-1.0 expecting I'll be able to find what broke my code in dependent.pl, I end up on commit 'sub f { return 2 }' without my history of changes from feature-x (i.e. If I run ls, all I see is main.pl and dependent.pl is missing).

This puts me in an untestable state. I cannot know if the current commit broke my work or not, nor can I say that commits on master broke it, so I can't say this commit is good or bad.

How can I test what broke my current branch?

Note: This was edited for clarity.

+6  A: 

The problem here is that git bisect is branch aware. When you tell it that "dependent" is good and "test" is bad, and one of the changes between there is a merge commit, it knows that in order to figure out where the problem was introduced, it's going to have to look at commits a, b, and c - otherwise, all it would be able to tell you is whether or not it's broken as of that merge commit.

It sounds like what you're expecting is to test the combination of commit b with the changes from the other branch, which is content which doesn't exist in any commit, and git bisect only lets you test commits! In order to test that content, you'd have to do a series of test merges - check out b, merge dependent, let you test, then check out a or c, merge dependent, let you test again. You can very easily do git merge --no-commit dependent once it's left you at commit b, then do git reset --hard when done with testing before running git bisect good/bad.

Otherwise, if I've misunderstood you expect it not to test any commits on the merged branch, and only test the merge commit itself (you don't care which of a, b, or c broke it), simply tell it that everything on the merged branch is good. Even better if you know that a, b, and c have nothing to do with it. Then you know without even testing that they're good!

But the one thing that you can't expect is for git to completely ignore commits a, b, and c. It has absolutely no way of knowing whether or not their changes are relevant to your "bug", and their changes are part of the difference between your good and bad commits.

Jefromi
Lets say a.txt has a function f that's called from dependent.txt, and had changes applied to it in commits a, b and c. How would you know that changes introduced in f didn't break dependent.txt?
The Daemons Advocate
Again, you're asking to test a set of content which does not exist in any commit - for example, the combination of the changes from b with the changes from dependent. To get that content in your working tree, the most general method would be to do a test merge as I described, then reset it away before proceeding.
Jefromi
@The Daemons Advocate I agree with Jefromi. It looks like you are using the test branch to add testing material to the tree, that's a bit unusual. If dependent.txt is used for testing, maybe it should be in the master branch. Another answer could be: merge more often to have better granularity.
gawi