Can I make an older revision the tip and push (using Mercurial)?
Asked Answered
A

3

10

Say if I have a good revision: 3200. Then I want to test something, and since it has 10 lines of change, and I need to remove a few lines, even though I am still testing I commit first, and after some changes, commit again, and let's say, I did 6 commits.

Now I want to put this on hold, but I don't want to lose all the testing and code written, so I want to

$ hg up -r 3200

which is the good, stable revision I want, and now can I commit and push as the tip? (if possible I want to avoid backing out hg backout because it looks bad somewhat, and I don't want to rollback because rollback has side effect of "if someone pulled from me during this time, the change can somehow get back in the repo")

Ananias answered 22/3, 2011 at 1:40 Comment(5)
Yes, sure. What problem did you have with that?Bismuth
If in doubt, or you just want to cleanly separate your two "branches", you can also keep your aborted working copy as it is now, clone the repo to a new location, update to rev3200 there and commit/push from there.Bismuth
i thought... i cannot either commit or push... when I commit I think it said "nothing to commit"Ananias
I see, you want to commit r3200 unmodified again as r3225. Not sure if that is possible, it does not make too much sense, either. If you want to "hide" r3201..r3224 from other people, you do not have to push them. Just keep them in your local copy, and start a new clone from r3200. (You already pushed them, right?)Bismuth
well, i don't need to hide r3201 to 3224... but just that it is feature not yet finished or in experimental state... so I just want r3200 to be the same as 3225. I can hg push -f (which is to "force" it), but will it affect other people if they push before me or after me, or committed but have not pushed (before my "force push" or after my "force push") and they will push laterAnanias
D
12

Putting things on hold can be done in several ways in Mercurial. The simplest way is to simply not push it anywhere. After you go back in history with

$ hg update 3200

you can use

$ hg push -r .

to push only up to revision 3200. The . is important — it means the working copy parent revision, which in this case is 3200. Revision 3200 wont be "tip" in your local repository since you still have revisions 3201–3206, and the highest numbered revision is always what we call "tip". In other words, the history looks like this:

[3199] -- [3200] -- [3201] ... [3205] -- [3206]
             ^                              ^
            "."                           "tip"

where I've marked the current working copy parent revision and the tip revision.

When you start working based on revision 3200, the graph will change into

[3199] -- [3200] -- [3201] ... [3205] -- [3206]
                \
                 \-------------------------------- [3207]
                                                      ^
                                                  ".", "tip"

Please try not to add too much emphasis on "tip". It changes all the time and is generally not very interesting. If you jump back to 3206 and make a commit, then tip will denote the newly created revision 3208 in your repository. In another repository, tip can be something else, depending on what was pulled from you and when it was pulled.

If you often need to do hg push -r ., then I suggest you create an alias for it. Such an alias would be a gentler push and could therefore be called "nudge":

[alias]
nudge = push -r .

With that in your toolbox, you can always do

$ hg nudge

to send the changesets you've just created up to the server, without worrying about sending up any other branches that you might have put on hold.

Finally, remember that you can use

$ hg update 3206
$ hg commit --close-branch -m "Abandoning this line of development"

to mark the 3206 changeset as "closed". This means that it wont show up in hg heads and it wont be considered for merging when you run hg merge. You will need to use hg push --force if you push it to the server, but and is okay since you're not creating multiple open heads, you just add another closed head.

The trouble with multiple open heads is really that a new hg clone might update to one of them and that would be confusing — people wouldn't know where to start working. With recent versions of Mercurial, hg clone won't update to closed heads so you avoid this problem.

You can re-open a closed head by simply making a child commit based on it. This means that you can close a line of development temporarily with no ill effects, other than a note in the graph saying that the branch was closed at some point.

Devan answered 21/12, 2011 at 23:58 Comment(0)
B
0

From the question and the accompanying comments, it sounds like you want all new changes to be based on 3200, leaving previous work based on 3200 as a separate branch. It's easy to do:

hg up 3200
# work work
hg ci -m "new work based on 3200"

but there isn't any way to mark 3200 as tip, as far as I can tell. Once you commit something based on 3200, that new changeset will be tip, so you could make some benign change and commit that to create the new tip, but that's kind of kludgy. Another option if you are concerned that fellow collaborators won't know to use 3200 as the basis for their work because mercurial won't have it marked as tip is to give it a tag and tell team members to make sure and update their working copy to that tag before beginning their work.

Butters answered 2/4, 2011 at 14:24 Comment(2)
if you add a space somewhere and commit and then push, it will then say there are multiple heads, and you need to merge... I tried merging with the tip and it says no use, and I have to merge with the older revision, and it is back to the newest revision. So I can't commit and push.Ananias
You can do an hg push --new-branch or hg push -f if you know that you want to create a new head. From what you have described, you want a new head.Butters
C
0

krupans answer is of course correct, and he already mentions the problem of having now two head. But I'd like to stress that you will then have two heads of the same branch, and it could be difficult for other people to understand what's going on, and which head to use.

For this reason, it might be beneficial to put your testing code into a new branch, and for that you'll have to rewrite the history. You can do this with the MQ extension (assuming 3201 is the child revision of of rev 3200, and 3206 is the last of your testing commits:

hg qimport -r 3201:3206
hg qpop -a
hg branch branchname
hg qpush -a
hg qfinish -r 3201:3206

Try this out on a clone of your repo!

This should only be done if you haven't already pushed these changes to some other places.

Cellist answered 20/12, 2011 at 8:54 Comment(2)
This is unnecessary. Going back to 3200 and committing does create a new branch, it's just an anonymous branch. Nothing wrong with that. If you're worried about labeling the heads, use bookmarks. No history re-writing required. Doesn't matter if you've pushed your changes or not.Hashimoto
@PaulS that depends on whether you'd rather use named branches or bookmarks. I prefer named branches.Cellist

© 2022 - 2024 — McMap. All rights reserved.