Can I make an older revision the tip and push (using Mercurial)?
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 wan开发者_JS百科t 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")
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.
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.
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.
精彩评论