[PATCH RFC] rebase: add --revisions flag

Subsystems: the rest

STALE3739d

13 messages, 2 authors, 2016-06-15 · open the first message on its own page

[PATCH RFC] rebase: add --revisions flag

From: "Michael S. Tsirkin" <mst@redhat.com>
Date: 2016-06-15 22:47:51

Add --revisions flag to rebase, so that it can be used
to apply an arbitrary range of commits on top
of a current branch.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---

I've been wishing for this functionality for a while now,
so here goes. This isn't yet properly documented and I didn't
write a test, but the patch seems to work fine for me.
Any early flames/feedback?


 git-rebase.sh |   36 ++++++++++++++++++++++++------------
 1 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/git-rebase.sh b/git-rebase.sh
index b121f45..d99d04b 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -3,12 +3,13 @@
 # Copyright (c) 2005 Junio C Hamano.
 #
 
-USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
+USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--onto <newbase>] [--revisions <revision range>] [<upstream>|--root] [<branch>] [--quiet | -q]'
 LONG_USAGE='git-rebase replaces <branch> with a new branch of the
 same name.  When the --onto option is provided the new branch starts
 out with a HEAD equal to <newbase>, otherwise it is equal to <upstream>
 It then attempts to create a new commit for each commit from the original
-<branch> that does not exist in the <upstream> branch.
+<branch> that does not exist in the <upstream> branch, or for
+each commit matching <revision range> when the --revisions options is provided.
 
 It is possible that a merge failure will prevent this process from being
 completely automatic.  You will have to resolve any such merge failure
@@ -41,6 +42,7 @@ If you would prefer to skip this patch, instead run \"git rebase --skip\".
 To restore the original branch and stop rebasing run \"git rebase --abort\".
 "
 unset newbase
+unset revisions
 strategy=recursive
 do_merge=
 dotest="$GIT_DIR"/rebase-merge
@@ -291,6 +293,11 @@ do
 		newbase="$2"
 		shift
 		;;
+	--revisions)
+		test 2 -le "$#" || usage
+		revisions="$2"
+		shift
+		;;
 	-M|-m|--m|--me|--mer|--merg|--merge)
 		do_merge=t
 		;;
@@ -459,12 +466,24 @@ case "$#" in
 esac
 orig_head=$branch
 
+if test -z "$revisions"
+then
+	if test -n "$rebase_root"
+	then
+		revisions="$onto..$orig_head"
+	else
+		revisions="$upstream..$orig_head"
+	fi
+	mb=$(git merge-base "$onto" "$branch")
+else
+	mb=""
+fi
+
 # Now we are rebasing commits $upstream..$branch (or with --root,
 # everything leading up to $branch) on top of $onto
 
 # Check if we are already based on $onto with linear history,
 # but this should be done only when upstream and onto are the same.
-mb=$(git merge-base "$onto" "$branch")
 if test "$upstream" = "$onto" && test "$mb" = "$onto" &&
 	# linear history?
 	! (git rev-list --parents "$onto".."$branch" | sane_grep " .* ") > /dev/null
@@ -489,10 +508,10 @@ if test -n "$diffstat"
 then
 	if test -n "$verbose"
 	then
-		echo "Changes from $mb to $onto:"
+		echo "Changes $revisions:"
 	fi
 	# We want color (if set), but no pager
-	GIT_PAGER='' git diff --stat --summary "$mb" "$onto"
+	GIT_PAGER='' git diff --stat --summary "$revisions"
 fi
 
 # If the $onto is a proper descendant of the tip of the branch, then
@@ -504,13 +523,6 @@ then
 	exit 0
 fi
 
-if test -n "$rebase_root"
-then
-	revisions="$onto..$orig_head"
-else
-	revisions="$upstream..$orig_head"
-fi
-
 if test -z "$do_merge"
 then
 	git format-patch -k --stdout --full-index --ignore-if-in-upstream \
-- 
1.6.6.rc1.43.gf55cc

Re: [PATCH RFC] rebase: add --revisions flag

From: Björn Steinbrink <hidden>
Date: 2016-06-15 22:47:51

