
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