threads / bug / 64454

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

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

## tl;dr

7 messages between Nov 7, 2025 and Nov 9, 2025.

replies: 6people: 3as markdown or json

Bhavik Bavishi· Nov 7, 2025, 04:39 UTC · lore

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· Nov 7, 2025, 06:37 UTC · re: Bhavik Bavishi · lore

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

Am 07.11.25 um 05:39 schrieb Bhavik Bavishi:
Show 12 quoted lines
> 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· Nov 7, 2025, 08:35 UTC · re: Johannes Sixt · lore

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

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:
Show 22 quoted lines
>
> 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· Nov 8, 2025, 03:44 UTC · re: Bhavik Bavishi · lore

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

> > 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· Nov 8, 2025, 08:26 UTC · re: Bhavik Bavishi · lore

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

Am 08.11.25 um 04:44 schrieb Bhavik Bavishi:
Show 15 quoted lines
>>> 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· Nov 8, 2025, 10:57 UTC · re: Bhavik Bavishi · lore

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

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· Nov 9, 2025, 10:09 UTC · re: Chris Torek · lore

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

Thanks for the explanation this helps.
On Sat, Nov 8, 2025 at 4:28 PM Chris Torek <chris.torek@gmail.com> wrote:
Show 102 quoted lines
>
> 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.

← back to recent threads