Boost logo

Boost :

Subject: Re: [boost] git cherry-pick (Was: RE process (prospective from a retired FreeBSD committer)...)
From: Dave Abrahams (dave_at_[hidden])
Date: 2011-01-30 20:07:23


At Sun, 30 Jan 2011 23:14:53 +0000,
Christopher Jefferson wrote:
>
>
> On 30 Jan 2011, at 21:05, Vladimir Prus wrote:
> >
> > Exactly, so this does not work for the case of cherry-pick from long-lived
> > public development branch of library X to release branch.
> >
> > Now, this use of git rebase appears to contradict my earlier statements
> > that git cannot record cherry-pick merges, so I went to investigate, and,
> > unfortunately, discovered a bug in my script. Instead of simulating the
> > 'I did cherry-pick, found conflicts, and edited them' use case it simulates
> > 'I did cherry-pick, and then edited the same lines in another commit' use
> > case. So, I've modified the script to do the right thing (see below), and
> > rebase trick no longer works. In fact, rebase itself causes a conflict.
> >
> > Looks like git cherry-pick is still deficient.
>
> I agree this is a problem with git. I think the problem is having a
> "trunk" which is merged piece-meal into a release branch. This is an
> unusual method of development, I'm not sure of any other large
> projects which have the a long-lived trunk and release, with merges
> from trunk to release. git does not support this well.

Actually it does; if all you ever do with Git is merge stuff, then
you're golden.

What Git doesn't support well is something else entirely... I just got
the low-down on #git and it was definitely an eye-opener. Basically,
there's a rule (maybe even an "ethic") that you're supposed to follow
with Git, and if you don't, you'll have this kind of trouble
eventually. IIUC, the ethic is that you don't keep the same "logical
change" around with two different commit histories (and sharing a
logical change with other people is considered "keeping it around,"
because you've lost control of its lifetime. Thus:

* Rewriting history should only be done on private commits, *and then
  you should throw away your reference to the old history so you don't
  get yourself in trouble*

* You never rebase or cherry-pick commits from a _public_ feature
  branch onto another public branch

* You never squash public commits onto another public branch.

Because each commit is a unique object, and its history is part of its
identity, doing any of these things is considered to be almost like
lying about history. The people on #git that I talked to were pretty
hard-line about this, and said that if you buy into the ethic you
almost never need to break it.

Instead of cherry picking a fix off the publically-visible 1.43
release branch for incorporation into the current trunk, what you
*should* do (according to this ethic) is merge the 1.43 branch into
trunk.

Now, to make this work in practice you need to accept a slightly
flexible meaning of "public" and "private." That is, for a number of
purposes you may need to show people commits that they should expect
to get rewritten, and you need to label these as "not for public
consumption." For example, if you want someone to pull from your
repository, and there's any chance they might look at your changes and
say "I like all of them except that one in the middle," the branch you
publish should be marked "volatile", so that people know to expect
those same logical changes might reappear in a different commit
history. You can actually name the branch "volatile/myfeature" if you
want!

If the upstream maintainer rejects your changes, you can rewrite them
and publish them as volatile again, until they are finally merged.

So, to reiterate, what Git doesn't support well is _maintaining_ the
same logical change in two different commit histories.

-- 
Dave Abrahams
BoostPro Computing
http://www.boostpro.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk