# [Bug report] git cherry-pick silently ignores error whereas git apply fails for hunk apply

7 messages from 2025-11-07 to 2025-11-09. Participants: Bhavik Bavishi, Johannes Sixt, Chris Torek.
Thread: https://gitlist.dev/t/64454

## Bhavik Bavishi, 2025-11-07 04:39

Subject: [Bug report] git cherry-pick silently ignores error whereas git apply fails for hunk apply
Message-ID: <CAEyHQXWd77_jJachC6FYbWMJ+L=KkKoUqiACQ7z8r-ZwYq8JYw@mail.gmail.com>
URL: https://gitlist.dev/e/CAEyHQXWd77_jJachC6FYbWMJ%2BL%3DKkKoUqiACQ7z8r-ZwYq8JYw%40mail.gmail.com

```
Thank you for filling out a Git bug report!
Please answer the following questions to help us understand your issue.

What did you do before the bug happened? (Steps to reproduce your issue)
> ran git cherry-pick command, which went fine without any error, but missed to apply change
> created patch with 'git fromat-patch' and applied with 'git apply --verbose', which error for the issue

What did you expect to happen? (Expected behavior)
> git cherry-pick should fail, since it failed to apply hunk

What happened instead? (Actual behavior)
> git cherry-pick completed successfully without any error

What's different between what you expected and what actually happened?
> git apply --verbose, failed with error about the issue, whereas git cherry-pick didn't fail for the same

Anything else you want to add:
> same error observed with '2.51.2' version as well
> we do primarily use Gerrit UI for cherry-pick, so JGIT has similar behaviour as git cli for cherry-pick.

> can we have verbose mode for git cherry-pick, like git apply --verbose ?

> below is output of git apply (note I've changed words for source code references)
=======================================================================
git apply --verbose ../test.patch
Checking patch mango/connectors/apple/ops/query_check_hierarchy_op.cc...
Checking patch mango/connectors/container/loc_base/util.cc...
Checking patch mango/connectors/container/loc_base/util.h...
Checking patch mango/main/http_test_ops/new_op.cc...
Hunk #1 succeeded at 56 (offset 2 lines).
Hunk #2 succeeded at 1074 (offset 21 lines).
Checking patch mango/main/main.cc...
Hunk #1 succeeded at 9876 (offset -63 lines).
Checking patch mango/main/ops/refresh_apple_hierarchy_op.cc...
Hunk #4 succeeded at 1713 (offset 18 lines).
Checking patch mango/main/validation_util.cc...
Hunk #1 succeeded at 42 (offset -1 lines).
Hunk #2 succeeded at 106 (offset -2 lines).
Hunk #3 succeeded at 11167 (offset -14 lines).
Checking patch mango/conn/ops/apple_box_storage_package_op.cc...
Checking patch mango/utils/apple_utils.cc...
error: while searching for:

//-----------------------------------------------------------------------------

// Returns true if Apple Box Pack usecases + the corresponding updates flag
// is enabled.
bool Converter::IsAppleBoxPackEnabled(
    std::shared_ptr<const orange::FeatureEnabler> updates_checks,
    std::shared_ptr<const mango::RegisteredParams>
        newed_params) {
  for (const auto& usecase :
       newed_params->apple_params().use_cases()) {
    if ((usecase == RegisteredAppleParams_UseCase_kBoxPack) &&
        updates_checks->updates_list_map()
            .apple_box_storage_protection_enabled()) {
      return true;
    }
  }
  return false;
}

//-----------------------------------------------------------------------------

}}}  // namespace org::mango::apple

error: patch failed: mango/utils/apple_utils.cc:658
error: mango/utils/apple_utils.cc: patch does not apply
Checking patch mango/utils/apple_utils.h...
=======================================================================

Please review the rest of the bug report below.
You can delete any lines you don't wish to share.


[System Info]
git version:
git version 2.34.1
cpu: x86_64
no commit associated with this build
sizeof-long: 8
sizeof-size_t: 8
shell-path: /bin/sh
uname: Linux 5.15.0-160-generic #170-Ubuntu SMP Wed Oct 1 10:06:56 UTC
2025 x86_64
compiler info: gnuc: 11.4
libc info: glibc: 2.35
$SHELL (typically, interactive shell): /bin/bash


[Enabled Hooks]
commit-msg

```

## Johannes Sixt, 2025-11-07 06:37