On 2009.12.08 16:47:42 +0200, Michael S. Tsirkin wrote:
Add --revisions flag to rebase, so that it can be used
to apply an arbitrary range of commits on top
of a current branch.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---

I've been wishing for this functionality for a while now,
so here goes. This isn't yet properly documented and I didn't
write a test, but the patch seems to work fine for me.
Any early flames/feedback?
This pretty much reverses what rebase normally does. Instead of "rebase
this onto that" it's "'rebase' that onto this". And instead of updating
the branch head that got rebased, the, uhm, "upstream" gets updated.

Also, AFAICT this needs to be called like this:
git rebase --revisions foo..bar HEAD

Changing the meaning of the <upstream> argument and relying on the fact
that <newbase> defaults to <upstream>. If such a thing gets added, it
should rather work like --root, not using <upstream> at all, but --onto
<newbase> only. Maybe defaulting to HEAD for <newbase> and making --onto
optional, as it's reversed WRT what it does compared to the usual
rebase.

But generally, I'd say it would be better to add such a range feature to
cherry-pick than abusing rebase for that.

Björn

Re: [PATCH RFC] rebase: add --revisions flag

From: "Michael S. Tsirkin" <mst@redhat.com>
Date: 2016-06-15 22:47:51

On Tue, Dec 08, 2009 at 05:08:22PM +0100, Björn Steinbrink wrote:
On 2009.12.08 16:47:42 +0200, Michael S. Tsirkin wrote:
quoted
Add --revisions flag to rebase, so that it can be used
to apply an arbitrary range of commits on top
of a current branch.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---

I've been wishing for this functionality for a while now,
so here goes. This isn't yet properly documented and I didn't
write a test, but the patch seems to work fine for me.
Any early flames/feedback?
This pretty much reverses what rebase normally does. Instead of "rebase
this onto that" it's "'rebase' that onto this". And instead of updating
the branch head that got rebased, the, uhm, "upstream" gets updated.

Also, AFAICT this needs to be called like this:
git rebase --revisions foo..bar HEAD

Changing the meaning of the <upstream> argument and relying on the fact
that <newbase> defaults to <upstream>. If such a thing gets added, it
should rather work like --root, not using <upstream> at all, but --onto
<newbase> only. Maybe defaulting to HEAD for <newbase> and making --onto
optional, as it's reversed WRT what it does compared to the usual
rebase.
Sorry, I had trouble parsing the above.  Could you suggest e.g. how the
help line should look?
But generally, I'd say it would be better to add such a range feature to
cherry-pick than abusing rebase for that.

Björn
The reason to use rebase is that I often want to combine
this with -i flag, editing patches as they are applied.

-- 
MST

Re: [PATCH RFC] rebase: add --revisions flag

From: "Michael S. Tsirkin" <mst@redhat.com>
Date: 2016-06-15 22:47:51

On Tue, Dec 08, 2009 at 05:08:22PM +0100, Björn Steinbrink wrote:
On 2009.12.08 16:47:42 +0200, Michael S. Tsirkin wrote:
quoted
Add --revisions flag to rebase, so that it can be used
to apply an arbitrary range of commits on top
of a current branch.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---

I've been wishing for this functionality for a while now,
so here goes. This isn't yet properly documented and I didn't
write a test, but the patch seems to work fine for me.
Any early flames/feedback?
This pretty much reverses what rebase normally does. Instead of "rebase
this onto that" it's "'rebase' that onto this". And instead of updating
the branch head that got rebased, the, uhm, "upstream" gets updated.
The last sentence is wrong I think - it is still the branch head that
is updated.

Re: [PATCH RFC] rebase: add --revisions flag

From: Björn Steinbrink <hidden>
Date: 2016-06-15 22:47:51

On 2009.12.08 18:11:44 +0200, Michael S. Tsirkin wrote:
On Tue, Dec 08, 2009 at 05:08:22PM +0100, Björn Steinbrink wrote:
quoted
On 2009.12.08 16:47:42 +0200, Michael S. Tsirkin wrote:
quoted
Add --revisions flag to rebase, so that it can be used
to apply an arbitrary range of commits on top
of a current branch.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---

