threads / discuss / 63809

Possible git bisect behavior issue when skipping commits

Subject: Possible git bisect behavior issue when skipping commits

## tl;dr

4 messages between Jul 19, 2025 and Jul 21, 2025.

replies: 3people: 3as markdown or json

Begad Habib· Jul 19, 2025, 15:31 UTC · lore
Hi Git developers,
I've been analyzing the behavior of `git bisect` when dealing with
skipped commits and noticed what might be an unexpected result. I
wanted to share a minimal reproduction to understand whether this is
intended behavior.
--
## Environment
- Git version: 2.43.0
- OS: Ubuntu 22.04
---
Steps to Reproduce

```mkdir bisect-bug-test && cd bisect-bug-test git init

# Commit 1 – good echo "good" > file.txt git add file.txt git commit -m "Commit 1 - good"

# Commit 2 – skipped echo "middle" > file.txt git add file.txt git commit -m "Commit 2 - middle"

# Commit 3 – bad echo "bad" > file.txt git add file.txt git commit -m "Commit 3 - bad"

# Start bisect git bisect start git bisect bad git bisect good HEAD~2 git bisect skip HEAD~1

Observed Output

There are only 'skip'ped commits left to test. The first bad commit could be any of: <commit 1> <commit 2> We cannot bisect more!

This output is a bit confusing, since the bad commit was already identified (HEAD, i.e., Commit 3), and the middle one was explicitly skipped. Including the good commit (Commit 1) in the potential bad list could mislead users into thinking it might be faulty.

Question

Is this the expected behavior for skipped commits? Or could the output be more accurate by excluding commits already marked as good?

Thanks for your time and the amazing work you all do on Git 🙏 Best regards

Junio C Hamano· Jul 20, 2025, 01:12 UTC · re: Begad Habib · lore

Re: Possible git bisect behavior issue when skipping commits

Begad Habib <begadhabib989@gmail.com> writes:
Show 11 quoted lines
> Hi Git developers,
>
> I've been analyzing the behavior of `git bisect` when dealing with
> skipped commits and noticed what might be an unexpected result. I
> wanted to share a minimal reproduction to understand whether this is
> intended behavior.
> --
> ## Environment
> - Git version: 2.43.0
> - OS: Ubuntu 22.04
> ---
Thanks for a report.

CC'ing the primary author of "git bisect skip" and showing of skipped ones for their thoughts.

Show 47 quoted lines
> Steps to Reproduce
>
> ```mkdir bisect-bug-test && cd bisect-bug-test
> git init
>
> # Commit 1 – good
> echo "good" > file.txt
> git add file.txt
> git commit -m "Commit 1 - good"
>
> # Commit 2 – skipped
> echo "middle" > file.txt
> git add file.txt
> git commit -m "Commit 2 - middle"
>
> # Commit 3 – bad
> echo "bad" > file.txt
> git add file.txt
> git commit -m "Commit 3 - bad"
>
> # Start bisect
> git bisect start
> git bisect bad
> git bisect good HEAD~2
> git bisect skip HEAD~1
>
>
> Observed Output
>
> There are only 'skip'ped commits left to test.
> The first bad commit could be any of:
> <commit 1>
> <commit 2>
> We cannot bisect more!
>
> This output is a bit confusing, since the bad commit was already
> identified (HEAD, i.e., Commit 3), and the middle one was explicitly
> skipped. Including the good commit (Commit 1) in the potential bad
> list could mislead users into thinking it might be faulty.
>
> Question
>
> Is this the expected behavior for skipped commits? Or could the output
> be more accurate by excluding commits already marked as good?
>
> Thanks for your time and the amazing work you all do on Git 🙏
> Best regards
Christian Couder· Jul 20, 2025, 08:34 UTC · re: Begad Habib · lore

Re: Possible git bisect behavior issue when skipping commits

