# Question about merge & cherry pick

5 messages from 2024-11-06 to 2024-11-07. Participants: Julien Maurel, Johannes Sixt, brian m. carlson.
Thread: https://gitlist.dev/t/62460

## Julien Maurel, 2024-11-06 20:24

Subject: Question about merge & cherry pick
Message-ID: <711a0faa-6d82-48b6-819d-9ddbeda03f6a@maurel.me>
URL: https://gitlist.dev/e/711a0faa-6d82-48b6-819d-9ddbeda03f6a%40maurel.me

```
Hi,
I detect a potential issue with usage of merge and cherry pick.
I do a short script to reproduce my use case.
 From my point of view, after these operations, content on branch master 
and dev should be same with "zZz" on second line and "eDe" on last one.
But it's not the case on second line...
I test the same thing with first commit on master, cherrypick on dev, 
second update on dev, merge dev on master, result is same.
And I test to cherry pick second commit on master after final merge, 
cherry pick is ok and "fix" master content.
Can you help me to understand if it's normal or not ?

The script :
mkdir repo
cd repo

# Create a file and init 2 branches with same content
git init
echo -e "aAa\nzZz\nqQq\neEe" > file
git add .
git commit -a -m "init"
git checkout -b dev

# Update on dev
sed -i "s#Z#Y#" file
git commit -a -m "update"

# Cherrypick on master
git checkout master
git cherry-pick -x dev

# Second update on dev
git checkout dev
sed -i "s#Y#Z#" file
sed -i "s#E#D#" file
git commit -a -m "update that change second line as before first update 
and do another change"

# Merge on master
git checkout master
git merge dev --no-ff -m "Merge"

# Display result
echo
echo
echo MASTER
cat file
git checkout dev > /dev/null 2>&1
echo
echo DEV
cat file


Thanks

```

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

Subject: Re: Question about merge & cherry pick
Message-ID: <eb367098-0c88-4bc6-b824-32ee6e6d273e@kdbg.org>
URL: https://gitlist.dev/e/eb367098-0c88-4bc6-b824-32ee6e6d273e%40kdbg.org
In-Reply-To: <711a0faa-6d82-48b6-819d-9ddbeda03f6a@maurel.me>

```
Am 06.11.24 um 21:24 schrieb Julien Maurel:
> From my point of view, after these operations, content on branch master
> and dev should be same with "zZz" on second line and "eDe" on last one.
> But it's not the case on second line...

The behavior that you observe is as intended and not a bug.

You have this (consider each letter on its own line):

          A Z Q E       initial commit
         /       \
     A Y Q E      |     dev: Z -> Y
        |         |
        |     A Y Q E   master: cherry-pick Z -> Y
        |         |
     A Z Q D      |     dev: revert Y -> Z and change E -> D
         \        /
          A Y Q D       merge

Your expectation that the merge result is "A Z Q D" is wrong. Consider
what happened on the dev branch (left) since the branches diverged:
Since the change from Z to Y was reverted to Z, the only change that the
dev side contributes to the merge is that of E to D. The master side, on
the other hand, contributes the change of Z to Y. So the total of the
merge must be Z to Y from the master side and E to D from the dev side,
and that is what you get.

A merge does not consider the individual changes on the branches, but
only the differences since the merge base. For the merge operation, the
change from Z to Y never happened on the dev side. The reversal of Y to
Z is not visible for the merge and cannot contribute to the result.

-- Hannes


```

## Julien Maurel, 2024-11-07 10:32

Subject: Re: Question about merge & cherry pick
Message-ID: <a129e967-efba-48ba-b5a0-1abbb0af5c9d@maurel.me>
URL: https://gitlist.dev/e/a129e967-efba-48ba-b5a0-1abbb0af5c9d%40maurel.me
In-Reply-To: <eb367098-0c88-4bc6-b824-32ee6e6d273e@kdbg.org>