Subject: Re: [Bug report] git cherry-pick silently ignores error whereas git apply fails for hunk apply
Message-ID: <e1fede83-bed0-49e9-84a0-f026b9df6039@kdbg.org>
URL: https://gitlist.dev/e/e1fede83-bed0-49e9-84a0-f026b9df6039%40kdbg.org
In-Reply-To: <CAEyHQXWd77_jJachC6FYbWMJ+L=KkKoUqiACQ7z8r-ZwYq8JYw@mail.gmail.com>

```
Am 07.11.25 um 05:39 schrieb Bhavik Bavishi:
> What did you do before the bug happened? (Steps to reproduce your issue)
>> ran git cherry-pick command, which went fine without any error, but missed to apply change
>> created patch with 'git fromat-patch' and applied with 'git apply --verbose', which error for the issue
> 
> What did you expect to happen? (Expected behavior)
>> git cherry-pick should fail, since it failed to apply hunk
> 
> What happened instead? (Actual behavior)
>> git cherry-pick completed successfully without any error
> 
> What's different between what you expected and what actually happened?
>> git apply --verbose, failed with error about the issue, whereas git cherry-pick didn't fail for the same


If you use `git apply --3way`, does it still fail, or does it succeed
and does it produce the same result as `git cherry-pick` or a different
result?

-- Hannes


```

## Bhavik Bavishi, 2025-11-07 08:35

Subject: Re: [Bug report] git cherry-pick silently ignores error whereas git apply fails for hunk apply
Message-ID: <CAEyHQXWd4kN=ehWh0Y7xNnPGk3ofXEc4=PvSYaZM91TFyLtnpg@mail.gmail.com>
URL: https://gitlist.dev/e/CAEyHQXWd4kN%3DehWh0Y7xNnPGk3ofXEc4%3DPvSYaZM91TFyLtnpg%40mail.gmail.com
In-Reply-To: <e1fede83-bed0-49e9-84a0-f026b9df6039@kdbg.org>

```
git apply --3way --verbose ../test.patch ; echo $?
Checking patch mango/connectors/apple/ops/query_check_hierarchy_op.cc...
Applied patch to
'mango/connectors/apple/ops/query_check_hierarchy_op.cc' cleanly.
Checking patch mango/connectors/container/loc_base/util.cc...
Applied patch to 'mango/connectors/container/loc_base/util.cc' cleanly.
Checking patch mango/connectors/container/loc_base/util.h...
Applied patch to 'mango/connectors/container/loc_base/util.h' cleanly.
Checking patch mango/main/http_test_ops/new_entity_op.cc...
Applied patch to 'mango/main/http_test_ops/new_entity_op.cc' cleanly.
Checking patch mango/main/main.cc...
Applied patch to 'mango/main/main.cc' cleanly.
Checking patch mango/main/ops/refresh_apple_entity_hierarchy_op.cc...
Applied patch to 'mango/main/ops/refresh_apple_entity_hierarchy_op.cc' cleanly.
Checking patch mango/main/validation_util.cc...
Applied patch to 'mango/main/validation_util.cc' cleanly.
Checking patch mango/conn/ops/apple_box_storage_package_op.cc...
Applied patch to 'mango/conn/ops/apple_box_storage_package_op.cc' cleanly.
Checking patch mango/utils/apple_utils.cc...
Applied patch to 'mango/utils/apple_utils.cc' cleanly.
Checking patch mango/utils/apple_utils.h...
Applied patch to 'mango/utils/apple_utils.h' cleanly.
Applied patch mango/connectors/apple/ops/query_check_hierarchy_op.cc cleanly.
Applied patch mango/connectors/container/loc_base/util.cc cleanly.
Applied patch mango/connectors/container/loc_base/util.h cleanly.
Applied patch mango/main/http_test_ops/new_entity_op.cc cleanly.
Applied patch mango/main/main.cc cleanly.
Applied patch mango/main/ops/refresh_apple_entity_hierarchy_op.cc cleanly.
Applied patch mango/main/validation_util.cc cleanly.
Applied patch mango/conn/ops/apple_box_storage_package_op.cc cleanly.
Applied patch mango/utils/apple_utils.cc cleanly.
Applied patch mango/utils/apple_utils.h cleanly.
0

I've compare the file content of `mango/utils/apple_utils.cc` for `git
apply --3way` and  `git cherry-pick` is same

On Fri, Nov 7, 2025 at 12:07 PM Johannes Sixt <j6t@kdbg.org> wrote:
>
> Am 07.11.25 um 05:39 schrieb Bhavik Bavishi:
> > What did you do before the bug happened? (Steps to reproduce your issue)
> >> ran git cherry-pick command, which went fine without any error, but missed to apply change
> >> created patch with 'git fromat-patch' and applied with 'git apply --verbose', which error for the issue
> >
> > What did you expect to happen? (Expected behavior)
> >> git cherry-pick should fail, since it failed to apply hunk
> >
> > What happened instead? (Actual behavior)
> >> git cherry-pick completed successfully without any error
> >
> > What's different between what you expected and what actually happened?
> >> git apply --verbose, failed with error about the issue, whereas git cherry-pick didn't fail for the same
>
>
> If you use `git apply --3way`, does it still fail, or does it succeed
> and does it produce the same result as `git cherry-pick` or a different
> result?
>
> -- Hannes
>

```