Hi,
On Sat, Jul 19, 2025 at 5:32 PM Begad Habib <begadhabib989@gmail.com> wrote:
Show 37 quoted lines
>
> Hi Git developers,
>
> I've been analyzing the behavior of `git bisect` when dealing with
> skipped commits and noticed what might be an unexpected result. I
> wanted to share a minimal reproduction to understand whether this is
> intended behavior.
> --
> ## Environment
> - Git version: 2.43.0
> - OS: Ubuntu 22.04
> ---
>
> Steps to Reproduce
>
> ```mkdir bisect-bug-test && cd bisect-bug-test
> git init
>
> # Commit 1 – good
> echo "good" > file.txt
> git add file.txt
> git commit -m "Commit 1 - good"
>
> # Commit 2 – skipped
> echo "middle" > file.txt
> git add file.txt
> git commit -m "Commit 2 - middle"
>
> # Commit 3 – bad
> echo "bad" > file.txt
> git add file.txt
> git commit -m "Commit 3 - bad"
>
> # Start bisect
> git bisect start
> git bisect bad
> git bisect good HEAD~2

When both one "good" and one "bad" commits have been specified, then Git starts bisecting, which means that you should then see something like:

Bisecting: 0 revisions left to test after this (roughly 0 steps)
[df357f37981b7f1e804684cc09842d02fd012146] Commit 2 - middle

and Git should have checked out "Commit 2 - middle", so HEAD should point to that commit.

By the way it could help if you could show git's output when giving steps to reproduce like this.

> git bisect skip HEAD~1

This will "skip" the commit before the current one, so "Commit 1 - good", which is already marked as "good".

I guess this is not what you want. You wanted to skip "Commit 2 - middle", right? In this case `git bisect skip` (without any additional argument) to skip the current commit is enough.

> Observed Output

(Note that I see the output you show below only when "Commit 2 - middle" is skipped by the previous command above.)

> There are only 'skip'ped commits left to test.
> The first bad commit could be any of:
> <commit 1>
> <commit 2>

I am not sure if <commit 1> and <commit 2> here refer to "Commit 1 - good" and "Commit 2 - middle" respectively or not. To avoid confusion, you might want to be explicit about what they refer to.

Anyway when I try to reproduce, I see the hashes of "Commit 2 - middle" and "Commit 3 - bad" which is what I expected.

> We cannot bisect more!
>
> This output is a bit confusing, since the bad commit was already
> identified (HEAD, i.e., Commit 3),

Git's output talks about the "first bad commit" not the commit currently marked as "bad". "first bad commit" has a special meaning. It means the first commit in the commit history that would be "bad" if all the commits could be tested (and thus no commit was skipped).

> and the middle one was explicitly
> skipped.

Yeah, but that doesn't mean it couldn't be the "first bad commit". The git bisect documentation about "skip" says:

"However, if you skip a commit adjacent to the one you are looking for, Git will be unable to tell exactly which of those commits was the first bad one."

This is what happens here, and that should be expected. Git cannot tell between "Commit 2 - middle" and "Commit 3 - bad" which one would be the first bad one if all the commits could be tested.

> Including the good commit (Commit 1) in the potential bad
> list could mislead users into thinking it might be faulty.

That's not what I see. I don't see the hash of "Commit 1 - good" listed there when I try to reproduce. But again your reproduction steps have some issues, see above. So I am not sure I reproduced the issue you saw or not.

> Question
>
> Is this the expected behavior for skipped commits? Or could the output
> be more accurate by excluding commits already marked as good?

Commits already marked good should be excluded but maybe if you mark them as both "good" and "skip"ped there could be some issues. Anyway we would need better reproduction steps to be able to debug this. And yeah I also tried to mark both "Commit 1 - good" and "Commit 2 - middle" as "skip"ped, and `git bisect` still seems to work correctly to me, especially it still say that it cannot tell between "Commit 2 - middle" and "Commit 3 - bad" (without showing the hash of "Commit 1 - good").

>  Thanks for your time and the amazing work you all do on Git 🙏
Thanks for the kind words!
Junio C Hamano· Jul 21, 2025, 17:03 UTC · re: Christian Couder · lore

Re: Possible git bisect behavior issue when skipping commits

Christian Couder <christian.couder@gmail.com> writes:
Show 37 quoted lines
>> # Commit 1 – good
>> echo "good" > file.txt
>> git add file.txt
>> git commit -m "Commit 1 - good"
>>
>> # Commit 2 – skipped
>> echo "middle" > file.txt
>> git add file.txt
>> git commit -m "Commit 2 - middle"
>>
>> # Commit 3 – bad
>> echo "bad" > file.txt
>> git add file.txt
>> git commit -m "Commit 3 - bad"
>>
>> # Start bisect
>> git bisect start
>> git bisect bad
>> git bisect good HEAD~2
>
> When both one "good" and one "bad" commits have been specified, then
> Git starts bisecting, which means that you should then see something
> like:
>
> Bisecting: 0 revisions left to test after this (roughly 0 steps)
> [df357f37981b7f1e804684cc09842d02fd012146] Commit 2 - middle
>
> and Git should have checked out "Commit 2 - middle", so HEAD should
> point to that commit.
>
> By the way it could help if you could show git's output when giving
> steps to reproduce like this.
>
>> git bisect skip HEAD~1
>
> This will "skip" the commit before the current one, so "Commit 1 -
> good", which is already marked as "good".

Good eyes. I missed that "HEAD~1 no longer means the second one at that point because you gave both bad and good already", which you correctly identified as the root cause of the confusion. The user thought #2 is marked to be skipped, but in reality #1 that is good is marked for skipping, which would result in nonsensical output, as the final output phase assumes that all skipped ones haven't been even tested.

Avoid this (I am not saying we should implement such a safety measure, at least not yet) would involve "Are you sure? You've already said X is A but now you are saying it is B" confirmation when "git bisect {good,bad,skip}" is used on a commit that the user already said something about. Allowing them to change their mind is a good feature. We'd need to make consistent changes. For example, when we create refs/bisect/bad, we should check if we already have refs/bisect/good-* that points at the same commit (and vice versa) to make sure we do not mark the same commit as both good and bad. The same thing can be said about "refs/bisect/skip-*".

This is a tangent, but do we forbid using the word "skip" as a customized term for "good"? If we are not, we probably should.

Thanks.

← back to recent threads