git/list[1] front-page[2] threads[3] people[4] search[5] about
 

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

From
Björn Steinbrink <b.steinbrink@gmx.de>
Date
Dec 8, 2009, 19:11 UTC
Message-ID
<20091208191107.GA4103@atjola.homenet>
In-Reply-To
<20091208164449.GA32204@redhat.com>
On 2009.12.08 18:44:49 +0200, Michael S. Tsirkin wrote:
Show 32 quoted lines
> 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:
> > > 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:
> > > > > 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.

Show 12 quoted lines
> 
> > 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
Previous: Michael S. TsirkinNext: Michael S. Tsirkin
Message 10 of 43 in “rebase: add --revisions flag”
  1. rebase: add --revisions flagMichael S. Tsirkin, Dec 8, 2009
  2. Björn SteinbrinkDec 8, 2009
  3. Michael S. TsirkinDec 8, 2009
  4. Björn SteinbrinkDec 8, 2009
  5. Michael S. TsirkinDec 8, 2009
  6. Björn SteinbrinkDec 8, 2009
  7. Michael S. TsirkinDec 8, 2009
  8. Björn SteinbrinkDec 8, 2009
  9. Michael S. TsirkinDec 8, 2009
  10. Björn SteinbrinkDec 8, 2009
  11. Michael S. TsirkinDec 8, 2009
  12. Björn SteinbrinkDec 9, 2009
  13. Michael S. TsirkinDec 9, 2009
  14. Miles BaderDec 9, 2009
  15. Junio C HamanoDec 8, 2009
  16. Sverre RabbelierDec 8, 2009
  17. Christian CouderDec 9, 2009
  18. Christian CouderDec 9, 2009
  19. Sverre RabbelierDec 9, 2009
  20. Peter KreftingDec 9, 2009
  21. Michael S. TsirkinDec 9, 2009
  22. Peter KreftingDec 9, 2009
  23. Björn SteinbrinkDec 9, 2009
  24. Andreas SchwabDec 9, 2009
  25. Björn SteinbrinkDec 9, 2009
  26. Michael S. TsirkinDec 9, 2009
  27. Björn SteinbrinkDec 9, 2009
  28. Junio C HamanoDec 9, 2009
  29. Björn SteinbrinkDec 10, 2009
  30. Junio C HamanoDec 10, 2009
  31. Björn SteinbrinkDec 11, 2009
  32. Peter KreftingDec 9, 2009
  33. Björn SteinbrinkDec 9, 2009
  34. Peter KreftingDec 10, 2009
  35. Björn SteinbrinkDec 10, 2009
  36. Michael S. TsirkinDec 9, 2009
  37. Matthieu MoyDec 9, 2009
  38. Matthieu MoyDec 9, 2009
  39. Michael S. TsirkinDec 9, 2009
  40. Björn SteinbrinkDec 9, 2009
  41. Michael S. TsirkinDec 9, 2009
  42. Junio C HamanoDec 9, 2009
  43. David KågedalDec 13, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.