# Recording cherry-picked commits

8 messages from 2008-03-21 to 2008-03-23. Participants: Jean-Baptiste Quenot, Rafael Garcia-Suarez, Junio C Hamano, Johannes Schindelin.
Thread: https://gitlist.dev/t/12791

## Jean-Baptiste Quenot, 2008-03-21 12:33

Subject: Recording cherry-picked commits
Message-ID: <ae63f8b50803210533n12645fb3w9a8be601c4cc394@mail.gmail.com>
URL: https://gitlist.dev/e/ae63f8b50803210533n12645fb3w9a8be601c4cc394%40mail.gmail.com

```
Hi there,

Cherry-picking is great with Git, both with git-cherry-pick and
git-cherry.   I use them to pick commits from my development branch to
my stable maintenance branch that goes to production.

But when a particular commit is slightly different between the two
branches (due to eg a conflict resolution in my stable branch), then
git-cherry still lists the commit as only present in the development
branch.  This is a feature, as documented in the man page, because
git-cherry compares the changeset rather than the commit id.

So I'm wondering if there's a way to record the commit ID as being
already picked from the development branch to the stable branch, so
that it's not listed again when I provide the same arguments to
cherry-pick.  I was used to this kind of feature with svnmerge, a
wrapper script around svn that records cherry-picked commits in a
Subversion property called svnmerge-integrated on the root directory.
But with Git, what is the best practice for knowing which commits you
already picked?

Ideally, the set of already-picked commits would be versioned in the
Git repo itself, so that other developers can watch what commits are
available to pick as well.

Thanks in advance,
-- 
Jean-Baptiste Quenot
http://caraldi.com/jbq/blog/

```

## Jean-Baptiste Quenot, 2008-03-22 16:37

Subject: Re: Recording cherry-picked commits
Message-ID: <ae63f8b50803220937k78571fbdl1eeb60966ec7aa40@mail.gmail.com>
URL: https://gitlist.dev/e/ae63f8b50803220937k78571fbdl1eeb60966ec7aa40%40mail.gmail.com
In-Reply-To: <ae63f8b50803210533n12645fb3w9a8be601c4cc394@mail.gmail.com>

```
What about using a hidden ".gitcherry" file in the current branch to
store the commits that have been applied?  With the simple shell
scripts below I'm able to achieve the same effect as svnmerge:


Wrapper around git-cherry-pick:
------------------------------------------------------------------------
#! /bin/sh -e

# Write the commit in .gitcherry, stage .gitcherry for commit and call
# git-cherry-pick.  If a conflict occurs, resolve it and invoke this script with
# --continue, in order to commit with the original author and commit message

if test "$1" = "--continue" ; then
    cont=1
    commit=$(tail -1 .gitcherry)
else
    cont=0
    commit=$1
fi

if test $cont = 0 ; then
    echo $commit >> .gitcherry
    git add .gitcherry
    git cherry-pick $commit
else
    git commit -c $commit
fi
-------------------------------------------------------------------------


Wrapper around git-cherry:
------------------------------------------------------------------------
#! /bin/sh -e

# List all commits with git-cherry and exclude all the ones that are specified
# in .gitcherry.  For each commit, invoke 'git show' to print the commit message

for commit in $(git-cherry $* | sed -ne 's/^+ //p' | grep -v -f .gitcherry) ; do
    git show -s --pretty=format:"%H %s" $commit
done
------------------------------------------------------------------------

WDYT?
-- 
Jean-Baptiste Quenot
http://caraldi.com/jbq/blog/

```

## Rafael Garcia-Suarez, 2008-03-22 22:48

Subject: Re: Recording cherry-picked commits
Message-ID: <b77c1dce0803221548x3250cb90taa9a9d53464f7ea7@mail.gmail.com>
URL: https://gitlist.dev/e/b77c1dce0803221548x3250cb90taa9a9d53464f7ea7%40mail.gmail.com
In-Reply-To: <ae63f8b50803220937k78571fbdl1eeb60966ec7aa40@mail.gmail.com>