I've been wishing for this functionality for a while now,
so here goes. This isn't yet properly documented and I didn't
write a test, but the patch seems to work fine for me.
Any early flames/feedback?
This pretty much reverses what rebase normally does. Instead of "rebase
this onto that" it's "'rebase' that onto this". And instead of updating
the branch head that got rebased, the, uhm, "upstream" gets updated.

Also, AFAICT this needs to be called like this:
git rebase --revisions foo..bar HEAD

Changing the meaning of the <upstream> argument and relying on the fact
that <newbase> defaults to <upstream>. If such a thing gets added, it
should rather work like --root, not using <upstream> at all, but --onto
<newbase> only. Maybe defaulting to HEAD for <newbase> and making --onto
optional, as it's reversed WRT what it does compared to the usual
rebase.
Sorry, I had trouble parsing the above.  Could you suggest e.g. how the
help line should look?
Current:
git rebase [-i | --interactive] [options] [--onto <newbase>]
	<upstream> [<branch>]
git rebase [-i | --interactive] [options] --onto <newbase>
	--root [<branch>]

Add:
git rebase [-i | --interactive] [options] --revisions <range> [<branch>]

(Thinking about it, I guess an explicit --onto makes no sense with the
--revisions flag)
quoted
But generally, I'd say it would be better to add such a range feature to
cherry-pick than abusing rebase for that.
The reason to use rebase is that I often want to combine
this with -i flag, editing patches as they are applied.
Hm, well, your patch didn't touch git-rebase--interactive.sh ;-)

Björn

Re: [PATCH RFC] rebase: add --revisions flag

From: "Michael S. Tsirkin" <mst@redhat.com>
Date: 2016-06-15 22:47:51

On Tue, Dec 08, 2009 at 05:37:37PM +0100, Björn Steinbrink wrote:
On 2009.12.08 18:14:07 +0200, Michael S. Tsirkin wrote:
quoted
On Tue, Dec 08, 2009 at 05:08:22PM +0100, Björn Steinbrink wrote:
quoted
On 2009.12.08 16:47:42 +0200, Michael S. Tsirkin wrote:
quoted
Add --revisions flag to rebase, so that it can be used
to apply an arbitrary range of commits on top
of a current branch.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---

I've been wishing for this functionality for a while now,
so here goes. This isn't yet properly documented and I didn't
write a test, but the patch seems to work fine for me.
Any early flames/feedback?
This pretty much reverses what rebase normally does. Instead of "rebase
this onto that" it's "'rebase' that onto this". And instead of updating
the branch head that got rebased, the, uhm, "upstream" gets updated.
The last sentence is wrong I think - it is still the branch head that
is updated.
But you don't rebase the branch head. Before the rebase, the branch head
doesn't reference the commits that get rebased. For example:

git checkout bar
git rebase --revisions foo bar

You "rebase" the commits in foo's history, but you update bar.
Yes, that's the who point of the patch.  The above applies a single
commit, foo, on top of current branch bar.
WRT the result, the above command should be equivalent to:
git checkout bar
git reset --hard foo
git rebase --root --onto ORIG_HEAD;

And here, the commits currently reachable through "bar" are rebased, and
"bar" also gets updated.

Björn
So this 
1. won't be very useful, as you show it is easy
   to achieve with existing commands.
2. interprets "foo" as branch name as opposed to
   revision range.

OTOH, rebase --revisions as I implemented is a "smarter cherry-pick" which
can't easily be achieved with existing commands, especially if you add
"-i".


-- 
MST

Re: [PATCH RFC] rebase: add --revisions flag

From: "Michael S. Tsirkin" <mst@redhat.com>
Date: 2016-06-15 22:47:51

On Tue, Dec 08, 2009 at 05:41:13PM +0100, Björn Steinbrink wrote:
On 2009.12.08 18:11:44 +0200, Michael S. Tsirkin wrote:
quoted
On Tue, Dec 08, 2009 at 05:08:22PM +0100, Björn Steinbrink wrote:
quoted
On 2009.12.08 16:47:42 +0200, Michael S. Tsirkin wrote:
quoted
Add --revisions flag to rebase, so that it can be used
to apply an arbitrary range of commits on top
of a current branch.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---

