threads / discuss / 9584

How to do a reverse rebase?

Subject: How to do a reverse rebase?

## tl;dr

5 messages between Aug 20, 2007 and Aug 20, 2007.

replies: 4people: 4as markdown or json

linux@horizon.com· Aug 20, 2007, 05:32 UTC · lore

Okay, this is picayune whining, but when you've fixed all the big bugs...

I don't want to rebase HEAD on *that*, but rather rebase *that* on top of the current HEAD.

Sometimes I have a little debug hack on a branch by itself, and I discover that I need it again, so I want to rebase it on top of current development.

But there's been a LOT of development in the meantime.  And if I do
git-rebase HEAD debug_hack

git first checks out debug_hack. This takes a while and, more importantly, every file modified in HEAD...debug_hack has its timestamp touched and make(1) insists on recompiling it.

I want to only modify the three files that are touched on the debug_hack branch, so my recompile times aren't too long.

Currently, when I remember, I'll use git-cherry-pick and manually rename branches.

Is there an easier way?  Or should I just learn StGit?
Shawn O. Pearce· Aug 20, 2007, 05:58 UTC · re: linux@horizon.com · lore

Re: How to do a reverse rebase?

linux@horizon.com wrote:
> I don't want to rebase HEAD on *that*, but rather rebase *that*
> on top of the current HEAD.
...
> Currently, when I remember, I'll use git-cherry-pick and manually
> rename branches.
> 
> Is there an easier way?

I don't think so. To do the merge of those files we need a working directory to operate in; that working directory is the one you have. It sounds like what you want is this:

	old=`git symbolic-ref HEAD` &&
	git checkout HEAD^0 &&
	git cherry-pick debug_hack &&
	git branch -f debug_hack HEAD &&
	git checkout $old

What's really needed is to avoid switching to the branch, as you mentioned. Instead switch to the --onto (implied or given by user). That way you can avoid updating a lot of files in the working directory for no (compelling) reason. Looking at the part of git-rebase.sh that is affected by this (l.284-322) this is probably not that difficult to improve. Just a little bit of work to keep track of everything.

Of course `git-rebase -i` is a completely different implementation, so now you are also talking about l.409-480 of that. Ick.

> Or should I just learn StGit?

Probably. It handles patch stacks easier than core Git. Or so I'm told. I find `git rebase -i` good enough for my needs, but it going first to the debug_hack branch, then to the onto does sort of suck.

-- 
Shawn.
Junio C Hamano· Aug 20, 2007, 06:33 UTC · re: Shawn O. Pearce · lore

Re: How to do a reverse rebase?

"Shawn O. Pearce" <spearce@spearce.org> writes:
>> Is there an easier way?
>
> I don't think so.  To do the merge of those files we need a working
> directory to operate in; that working directory is the one you have.

Actually, if the rebase is really tine compared to the differences between the branches, we _could_ do that without using the real work tree.

Prepare a "for rebase" index, with an empty temporary directory as the work tree, and use the merge machinery to do the necessary per-path and contents merge all inside that temporary directory. As the merge machiery is designed to be usable inside an empty directory and treat "missing" work tree files as if they are unchanged since index, the checkout in this temporary directory would be kept to the minimum.

linux@horizon.com· Aug 20, 2007, 10:39 UTC · re: Shawn O. Pearce · lore

Re: How to do a reverse rebase?

> I don't think so.  To do the merge of those files we need a working
> directory to operate in; that working directory is the one you have.
> It sounds like what you want is this:
Show 5 quoted lines
>	old=`git symbolic-ref HEAD` &&
>	git checkout HEAD^0 &&
>	git cherry-pick debug_hack &&
>	git branch -f debug_hack HEAD &&
>	git checkout $old

Er, actually, I don't want the messing about with $old. At the end of the day, I want to be on the tip of the rebased work.

The problem is that git-cherry-pick only oves a single comit, so if I have a stack, it's annoying.

It's more like:
	git checkout HEAD^0 &&
	for i in `git-rev-list --reverse ..debug_hack`; do
		git-cherry-pick $i
	done &&
	git branch -D debug_hack &&
	git checkout -b debug_hack
Johannes Sixt· Aug 20, 2007, 09:49 UTC · re: linux@horizon.com · lore

Re: How to do a reverse rebase?

linux@horizon.com wrote:
Show 14 quoted lines
> I don't want to rebase HEAD on *that*, but rather rebase *that*
> on top of the current HEAD.
> 
> Sometimes I have a little debug hack on a branch by itself, and I
> discover that I need it again, so I want to rebase it on top of
> current development.
> 
> But there's been a LOT of development in the meantime.  And if I do
> 
> git-rebase HEAD debug_hack
> 
> git first checks out debug_hack.  This takes a while and, more
> importantly, every file modified in HEAD...debug_hack has its timestamp
> touched and make(1) insists on recompiling it.
Heh. For the same reason I also want 'git merge --into that'.

I often hack on a topic branch until it has the right shape. One of the changes touches a central file that triggers a complete recompile.

Now I want to merge the topic into master (which did not change this central file since the merge-base). Currently, I must checkout master, which touches the file, but if there existed 'merge --into' it could get away without touching the file.

-- Hannes

← back to recent threads