threads / discuss / 43492

Re: Idea for rebase strategy

Subject: Re: Idea for rebase strategy

## tl;dr

5 messages between Nov 27, 2006 and Nov 27, 2006.

replies: 4people: 3as markdown or json

Johannes Schindelin· Nov 27, 2006, 00:15 UTC · lore

Idea for rebase strategy

Hi,

an idea hit me today: maybe we can make rebase work nicely with merges after all. We could record the original branch point and the new branch point for rebases.

If this information is somehow accessible when doing a merge, git could check if the old branch point is reachable from the current HEAD, but not the new branch point, and if both are the case, rebase the changes since the old branch point on top of the new branch point before trying to merge.

Does this sound too far-fetched?

Ciao, Dscho

Junio C Hamano· Nov 27, 2006, 08:33 UTC · re: Johannes Schindelin · lore
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> an idea hit me today: maybe we can make rebase work nicely with merges 
> after all. We could record the original branch point and the new branch 
> point for rebases.

One case that that would be simple enough, appear often enough in real life, and would be useful in practice is this:

       A---B---C---D---E topic
      /       /
  ---X---o---Y---Z master

After forking 'topic' at 'X' and built two commits A and B, the master has a related change in the area 'topic' works on, and a merge to adjust is made at C. Then it builds two other commits D and E. We should be able to rebase it on top of the master.

If we have a reliable ref-log for 'topic' that should be trivial to do. It will be just the matter of replaying the log on top of master. The ref-log says we committed two after we forked, so we replay them:

       A---B---C---D---E topic
      /       /
  ---X---o---Y---Z master
                  \
                   A'--B'

Then the log says we merged 'Y'. We faithfully replay that, which wuold result in "fast-forward -- nothing special is needed" situation. The remaining log entries would say we have two further commits, so replaying them would result in:

       A---B---C---D---E topic
      /       /
  ---X---o---Y---Z master
                  \
                   A'--B'--C'--D' topic'
Andy Whitcroft· Nov 27, 2006, 09:02 UTC · re: Junio C Hamano · lore
Junio C Hamano wrote:
Show 39 quoted lines
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
>> an idea hit me today: maybe we can make rebase work nicely with merges 
>> after all. We could record the original branch point and the new branch 
>> point for rebases.
> 
> One case that that would be simple enough, appear often enough
> in real life, and would be useful in practice is this:
> 
>        A---B---C---D---E topic
>       /       /
>   ---X---o---Y---Z master
> 
> After forking 'topic' at 'X' and built two commits A and B, the
> master has a related change in the area 'topic' works on, and a
> merge to adjust is made at C.  Then it builds two other commits
> D and E.  We should be able to rebase it on top of the master.
> 
> If we have a reliable ref-log for 'topic' that should be trivial
> to do.  It will be just the matter of replaying the log on top
> of master.  The ref-log says we committed two after we forked,
> so we replay them:
> 
>        A---B---C---D---E topic
>       /       /
>   ---X---o---Y---Z master
>                   \
>                    A'--B'
> 
> Then the log says we merged 'Y'.  We faithfully replay that,
> which wuold result in "fast-forward -- nothing special is
> needed" situation.  The remaining log entries would say we have
> two further commits, so replaying them would result in:
> 
>        A---B---C---D---E topic
>       /       /
>   ---X---o---Y---Z master
>                   \
>                    A'--B'--C'--D' topic'

Interestingly this trivial situation seems to works pretty much as is. A "git rebase --onto master X topic" (at least in my trivial test case) replayed A and B, squashed C as a noop, and copied D and E. I did not need any information from the reflog. Of course the reflog is a good way to find X as its first transaction but I did not need it to drive replay.

Junio C Hamano· Nov 27, 2006, 09:26 UTC · re: Andy Whitcroft · lore
Andy Whitcroft <apw@shadowen.org> writes:
Show 13 quoted lines
>> 
>>        A---B---C---D---E topic
>>       /       /
>>   ---X---o---Y---Z master
>>                   \
>>                    A'--B'--C'--D' topic'
>
> Interestingly this trivial situation seems to works pretty much as is.
> A "git rebase --onto master X topic" (at least in my trivial test case)
> replayed A and B, squashed C as a noop, and copied D and E.  I did not
> need any information from the reflog.  Of course the reflog is a good
> way to find X as its first transaction but I did not need it to drive
> replay.

That is only because the pictures are showing the degenerated case for simplicity, and the defect that the current rebase does not even look at any merges is hidden by the fact that the merge in the example C becomes no-op in the rebased history. C could be somewhere not between X and Z, in which case replaying the merge becomes necessary. Also when following from E to traverse down the history of topic, at point C, you need to tell which of B or Y are on the topic, and that's where you would rely on ref-log.

Johannes Schindelin· Nov 27, 2006, 23:40 UTC · re: Junio C Hamano · lore
Hi,
On Mon, 27 Nov 2006, Junio C Hamano wrote:
Show 10 quoted lines
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > an idea hit me today: maybe we can make rebase work nicely with merges 
> > after all. We could record the original branch point and the new branch 
> > point for rebases.
> 
> [...]
> 
> If we have a reliable ref-log for 'topic' that should be trivial
> to do.

But of course! Yet another reason to introduce core.disableRefLog, and turn it on by default...

The graceful merging of a rebased branch indeed depends on the local history, i.e. what is stored in the reflog.

Ciao, Dscho

← back to recent threads