I've been wishing for this functionality for a while now,
so here goes. This isn't yet properly documented and I didn't
write a test, but the patch seems to work fine for me.
Any early flames/feedback?
This pretty much reverses what rebase normally does. Instead of "rebase
this onto that" it's "'rebase' that onto this". And instead of updating
the branch head that got rebased, the, uhm, "upstream" gets updated.

Also, AFAICT this needs to be called like this:
git rebase --revisions foo..bar HEAD

Changing the meaning of the <upstream> argument and relying on the fact
that <newbase> defaults to <upstream>. If such a thing gets added, it
should rather work like --root, not using <upstream> at all, but --onto
<newbase> only. Maybe defaulting to HEAD for <newbase> and making --onto
optional, as it's reversed WRT what it does compared to the usual
rebase.
Sorry, I had trouble parsing the above.  Could you suggest e.g. how the
help line should look?
Current:
git rebase [-i | --interactive] [options] [--onto <newbase>]
	<upstream> [<branch>]
git rebase [-i | --interactive] [options] --onto <newbase>
	--root [<branch>]

Add:
git rebase [-i | --interactive] [options] --revisions <range> [<branch>]

(Thinking about it, I guess an explicit --onto makes no sense with the
--revisions flag)
I agree.
So this is different from what I implemented basically only in that
we should disallow combining --onto with --revisions. Right?
quoted
quoted
But generally, I'd say it would be better to add such a range feature to
cherry-pick than abusing rebase for that.
The reason to use rebase is that I often want to combine
this with -i flag, editing patches as they are applied.
Hm, well, your patch didn't touch git-rebase--interactive.sh ;-)

Björn
Ah, I was wondering why it doesn't work :)

Re: [PATCH RFC] rebase: add --revisions flag

From: Björn Steinbrink <hidden>
Date: 2016-06-15 22:47:51

On 2009.12.08 18:14:07 +0200, Michael S. Tsirkin wrote:
On Tue, Dec 08, 2009 at 05:08:22PM +0100, Björn Steinbrink wrote:
quoted
On 2009.12.08 16:47:42 +0200, Michael S. Tsirkin wrote:
quoted
Add --revisions flag to rebase, so that it can be used
to apply an arbitrary range of commits on top
of a current branch.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---

I've been wishing for this functionality for a while now,
so here goes. This isn't yet properly documented and I didn't
write a test, but the patch seems to work fine for me.
Any early flames/feedback?
This pretty much reverses what rebase normally does. Instead of "rebase
this onto that" it's "'rebase' that onto this". And instead of updating
the branch head that got rebased, the, uhm, "upstream" gets updated.
The last sentence is wrong I think - it is still the branch head that
is updated.
But you don't rebase the branch head. Before the rebase, the branch head
doesn't reference the commits that get rebased. For example:

git checkout bar
git rebase --revisions foo bar

You "rebase" the commits in foo's history, but you update bar.

WRT the result, the above command should be equivalent to:
git checkout bar
git reset --hard foo
git rebase --root --onto ORIG_HEAD;

And here, the commits currently reachable through "bar" are rebased, and
"bar" also gets updated.

Björn

Re: [PATCH RFC] rebase: add --revisions flag

From: Björn Steinbrink <hidden>
Date: 2016-06-15 22:47:51

On 2009.12.08 18:44:49 +0200, Michael S. Tsirkin wrote:
On Tue, Dec 08, 2009 at 05:37:37PM +0100, Björn Steinbrink wrote:
quoted
On 2009.12.08 18:14:07 +0200, Michael S. Tsirkin wrote:
quoted
On Tue, Dec 08, 2009 at 05:08:22PM +0100, Björn Steinbrink wrote:
quoted
On 2009.12.08 16:47:42 +0200, Michael S. Tsirkin wrote:
quoted
Add --revisions flag to rebase, so that it can be used
to apply an arbitrary range of commits on top
of a current branch.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---