## Bhavik Bavishi, 2025-11-08 03:44

Subject: Re: [Bug report] git cherry-pick silently ignores error whereas git apply fails for hunk apply
Message-ID: <CAEyHQXUgzRnT=8Fydn9Ew6V29hfJcjR8i26mdvGOXaWD=agzNA@mail.gmail.com>
URL: https://gitlist.dev/e/CAEyHQXUgzRnT%3D8Fydn9Ew6V29hfJcjR8i26mdvGOXaWD%3DagzNA%40mail.gmail.com
In-Reply-To: <CAEyHQXWd4kN=ehWh0Y7xNnPGk3ofXEc4=PvSYaZM91TFyLtnpg@mail.gmail.com>

```
> > If you use `git apply --3way`, does it still fail, or does it succeed
> > and does it produce the same result as `git cherry-pick` or a different
> > result?
> I've compare the file content of `mango/utils/apple_utils.cc` for `git
apply --3way` and  `git cherry-pick` is same

If I understand correctly, `git cherry-pick` is processed as expected, but for
some reason we are not able to follow this behavior because the end result is
missing content. expectation was to have this content either be applied
successfully or fail with a conflict (indicating it could not be applied).

query: is there a way to understand this behavior? Based on that, we can then
correct or update the file format to avoid such issues in the future, or
introduce an additional process to run `git apply` (without `--3way`) and check
if there is any hunk failed to apply and notify for the same.

```

## Johannes Sixt, 2025-11-08 08:26

Subject: Re: [Bug report] git cherry-pick silently ignores error whereas git apply fails for hunk apply
Message-ID: <6f9a0358-4d87-477a-a067-081ce6b2d102@kdbg.org>
URL: https://gitlist.dev/e/6f9a0358-4d87-477a-a067-081ce6b2d102%40kdbg.org
In-Reply-To: <CAEyHQXUgzRnT=8Fydn9Ew6V29hfJcjR8i26mdvGOXaWD=agzNA@mail.gmail.com>

```
Am 08.11.25 um 04:44 schrieb Bhavik Bavishi:
>>> If you use `git apply --3way`, does it still fail, or does it succeed
>>> and does it produce the same result as `git cherry-pick` or a different
>>> result?
>> I've compare the file content of `mango/utils/apple_utils.cc` for `git
> apply --3way` and  `git cherry-pick` is same
> 
> If I understand correctly, `git cherry-pick` is processed as expected, but for
> some reason we are not able to follow this behavior because the end result is
> missing content. expectation was to have this content either be applied
> successfully or fail with a conflict (indicating it could not be applied).
> 
> query: is there a way to understand this behavior? Based on that, we can then
> correct or update the file format to avoid such issues in the future, or
> introduce an additional process to run `git apply` (without `--3way`) and check
> if there is any hunk failed to apply and notify for the same.

`git cherry-pick` and `git apply --3wax` use a merge strategy. If this
operation omits a change, then it is usually the case that it was
determined that the change was already applied independently. This in
turn can happen in a situation where there are repeated occurrences of
the same text, and only some of them are changed, like this (and I am
speculating here):

base:   ...ABC...ABC...
theirs: ...ABC...AXC...
ours:   .........AXC...ABC...

Here, the merge strategy thinks that the change of the second "ABC" to
"AXC" on their side matches up with the first "ABC", but that has
already been changed to "AXC" independently on our side, hence, there is
nothing more to do.

-- Hannes


```

## Chris Torek, 2025-11-08 10:57

