# How to do a reverse rebase?

5 messages from 2007-08-20 to 2007-08-20. Participants: linux@horizon.com, Shawn O. Pearce, Junio C Hamano, Johannes Sixt.
Thread: https://gitlist.dev/t/9584

## linux@horizon.com, 2007-08-20 05:32

Subject: How to do a reverse rebase?
Message-ID: <20070820053237.9349.qmail@science.horizon.com>
URL: https://gitlist.dev/e/20070820053237.9349.qmail%40science.horizon.com

```
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, 2007-08-20 05:58

Subject: Re: How to do a reverse rebase?
Message-ID: <20070820055809.GZ27913@spearce.org>
URL: https://gitlist.dev/e/20070820055809.GZ27913%40spearce.org
In-Reply-To: <20070820053237.9349.qmail@science.horizon.com>

```
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, 2007-08-20 06:33

Subject: Re: How to do a reverse rebase?
Message-ID: <7vr6ly90li.fsf@gitster.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vr6ly90li.fsf%40gitster.siamese.dyndns.org
In-Reply-To: <20070820055809.GZ27913@spearce.org>

```
"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.

```

## Johannes Sixt, 2007-08-20 09:49

Subject: Re: How to do a reverse rebase?
Message-ID: <46C963B7.7ABF2944@eudaptics.com>
URL: https://gitlist.dev/e/46C963B7.7ABF2944%40eudaptics.com
In-Reply-To: <20070820053237.9349.qmail@science.horizon.com>

```
linux@horizon.com wrote:
> 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

```

## linux@horizon.com, 2007-08-20 10:39

Subject: Re: How to do a reverse rebase?
Message-ID: <20070820103943.6046.qmail@science.horizon.com>
URL: https://gitlist.dev/e/20070820103943.6046.qmail%40science.horizon.com
In-Reply-To: <20070820055809.GZ27913@spearce.org>

```
> 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

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

```