```
On 22/03/2008, Jean-Baptiste Quenot <jbq@caraldi.com> wrote:
> What about using a hidden ".gitcherry" file in the current branch to
>  store the commits that have been applied?  With the simple shell
>  scripts below I'm able to achieve the same effect as svnmerge:

(.gitcherry should really be at the root of the git repository, not in
the current directory)

What happens to .gitcherry across merges ? I think your solution isn't
robust enough.

Here's an alternate idea: store the original sha1 in the commit
message, via a custom header (something like X-Cherry-Picked-From) at
least in case of conflict, and have git-cherry recognize it.

(I have the same problem as you, by the way, and would really like to
see it solved one way or another.)

```

## Junio C Hamano, 2008-03-23 00:37

Subject: Re: Recording cherry-picked commits
Message-ID: <7veja2gts9.fsf@gitster.siamese.dyndns.org>
URL: https://gitlist.dev/e/7veja2gts9.fsf%40gitster.siamese.dyndns.org
In-Reply-To: <b77c1dce0803221548x3250cb90taa9a9d53464f7ea7@mail.gmail.com>

```
"Rafael Garcia-Suarez" <rgarciasuarez@gmail.com> writes:

> Here's an alternate idea: store the original sha1 in the commit
> message, via a custom header (something like X-Cherry-Picked-From) at
> least in case of conflict, and have git-cherry recognize it.
>
> (I have the same problem as you, by the way, and would really like to
> see it solved one way or another.)

"-x"?

```

## Jean-Baptiste Quenot, 2008-03-23 11:07

Subject: Re: Recording cherry-picked commits
Message-ID: <ae63f8b50803230407u7062586dy26fab7d98090efb9@mail.gmail.com>
URL: https://gitlist.dev/e/ae63f8b50803230407u7062586dy26fab7d98090efb9%40mail.gmail.com
In-Reply-To: <b77c1dce0803221548x3250cb90taa9a9d53464f7ea7@mail.gmail.com>

```
2008/3/22, Rafael Garcia-Suarez <rgarciasuarez@gmail.com>:
> On 22/03/2008, Jean-Baptiste Quenot <jbq@caraldi.com> wrote:
>  > What about using a hidden ".gitcherry" file in the current branch to
>  >  store the commits that have been applied?  With the simple shell
>  >  scripts below I'm able to achieve the same effect as svnmerge:
>
> (.gitcherry should really be at the root of the git repository, not in
>  the current directory)

Yes that's what I meant.  Usually I'm always at the root when I'm
cherry-picking changes but you're right the script could be improved
in this regard.  Is there a trick to find the root repository
directory?

>  What happens to .gitcherry across merges ?  I think your solution isn't robust
> enough.

The .gitcherry is merged like any other file.  I'm just trying to
mimic svnmerge here, not to reinvent anything.  As Git does not have
file metadata, I'm using a plain text file to achieve this.

>  Here's an alternate idea: store the original sha1 in the commit
>  message, via a custom header (something like X-Cherry-Picked-From) at
>  least in case of conflict, and have git-cherry recognize it.

I like your idea of filtering on commit messages, that makes sense and
it voids the use of .gitcherry, and thus better preserves the diffs.

Here is the updated git-cherry-pick wrapper.  Note that we repeat the
commit log in the message, and we're loosing the author information.
Keeping the author would require to change git-commit to allow
combining -C and -F.  Also it seems that -C and -t are incompatible,
although git-commit does not error out.

Junio suggests to use git-cherry's -x flag, but it is not written upon
conflict, so it's useless for the current usecase about properly
handling conflicts during cherry-picking.

------------------------------------------------------------------------
#! /bin/sh -e

# Record the commit id in .git/CHERRY_COMMIT, and call git-cherry-pick without
# actually committing.  If a conflict occurs, resolve it and invoke this script
# with --continue.  The commit log is then fed to git commit.
#
# FIXME find the root repository directory

if test "$1" = "--continue" ; then
    cont=1
    commit=$(cat .git/CHERRY_COMMIT)
else
    cont=0
    commit=$1
fi

if test $cont = 0 ; then
    echo $commit > .git/CHERRY_COMMIT
    git cherry-pick -n $commit
fi

git log -1 $commit | git commit -F -
rm -f .git/CHERRY_COMMIT
------------------------------------------------------------------------


And the updated git-cherry wrapper:
------------------------------------------------------------------------
#! /bin/sh -e

# List all commits with git-cherry and exclude all the ones that are already
# part of the change log of the current branch.  For each available commit,
# invoke 'git show' to print the commit message.

tempfile=$(tempfile -p $(basename $0))
git log --pretty=format:%s | sed -ne 's/^commit
\([a-z0-9]\{40\}\)$/\1/p' > $tempfile

for commit in $(git-cherry $* | sed -ne 's/^+ //p' | grep -v -f $tempfile) ; do
    git show -s --pretty=format:"%H %s" $commit
done

rm -f $tempfile
------------------------------------------------------------------------

Cheers,
-- 
Jean-Baptiste Quenot
http://caraldi.com/jbq/blog/

```