Subject: Re: [Bug report] git cherry-pick silently ignores error whereas git apply fails for hunk apply
Message-ID: <CAPx1GvcwAj5k0QEwxS8h=VNBNTgtxAaXGAf1a38Sb18COuSHEA@mail.gmail.com>
URL: https://gitlist.dev/e/CAPx1GvcwAj5k0QEwxS8h%3DVNBNTgtxAaXGAf1a38Sb18COuSHEA%40mail.gmail.com
In-Reply-To: <CAEyHQXWd4kN=ehWh0Y7xNnPGk3ofXEc4=PvSYaZM91TFyLtnpg@mail.gmail.com>

```
On Fri, Nov 7, 2025 at 12:35 AM Bhavik Bavishi <bhavikdbavishi@gmail.com> wrote:

["git apply" fails, "git apply --3way" and "git cherry-pick" succeed, and:]

> I've compare the file content of `mango/utils/apple_utils.cc` for `git
> apply --3way` and  `git cherry-pick` is same

This is all entirely normal.  You're seeing the difference between a
"patch" and an actual "three way merge".  The cherry-pick command does a
three-way merge using the complete information available to it.  The
apply command applies a simple patch, or, with "--3way", searches the
patch for auxiliary information that may or may not provide the extra
detail needed for doing a three-way merge.

To understand this, we need to illustrate the difference between
these two ideas.  Let's start with patches.

A "patch" says "we expect the file looks something like this, and
we would like to make certain changes in these areas".  If the file
*does* look "like this" in the indicated areas, it's easy to apply
the patch:

   --- lines 15 through 19 of file.txt used to be like this
   +++ lines 15 through 20 of file.txt should now look like this
      we expect the file to
      look like this
    + and we should add a line
      and then the text
      goes on as before

If file `file.txt` has the desired lines at lines 15--19, and we
add the indicated text in the middle, we've "patched" the file to
match the new desired result.

But what if the file, at lines 15 through 19, reads:

      we expect the file to
      look like this
      and we should add a line
      and then the text

Well, it sure looks like that patch was already applied.  We
can *guess* that it was in fact already applied, or we can search
for lines before or after lines 15 through 19 that read the
expected way.

Patches can add, remove, or (depending on the kind of patch)
change lines (or characters within lines, or whatever: the
more general form is "symbol by symbol, add/subtract/replace").

A *merge*, by contrast, takes two separate sets of patches:

 * First, there's a "common base version": a version both you
   and they, whoever they were, had that's absolutely 100%]
   identical in all respects.

 * Second, there's an "ours" version. By comparing the "base"
   version to the "ours" version, we find out what *we* changed.

 * Last, there's a "theirs" version. By comparing the "base"
   version to the "theirs" version, we find out what *they* changed.

This time, if we already have the change at lines 15--19 / 15--20, we'll
see that they and we have the *same* change.  We can silenly discard
their duplicate change!  We don't have to guess whether we have their
change, or whether the lines moved around somewhat in the file.

This same method handles removals (and if they're in the difference
format, "changes", which are just "remove and add" combined into one
block).

The way "git apply --3way" works is that it looks for a text line in the
patch of the form "index <hash1>..<hash2>" before the diff listing
(which has only add and remove, in Git's case). The first hash ID in
this pair of hash IDs is the Git-specific unique identifier for the
original version of the file.  Git then looks in your own Git repository
to see if you have that version of the file.  If so, that's the
"common base version".

If Git can find the base version this way, Git can then apply the patch
diff to the *base* version, which produces the "theirs" version,
guaranteed, because the change *must* apply to the base.  That ID is
*unique*, across the entire universe of every file in existence
anywhere, in any Git repository.[footnote] If you have that ID, you have
*that version* of *that file*.

Now that Git has the base version and the "theirs" version, Git can do
its own three-way merge: diff the base vs your version to see what you
changed, and diff the base vs their version to see what they changed.
This can still have conflicts, but now at least they will always be in
the right places.

Chris

[footnote] This is clearly nonsense, due to the pigeonhole principle.
And yet, Git depends on it successfully (modulo carefully engineered
hash collisions, currently possible for SHA-1 but not for SHA-256). With
some clever mathematics we can show that the chance of failure of any
given Git repository is quite small -- far smaller than the chance that
your computer will just randomly explode into flames while you're using
it, for instance.

```

## Bhavik Bavishi, 2025-11-09 10:09

Subject: Re: [Bug report] git cherry-pick silently ignores error whereas git apply fails for hunk apply
Message-ID: <CAEyHQXXKdVNRKzrTPJ1uVYVkpdMfCbSeXFW2TQJx6GNa4xStPw@mail.gmail.com>
URL: https://gitlist.dev/e/CAEyHQXXKdVNRKzrTPJ1uVYVkpdMfCbSeXFW2TQJx6GNa4xStPw%40mail.gmail.com
In-Reply-To: <CAPx1GvcwAj5k0QEwxS8h=VNBNTgtxAaXGAf1a38Sb18COuSHEA@mail.gmail.com>