I've been wishing for this functionality for a while now,
so here goes. This isn't yet properly documented and I didn't
write a test, but the patch seems to work fine for me.
Any early flames/feedback?
This pretty much reverses what rebase normally does. Instead of "rebase
this onto that" it's "'rebase' that onto this". And instead of updating
the branch head that got rebased, the, uhm, "upstream" gets updated.
The last sentence is wrong I think - it is still the branch head that
is updated.
But you don't rebase the branch head. Before the rebase, the branch head
doesn't reference the commits that get rebased. For example:

git checkout bar
git rebase --revisions foo bar

You "rebase" the commits in foo's history, but you update bar.
Yes, that's the who point of the patch.
Yes, and it's "backwards" compared to the existing "rebase" modes, but
more like "cherry-pick".
The above applies a single commit, foo, on top of current branch bar.
Hm, no. I expected it to turn all commits reachable from foo into
patches and applying them to bar. But actually, that should hit the
special <since> mode of format-patch. So
git rebase --revisions foo bar
is (with your patch) actually the same as
git rebase foo bar

So actually the example should have been:
git rebase --root --revisions foo bar

Both invocations probably mess up the diff-stat as that becomes:
git diff --stat --summary foo
So it creates a diffstat of the diff from the working tree to "foo",
which can't be right.
quoted
WRT the result, the above command should be equivalent to:
git checkout bar
git reset --hard foo
git rebase --root --onto ORIG_HEAD;

And here, the commits currently reachable through "bar" are rebased, and
"bar" also gets updated.
So this 
1. won't be very useful, as you show it is easy
   to achieve with existing commands.
One can "almost" achieve it.
git rebase --revision A..B foo

is about the same as:
git checkout foo
git reset --hard B
git rebase --onto ORIG_HEAD A

But:
a) The "reset --hard" obviously lacks the safety checks for clean
index/working tree.
b) "git rebase --abort" won't take you back to your initial state, but
to B.
c) It's not really obvious that you can do it and how to do it.

Another possibility would be:

git checkout B^0 # detach HEAD at B
git rebase foo # rebase onto foo
git checkout foo 
git merge HEAD@{1} # Fast-forwards foo to the rebased stuff

That fixes a), avoid b) [because you don't mess up any branch head
early] but is still subject to c).

And for both methods, the ORIG_HEAD and HEAD@{1} arguments are somewhat
"unstable", e.g. checking out the wrong branch head first, and only then
the correct one, you'd have to use HEAD@{2} instead of HEAD@{1} (because
the reflog for HEAD got a new entry).

So you can already do what you want to do, but wrapping it in a single
porcelain might still be useful because it's obviously a  lot easier and
safer that way. That said, I wonder what kind of workflow you're using
though, and why you require that feature. I've never needed something
like that.
2. interprets "foo" as branch name as opposed to
   revision range.
Well, a single committish is a "range" as far as the range-based
commands are concerned, e.g. "git log master" treats "master" to mean
all commits reachable it. If "rebase --revisions master" would do the
same, that's at least consistent (and for single commit picks, there's
already cherry-pick). The problem with your patch is that it passes the
revision argument to format-patch as is, and:
git format-patch foo
is the same as
git format-patch foo..HEAD

OTOH, rebase --revisions as I implemented is a "smarter cherry-pick"
which can't easily be achieved with existing commands, especially if
you add "-i".
And that "is a 'smarter cherry-pick'" is why I think that rebase is
actually the wrong command to get that feature. While rebase internally
does just mass-cherry-picking, it does that with commits in the current
branch onto a specified branch. The --revisions flag makes it do things
the other way around.

Björn

Re: [PATCH RFC] rebase: add --revisions flag

From: Björn Steinbrink <hidden>
Date: 2016-06-15 22:47:51

On 2009.12.08 18:49:04 +0200, Michael S. Tsirkin wrote:
On Tue, Dec 08, 2009 at 05:41:13PM +0100, Björn Steinbrink wrote:
quoted
quoted
quoted
Also, AFAICT this needs to be called like this:
git rebase --revisions foo..bar HEAD