## Johannes Schindelin, 2008-03-23 12:11

Subject: Re: Recording cherry-picked commits
Message-ID: <alpine.LSU.1.00.0803231309370.4353@racer.site>
URL: https://gitlist.dev/e/alpine.LSU.1.00.0803231309370.4353%40racer.site
In-Reply-To: <ae63f8b50803230407u7062586dy26fab7d98090efb9@mail.gmail.com>

```
Hi,

On Sun, 23 Mar 2008, Jean-Baptiste Quenot wrote:

> 2008/3/22, Rafael Garcia-Suarez <rgarciasuarez@gmail.com>:
> > On 22/03/2008, Jean-Baptiste Quenot <jbq@caraldi.com> wrote:
> >  > What about using a hidden ".gitcherry" file in the current branch 
> >  > to store the commits that have been applied?  With the simple shell 
> >  > scripts below I'm able to achieve the same effect as svnmerge:
> >
> > (.gitcherry should really be at the root of the git repository, not in 
> > the current directory)
> 
> Yes that's what I meant.  Usually I'm always at the root when I'm 
> cherry-picking changes but you're right the script could be improved in 
> this regard.  Is there a trick to find the root repository directory?

Actually, you should not store it in the root of the working tree, but in 
the git dir (because it should never be tracked!), and then you can make 
it non-hidden:

	file="$(git rev-parse --git-dir)"/cherry

> > What happens to .gitcherry across merges ?  I think your solution 
> > isn't robust enough.
> 
> The .gitcherry is merged like any other file.  I'm just trying to
> mimic svnmerge here, not to reinvent anything.  As Git does not have
> file metadata, I'm using a plain text file to achieve this.

Ah, I see, so you _want_ to track it.  I do not like this idea personally, 
but then, I will not use .gitcherry anyway.

	file="$(git rev-parse --show-cdup)"/.gitcherry

Hth,
Dscho

```

## Rafael Garcia-Suarez, 2008-03-23 13:57

Subject: Re: Recording cherry-picked commits
Message-ID: <b77c1dce0803230657i6d61abefg3b0ee7b42119927c@mail.gmail.com>
URL: https://gitlist.dev/e/b77c1dce0803230657i6d61abefg3b0ee7b42119927c%40mail.gmail.com
In-Reply-To: <alpine.LSU.1.00.0803231309370.4353@racer.site>

```
On 23/03/2008, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> Actually, you should not store it in the root of the working tree, but in
>  the git dir (because it should never be tracked!), and then you can make
>  it non-hidden:
>
>         file="$(git rev-parse --git-dir)"/cherry

But this way, how can it be shared among several repositories?
(without patching git-clone itself, that might be a solution.) The use
case being many commiters cherry-picking patches from a development
branch to a maintainance one.

```

## Johannes Schindelin, 2008-03-23 14:12

Subject: Re: Recording cherry-picked commits
Message-ID: <alpine.LSU.1.00.0803231512110.4353@racer.site>
URL: https://gitlist.dev/e/alpine.LSU.1.00.0803231512110.4353%40racer.site
In-Reply-To: <b77c1dce0803230657i6d61abefg3b0ee7b42119927c@mail.gmail.com>

```
Hi,

On Sun, 23 Mar 2008, Rafael Garcia-Suarez wrote:

> On 23/03/2008, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> > Actually, you should not store it in the root of the working tree, but in
> >  the git dir (because it should never be tracked!), and then you can make
> >  it non-hidden:
> >
> >         file="$(git rev-parse --git-dir)"/cherry
> 
> But this way, how can it be shared among several repositories?

As I said, I would not want it shared.  Or tracked.

You can still do what you want to, though.

Ciao,
Dscho

```