```
Ok, I didn't have this vision about how merge is apply, thanks.
There is no option to merge by considering each commit individually ?
Rebase do it but not applicable in my case :)
Thanks.

Le 07/11/2024 à 07:37, Johannes Sixt a écrit :
> Am 06.11.24 um 21:24 schrieb Julien Maurel:
>>  From my point of view, after these operations, content on branch master
>> and dev should be same with "zZz" on second line and "eDe" on last one.
>> But it's not the case on second line...
> The behavior that you observe is as intended and not a bug.
>
> You have this (consider each letter on its own line):
>
>            A Z Q E       initial commit
>           /       \
>       A Y Q E      |     dev: Z -> Y
>          |         |
>          |     A Y Q E   master: cherry-pick Z -> Y
>          |         |
>       A Z Q D      |     dev: revert Y -> Z and change E -> D
>           \        /
>            A Y Q D       merge
>
> Your expectation that the merge result is "A Z Q D" is wrong. Consider
> what happened on the dev branch (left) since the branches diverged:
> Since the change from Z to Y was reverted to Z, the only change that the
> dev side contributes to the merge is that of E to D. The master side, on
> the other hand, contributes the change of Z to Y. So the total of the
> merge must be Z to Y from the master side and E to D from the dev side,
> and that is what you get.
>
> A merge does not consider the individual changes on the branches, but
> only the differences since the merge base. For the merge operation, the
> change from Z to Y never happened on the dev side. The reversal of Y to
> Z is not visible for the merge and cannot contribute to the result.
>
> -- Hannes
>


```

## brian m. carlson, 2024-11-07 12:02

Subject: Re: Question about merge & cherry pick
Message-ID: <ZyysPeBRXvTAxLVf@tapette.crustytoothpaste.net>
URL: https://gitlist.dev/e/ZyysPeBRXvTAxLVf%40tapette.crustytoothpaste.net
In-Reply-To: <a129e967-efba-48ba-b5a0-1abbb0af5c9d@maurel.me>

```
On 2024-11-07 at 10:32:06, Julien Maurel wrote:
> Ok, I didn't have this vision about how merge is apply, thanks.
> There is no option to merge by considering each commit individually ?
> Rebase do it but not applicable in my case :)

There's no way to do a merge commit-by commit.  The recommendation is to
do a rebase, since it essentially does a commit-by-commit merge under the
hood (due to using the merge machinery).  The title of the FAQ entry at
[0] doesn't perfectly describe your case, but it does sort of explain it
and it explains how the merge and rebase machinery works.

[0] https://git-scm.com/docs/gitfaq#merge-two-revert-one
-- 
brian m. carlson (they/them or he/him)
Toronto, Ontario, CA

```

## Johannes Sixt, 2024-11-07 17:18

Subject: Re: Question about merge & cherry pick
Message-ID: <eb3a25c0-7f43-4811-a9ad-0388f395b26e@kdbg.org>
URL: https://gitlist.dev/e/eb3a25c0-7f43-4811-a9ad-0388f395b26e%40kdbg.org
In-Reply-To: <a129e967-efba-48ba-b5a0-1abbb0af5c9d@maurel.me>

```
Am 07.11.24 um 11:32 schrieb Julien Maurel:
> Le 07/11/2024 à 07:37, Johannes Sixt a écrit :
>> A merge does not consider the individual changes on the branches, but
>> only the differences since the merge base. For the merge operation, the
>> change from Z to Y never happened on the dev side. The reversal of Y to
>> Z is not visible for the merge and cannot contribute to the result.
> 
> Ok, I didn't have this vision about how merge is apply, thanks.
> There is no option to merge by considering each commit individually ?
> Rebase do it but not applicable in my case :)

You can merge the dev branch in two steps:

          A Z Q E        initial commit
          /      \
      A Y Q E     |      dev: Z -> Y
         |\       |
         | \   A Y Q E   master: cherry-pick Z -> Y
         |  \     |
         |   A Y Q E     master: merge dev
         |        |
      A Z Q D     |      dev: revert Y -> Z and change E -> D
          \      /
          A Z Q D        merge again

The merge of dev into master changes the merge base of the final merge:
it is the second commit in the diagram. Now there is no contribution to
the merge from the master branch anymore, because its tip is identical
to the merge base, and both changes made in the second commit on dev are
visible and contribute to the merge result.

-- Hannes


```