```
Thanks for the explanation this helps.

On Sat, Nov 8, 2025 at 4:28 PM Chris Torek <chris.torek@gmail.com> wrote:
>
> On Fri, Nov 7, 2025 at 12:35 AM Bhavik Bavishi <bhavikdbavishi@gmail.com> wrote:
>
> ["git apply" fails, "git apply --3way" and "git cherry-pick" succeed, and:]
>
> > I've compare the file content of `mango/utils/apple_utils.cc` for `git
> > apply --3way` and  `git cherry-pick` is same
>
> This is all entirely normal.  You're seeing the difference between a
> "patch" and an actual "three way merge".  The cherry-pick command does a
> three-way merge using the complete information available to it.  The
> apply command applies a simple patch, or, with "--3way", searches the
> patch for auxiliary information that may or may not provide the extra
> detail needed for doing a three-way merge.
>
> To understand this, we need to illustrate the difference between
> these two ideas.  Let's start with patches.
>
> A "patch" says "we expect the file looks something like this, and
> we would like to make certain changes in these areas".  If the file
> *does* look "like this" in the indicated areas, it's easy to apply
> the patch:
>
>    --- lines 15 through 19 of file.txt used to be like this
>    +++ lines 15 through 20 of file.txt should now look like this
>       we expect the file to
>       look like this
>     + and we should add a line
>       and then the text
>       goes on as before
>
> If file `file.txt` has the desired lines at lines 15--19, and we
> add the indicated text in the middle, we've "patched" the file to
> match the new desired result.
>
> But what if the file, at lines 15 through 19, reads:
>
>       we expect the file to
>       look like this
>       and we should add a line
>       and then the text
>
> Well, it sure looks like that patch was already applied.  We
> can *guess* that it was in fact already applied, or we can search
> for lines before or after lines 15 through 19 that read the
> expected way.
>
> Patches can add, remove, or (depending on the kind of patch)
> change lines (or characters within lines, or whatever: the
> more general form is "symbol by symbol, add/subtract/replace").
>
> A *merge*, by contrast, takes two separate sets of patches:
>
>  * First, there's a "common base version": a version both you
>    and they, whoever they were, had that's absolutely 100%]
>    identical in all respects.
>
>  * Second, there's an "ours" version. By comparing the "base"
>    version to the "ours" version, we find out what *we* changed.
>
>  * Last, there's a "theirs" version. By comparing the "base"
>    version to the "theirs" version, we find out what *they* changed.
>
> This time, if we already have the change at lines 15--19 / 15--20, we'll
> see that they and we have the *same* change.  We can silenly discard
> their duplicate change!  We don't have to guess whether we have their
> change, or whether the lines moved around somewhat in the file.
>
> This same method handles removals (and if they're in the difference
> format, "changes", which are just "remove and add" combined into one
> block).
>
> The way "git apply --3way" works is that it looks for a text line in the
> patch of the form "index <hash1>..<hash2>" before the diff listing
> (which has only add and remove, in Git's case). The first hash ID in
> this pair of hash IDs is the Git-specific unique identifier for the
> original version of the file.  Git then looks in your own Git repository
> to see if you have that version of the file.  If so, that's the
> "common base version".
>
> If Git can find the base version this way, Git can then apply the patch
> diff to the *base* version, which produces the "theirs" version,
> guaranteed, because the change *must* apply to the base.  That ID is
> *unique*, across the entire universe of every file in existence
> anywhere, in any Git repository.[footnote] If you have that ID, you have
> *that version* of *that file*.
>
> Now that Git has the base version and the "theirs" version, Git can do
> its own three-way merge: diff the base vs your version to see what you
> changed, and diff the base vs their version to see what they changed.
> This can still have conflicts, but now at least they will always be in
> the right places.
>
> Chris
>
> [footnote] This is clearly nonsense, due to the pigeonhole principle.
> And yet, Git depends on it successfully (modulo carefully engineered
> hash collisions, currently possible for SHA-1 but not for SHA-256). With
> some clever mathematics we can show that the chance of failure of any
> given Git repository is quite small -- far smaller than the chance that
> your computer will just randomly explode into flames while you're using
> it, for instance.

```
