[prev in list] [next in list] [prev in thread] [next in thread] 

List:       mercurial
Subject:    Re: Problem: how move a branch back to a previous revision?
From:       Bram Moolenaar <Bram () Moolenaar ! net>
Date:       2010-05-17 20:09:00
Message-ID: 201005172009.o4HK90Je007844 () masaka ! moolenaar ! net
[Download RAW message or body]


Martin Geisler wrote:

> >> > Now a fix was made in the default branch: "Correct Japanese menus
> >> > to avoid error while loading them after 7.2.432." I wanted to pick
> >> > this up in the vim73 branch with "hg rebase". That's where it went
> >> > wrong.
> >> 
> >> Yeah, you don't "pickup" changes with rebase -- you use rebase to
> >> move local changesets from one point in the graph to another. It's
> >> very important to only move unpublished changesets since others may
> >> have based work on the changesets you rebase.
> >
> > There should be a big warning in the rebase documentation about this.
> > I did have published changesets, I had no idea that made a difference.
> 
> Okay. What do you think of adding this paragraph to the top of 'hg help
> rebase':
> 
> diff --git a/hgext/rebase.py b/hgext/rebase.py
> --- a/hgext/rebase.py
> +++ b/hgext/rebase.py
> @@ -29,9 +29,14 @@
>  
>      Rebase uses repeated merging to graft changesets from one part of
>      history (the source) onto another (the destination). This can be
> -    useful for linearizing local changes relative to a master
> +    useful for linearizing *local* changes relative to a master
>      development tree.
>  
> +    Do not rebase changesets that have already been pulled into other
> +    repositories. Doing so will force everybody else to run the same
> +    rebase or they will end up with duplicated changesets after
> +    pulling in your rebased changesets.
> +
>      If you don't specify a destination changeset (``-d/--dest``),
>      rebase uses the tipmost head of the current named branch as the
>      destination. (The destination changeset is not modified by
> 
> Is it clear enough? I want to somehow briefly explain the consequence of
> rebasing public changesets. I hate it when software say "don't do this
> or bad things will happen" without being specific about the bad things.

Works for me.  Thanks for looking into this.


> >> The way to do this is merge: in your case you want to make the vim73
> >> branch a superset of the default branch. By this I mean that you want
> >> to merge default into vim73 whenever default is changed. What way you
> >> will propagate all the bugfixes from the default (stable) branch into
> >> your vim73 (development) branch.
> >
> > OK.  So how?  I know export in the default branch + import in the vim73
> > branch works.  But it's a bit clumsy.
> 
> Right, I see what you mean. Luckily that's not the way to do it :-)
> 
> I think you have a slightly incorrect view of how branches work. You do
> not need to duplicate the changes with export and import in order to get
> the changes from the default branch "into" the vim73 branch. You only
> have to merge the two branches.
> 
> When you merge (with or without named branches), you ask Mercurial to
> combine two revisions. So let's say you have a graph like this:
> 
>   [d1] --- [d2] --- [d3]
>                \
>                 [v1] --- [v2] --- [v3]
> 
> where the d* changesets are "on" the default branch and the v*
> changesets are on the vim73 branch, which you started at changeset d2.
> You have now made a critical bugfix (d3) which you need to propagate to
> the vim73 branch. The way to do this is
> 
>   hg update vim73 # if you're not already there
>   hg merge default
>   # check the merge
>   hg commit -m 'Merged bugfix from default.'
> 
> The 'hg merge default' is just a shorthand for 'hg merge d3' since d3 is
> the tip-most changeset on default.

Yes, I understand.  So what happened for me is that the "default" branch
got messed up by the badly used rebase an I had to add another change to
undo that.  So now I have:

    [d1] --- [d2] --- [d3] --- [XXX] --- [YYY] --- [d4]
                 \
                  [v1] --- [v2] --- [v3]

Where XXX is the broken change and YYY undoing it.

Now I cannot merge, because I don't want XXX and YYY in the other
branch, it undoes the first few changes there.

I actually tried the "hg merge default" command, and it resulted in
several "vim73" changes to be undone (e.g., the version number went back
from 7.3a to 7.2).  So that doesn't work now.  Fortunately I could
revert this without side effects.

> When merging, Mercurial finds the common ancestor point for each file
> and applies the missing changes to the file. Since you are in v3, the
> ancestor point is d2, and the missing changes will be the changes made
> in d3. Mercurial will merge these changes into your working copy. When
> you commit the graph looks like this:
> 
>   [d1] --- [d2] --- [d3] ----------------\
>                \                          \
>                 [v1] --- [v2] --- [v3] --- [v4]
> 
> The v4 changeset is "on" the vim73 branch since you updated to vim73
> before the merge -- it inherits the branch name from the working copy's
> first parent (the working copy's second parent was d3).
> 
> You are now done -- the changes from default are now also on vim73.
> 
> When more bugs are fixed on default, d3 will be the new common ancestor
> point. So when d4 is to be merged into v4:
> 
>   [d1] --- [d2] --- [d3] ----------------\---- [d4]
>                \                          \
>                 [v1] --- [v2] --- [v3] --- [v4]
> 
> then Mercurial will see that it only needs to apply the change in d4 and
> you'll get:
> 
>   [d1] --- [d2] --- [d3] ----------------\---- [d4]
>                \                          \        \
>                 [v1] --- [v2] --- [v3] --- [v4] --- [v5]

Thanks for the very clear explanation.  Please make this publicly
available, it will help many others.

> You could do all this without the use of named branches. Named branches
> are only a way to label changesets with a particular name. You can then
> use the name in all contexts that expect a changeset identifier -- the
> name will simply resolve into the tip-most changeset with that label.

But I want users who check out the normal version to get the "default"
branch, not the latest patch that might be in the unstable branch.

> That is why I put "into" and "on" in quotes -- a named branch is not a
> container into which you can move changesets, it is simply a subset of
> the changesets that all have the same label. You can also not move a
> changeset out of a named branch since the label is an integral part of
> the changeset.
> 
> So when you merge default into vim73, the two branch names are turned
> into changeset identifiers and all the computations are done using
> those. All that matters is that your working was on vim73 to begin with
> so that the merge changeset is also labelled "vim73".

-- 
Q: Should I clean my house or work on Vim?
A: Whatever contains more bugs.

 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\        download, build and distribute -- http://www.A-A-P.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///
_______________________________________________
Mercurial mailing list
Mercurial@selenic.com
http://selenic.com/mailman/listinfo/mercurial
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic