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.