Changing the meaning of the <upstream> argument and relying on the fact
that <newbase> defaults to <upstream>. If such a thing gets added, it
should rather work like --root, not using <upstream> at all, but --onto
<newbase> only. Maybe defaulting to HEAD for <newbase> and making --onto
optional, as it's reversed WRT what it does compared to the usual
rebase.
Sorry, I had trouble parsing the above.  Could you suggest e.g. how the
help line should look?
Current:
git rebase [-i | --interactive] [options] [--onto <newbase>]
	<upstream> [<branch>]
git rebase [-i | --interactive] [options] --onto <newbase>
	--root [<branch>]

Add:
git rebase [-i | --interactive] [options] --revisions <range> [<branch>]

(Thinking about it, I guess an explicit --onto makes no sense with the
--revisions flag)
I agree.
So this is different from what I implemented basically only in that
we should disallow combining --onto with --revisions. Right?
It also drops <upstream>, because that makes no sense with --revisions.
So the only mandatory argument is the revision range.

Björn

Re: [PATCH RFC] rebase: add --revisions flag

From: "Michael S. Tsirkin" <mst@redhat.com>
Date: 2016-06-15 22:47:51

On Tue, Dec 08, 2009 at 08:11:07PM +0100, Björn Steinbrink wrote:
On 2009.12.08 18:44:49 +0200, Michael S. Tsirkin wrote:
quoted
On Tue, Dec 08, 2009 at 05:37:37PM +0100, Björn Steinbrink wrote:
quoted
On 2009.12.08 18:14:07 +0200, Michael S. Tsirkin wrote:
quoted
On Tue, Dec 08, 2009 at 05:08:22PM +0100, Björn Steinbrink wrote:
quoted
On 2009.12.08 16:47:42 +0200, Michael S. Tsirkin wrote:
quoted
Add --revisions flag to rebase, so that it can be used
to apply an arbitrary range of commits on top
of a current branch.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---

I've been wishing for this functionality for a while now,
so here goes. This isn't yet properly documented and I didn't
write a test, but the patch seems to work fine for me.
Any early flames/feedback?
This pretty much reverses what rebase normally does. Instead of "rebase
this onto that" it's "'rebase' that onto this". And instead of updating
the branch head that got rebased, the, uhm, "upstream" gets updated.
The last sentence is wrong I think - it is still the branch head that
is updated.
But you don't rebase the branch head. Before the rebase, the branch head
doesn't reference the commits that get rebased. For example:

git checkout bar
git rebase --revisions foo bar

You "rebase" the commits in foo's history, but you update bar.
Yes, that's the who point of the patch.
Yes, and it's "backwards" compared to the existing "rebase" modes, but
more like "cherry-pick".
quoted
The above applies a single commit, foo, on top of current branch bar.
Hm, no. I expected it to turn all commits reachable from foo into
patches and applying them to bar. But actually, that should hit the
special <since> mode of format-patch. So
git rebase --revisions foo bar
is (with your patch) actually the same as
git rebase foo bar

So actually the example should have been:
git rebase --root --revisions foo bar

Both invocations probably mess up the diff-stat as that becomes:
git diff --stat --summary foo
So it creates a diffstat of the diff from the working tree to "foo",
which can't be right.
quoted
quoted
WRT the result, the above command should be equivalent to:
git checkout bar
git reset --hard foo
git rebase --root --onto ORIG_HEAD;

And here, the commits currently reachable through "bar" are rebased, and
"bar" also gets updated.
So this 
1. won't be very useful, as you show it is easy
   to achieve with existing commands.
One can "almost" achieve it.
git rebase --revision A..B foo

is about the same as:
git checkout foo
git reset --hard B
git rebase --onto ORIG_HEAD A

But:
a) The "reset --hard" obviously lacks the safety checks for clean
index/working tree.
b) "git rebase --abort" won't take you back to your initial state, but
to B.
c) It's not really obvious that you can do it and how to do it.

Another possibility would be:

git checkout B^0 # detach HEAD at B
git rebase foo # rebase onto foo
git checkout foo 
git merge HEAD@{1} # Fast-forwards foo to the rebased stuff

