[Core GIT] Long-term cherrypicking
Hello,
I've been working out some workflow possibilities with Karsten Keil at
the SuSE Labs conference, and I'd like to see your opinions. His
position does not seem unique at all, so I'm a bit surprised that noone
solved this before, or at least I didn't find any documentation about
this in the tutorial and howtos (or perhaps I missed it?).
His situation is that he has some patches in the ISDN subsystem, a
public repository, but sends the patches over e-mail to Linus. So he is
something between the subsystem maintainer and individual developer in
the categories listed out in the tutorial. What should be his merging
strategy?
Since he has public repository, he cannot rebase, but he needs to
be cherrypicking. The trouble is, git-cherry really does not work
"through" merges now - it stops at his last merge with Linus. The
obvious solution would be something like this patch:
diff --git a/git-cherry.sh b/git-cherry.sh
--- a/git-cherry.sh
+++ b/git-cherry.sh
@@ -5,18 +5,22 @@
. git-sh-setup || die "Not a git archive."
-usage="usage: $0 "'[-v] <upstream> [<head>]
+usage="usage: $0 "'[-v] <upstream> [<head>] [<base>]
__*__*__*__*__> <upstream>
- /
- fork-point
+ / \
+ <base> \ fork-point
\__+__+__+__+__+__+__+__> <head>
Each commit between the fork-point and <head> is examined, and
-compared against the change each commit between the fork-point and
+compared against the change each commit between the <base> and
<upstream> introduces. If the change seems to be in the upstream,
it is shown on the standard output with prefix "+". Otherwise
it is shown with prefix "-".
+
+If no <base> is specified, it is assumed to be the same as fork-point.
+This is the case if you run git-cherry only before you merge the
+upstream.
'
case "$1" in -v) verbose=t; shift ;; esac
@@ -35,12 +39,16 @@ case "$#" in
2) upstream=`git-rev-parse --verify "$1"` &&
ours=`git-rev-parse --verify "$2"` || exit
;;
+3) upstream=`git-rev-parse --verify "$1"` &&
+ ours=`git-rev-parse --verify "$2"` &&
+ base=`git-rev-parse --verify "$3"` || exit
*) echo >&2 "$usage"; exit 1 ;;
esac
# Note that these list commits in reverse order;
# not that the order in inup matters...
-inup=`git-rev-list ^$ours $upstream` &&
+[ -z "$base" ] && base=$ours
+inup=`git-rev-list ^$base $upstream` &&
ours=`git-rev-list $ours ^$upstream` || exit
tmp=.cherry-tmp$$
Then you would invoke it like
git cherry origin master forkpoint
where forkpoint is a tag pointing at the last known point in Linus'
branch when he had all my (well, Karsten's) patches integrated in his
tree. I tested it briefly and it seems to work - I suppose that I will
leave more testing to him. :-) If GIT wants to be even cooler, it could
remember the last forkpoint and automatically advance it.
Opinions?
PS: Perex hints over my shoulder that the ALSA guys are just manually
recording which patches were merged and which weren't. It's a shame that
GIT has no UI to do that for them if it can. Anyway, I'll be thinking
about if/how to implement the cherrypicking workflow support for Cogito.
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.