That fixes a), avoid b) [because you don't mess up any branch head
early] but is still subject to c).

And for both methods, the ORIG_HEAD and HEAD@{1} arguments are somewhat
"unstable", e.g. checking out the wrong branch head first, and only then
the correct one, you'd have to use HEAD@{2} instead of HEAD@{1} (because
the reflog for HEAD got a new entry).

So you can already do what you want to do, but wrapping it in a single
porcelain might still be useful because it's obviously a  lot easier and
safer that way. That said, I wonder what kind of workflow you're using
though, and why you require that feature. I've never needed something
like that.
I need this often for many reasons:
-	Imagine developing a patchset with a complex bugfix on master branch.
	Then I decide to also apply (backport) this patchset to stable branch.
-	Imagine developing a bugfix/feature patchset on master branch.
	Then I decide the patchset is too large/unsafe and want to
	switch it to staging branch.
-	I have a large queue of patches on staging branch, I decide that
	a range of patches is mature enough for master.

And I often need -i to inspec/edit patches while doing this,
even though I can rebase -i later, but that would mean
figuring which commit to pass to rebase -i.
quoted
2. interprets "foo" as branch name as opposed to
   revision range.
Well, a single committish is a "range" as far as the range-based
commands are concerned, e.g. "git log master" treats "master" to mean
all commits reachable it. If "rebase --revisions master" would do the
same, that's at least consistent (and for single commit picks, there's
already cherry-pick). The problem with your patch is that it passes the
revision argument to format-patch as is, and:
git format-patch foo
is the same as
git format-patch foo..HEAD

quoted
OTOH, rebase --revisions as I implemented is a "smarter cherry-pick"
which can't easily be achieved with existing commands, especially if
you add "-i".
And that "is a 'smarter cherry-pick'" is why I think that rebase is
actually the wrong command to get that feature. While rebase internally
does just mass-cherry-picking, it does that with commits in the current
branch onto a specified branch. The --revisions flag makes it do things
the other way around.

Björn
Well, implemenation-wise, teaching cherry-pick about multiple
commits seems very hard to me. We would need to teach it about
all the flags that rebase has to patch queue management.
So I can't implement it. Can you?

-- 
MST

Re: [PATCH RFC] rebase: add --revisions flag

From: Björn Steinbrink <hidden>
Date: 2016-06-15 22:47:51

On 2009.12.08 22:00:17 +0200, Michael S. Tsirkin wrote:
On Tue, Dec 08, 2009 at 08:11:07PM +0100, Björn Steinbrink wrote:
quoted
So you can already do what you want to do, but wrapping it in a single
porcelain might still be useful because it's obviously a  lot easier and
safer that way. That said, I wonder what kind of workflow you're using
though, and why you require that feature. I've never needed something
like that.
I need this often for many reasons:
-	Imagine developing a patchset with a complex bugfix on master branch.
	Then I decide to also apply (backport) this patchset to stable branch.
Hm, I'd also imagine that you want a separate branch then, and not
directly mess up the stable branch, so I'd do:
git branch foo-stable foo # Create a branch for the backport
git rebase --onto stable master foo-stable # Backport

Now you got your backported version and can merge it to "stable".

Common wisdom is do things the other way around though. Create the
bugfix for the oldest branch that it applies to, then merge it forward,
either doing:

"bugfix -> stable" and "stable -> master" merges, or
"bugfix -> stable" and "bugfix -> master" merges.

That approach has the advantage that you don't get multiple commits
doing the same thing, which you get with rebasing/cherry-picking.

IIRC the gitworkflows manpage describe that in some more detail.
-	Imagine developing a bugfix/feature patchset on master branch.
	Then I decide the patchset is too large/unsafe and want to
	switch it to staging branch.
Hm, so you have a topic branch "foo" based upon master, but it's too
experimental so you don't want to merge it to master, but "staging". I
don't see why you even have to rebase it then. "staging" is likely ahead
of master, so the merge base of "foo" and "master" is also reachable
through "staging", and simply merging "foo" to "staging" should work
without any ill-effects.
-	I have a large queue of patches on staging branch, I decide that
	a range of patches is mature enough for master.
Basically, same deal as with the first two cases. If the series is
directly on "staging" (i.e. you didn't create a topic branch), you can
create one now:
git branch foo $last_commit_for_foo
git rebase --onto master $first_commit_for_foo^ foo

And you got your backported topic branch for "foo".

Or you already have a topic branch "foo-staging", but it's based upon
some commit only in "staging" but not in "master", so a plain merge
would mess things up. Same deal as with backporting from "master" to
"stable"

And in this case it's also true that basing the topic branches on
"master" instead of "staging" makes things easier. That way, you can
merge to either "staging" or "master" without any ill-effects.

Björn

Re: [PATCH RFC] rebase: add --revisions flag

From: "Michael S. Tsirkin" <mst@redhat.com>
Date: 2016-06-15 22:47:52

On Wed, Dec 09, 2009 at 02:19:45PM +0100, Björn Steinbrink wrote:
On 2009.12.08 22:00:17 +0200, Michael S. Tsirkin wrote:
quoted
On Tue, Dec 08, 2009 at 08:11:07PM +0100, Björn Steinbrink wrote:
quoted
So you can already do what you want to do, but wrapping it in a single
porcelain might still be useful because it's obviously a  lot easier and
safer that way. That said, I wonder what kind of workflow you're using
though, and why you require that feature. I've never needed something
like that.
I need this often for many reasons:
-	Imagine developing a patchset with a complex bugfix on master branch.
	Then I decide to also apply (backport) this patchset to stable branch.
Hm, I'd also imagine that you want a separate branch then, and not
directly mess up the stable branch,
Well, directly working with a stable branch is easier, so yes,
I want to mess it up: this is just my local tree, if anything
goes wrong  I just don't push or "reset --hard origin/stable".
so I'd do:
git branch foo-stable foo # Create a branch for the backport
git rebase --onto stable master foo-stable # Backport

Now you got your backported version and can merge it to "stable".
The annoying thing is that merge step. I can create a merge
commit if I mistype things, and I do not want any
merge commits, I want to create linear history.
Common wisdom is do things the other way around though. Create the
bugfix for the oldest branch that it applies to, then merge it forward,
either doing:

"bugfix -> stable" and "stable -> master" merges, or
"bugfix -> stable" and "bugfix -> master" merges.

That approach has the advantage that you don't get multiple commits
doing the same thing, which you get with rebasing/cherry-picking.

IIRC the gitworkflows manpage describe that in some more detail.

I know. The advantage of making all changes to master first
is that this way a change gets more review and testing before
being applied to stable. Further, often different people
maintain master and stable branches.
quoted
-	Imagine developing a bugfix/feature patchset on master branch.
	Then I decide the patchset is too large/unsafe and want to
	switch it to staging branch.
Hm, so you have a topic branch "foo" based upon master, but it's too
experimental so you don't want to merge it to master, but "staging". I
don't see why you even have to rebase it then. "staging" is likely ahead
of master, so the merge base of "foo" and "master" is also reachable
through "staging", and simply merging "foo" to "staging" should work
without any ill-effects.
Yes but I want my development history to be linear,
so that format patch rebase -i etc work well.
quoted
-	I have a large queue of patches on staging branch, I decide that
	a range of patches is mature enough for master.
Basically, same deal as with the first two cases. If the series is
directly on "staging" (i.e. you didn't create a topic branch), you can
create one now:
git branch foo $last_commit_for_foo
git rebase --onto master $first_commit_for_foo^ foo

And you got your backported topic branch for "foo".

Or you already have a topic branch "foo-staging", but it's based upon
some commit only in "staging" but not in "master", so a plain merge
would mess things up. Same deal as with backporting from "master" to
"stable"
Yes, I understand that creating a temporary branch and checking it out
then merging it will make rebase do what I want.
The only disadvantage is that I need to remember where I am in the
process, while an "atomic" command does this for me.
And in this case it's also true that basing the topic branches on
"master" instead of "staging" makes things easier. That way, you can
merge to either "staging" or "master" without any ill-effects.

Björn
As above, I do not want merges.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help