My repository has only two branches: default and stable. I made a mess in the stable branch but I have no clue on how to fix it.
The default branch is for new feature
92 is the revision created by the maven-release-plugin.
93 commit on stable
94 merge stable into default
95 to 98 commit on default
99 merge default into stable
100 to 103 commit on stable
104 try to fix the mess with a hg merge -r 98
For default I want the head to be 98. For stable I want to go back to a single head including the commit 94 to 98.
Default's head should be 98; is it not? Run hg heads default to get the list of changesets that are heads on the default branch. From your graph, this is 98 and only 98.
For stable, it sounds like you want to hg merge commits 103 and 104. To do that, update to one of them (hg update 103), then merge the other one in (hg merge 104).
You'll still have to take care of commit 93. Did you want to have it in stable also? Or do you want to not have its effects? If you want to have it in stable, just merge it in also.
If you don't want its effects in stable at all, what you need to do will differ depending that's happened to it. Is it just on your local computer, or have you already pushed it upstream? If it's just on your local computer, running hg strip 93 will remove it from your repository, and it won't get pushed remotely. To do this, you'll have to enable the mq extension.
If you have pushed 93 upstream, you can't strip it. What you can do, however, is make a commit that undoes the effects of 93 by updating to changeset 93, then running hg backout 93. Then, you can merge your new commit into the stable branch, and it will be as though you never committed 93. 93 will be in your history, but its code changes are gone.
Related
Hi im a bit of a newbie on tortoise hg. I made some changes to the code (revision 100 and 101) and realised I dont need them. I therefore "updated" (right click update) to 99 then continued developing. Now I try to commit to the server using the push button and I get the error:
abort: push creates new remote head 66444791e8ed on branch 'Marc-dev'!
hint: merge or see 'hg help push' for details about pushing new heads
How do I solve this? Please make it as easy as possible for me as I dont have a tonne of experience.
thanks
If you don't need the two changesets 100 and 101 and want to get rid of them, you can delete (strip) them from the history. First ensure that the strip extension is activated (File > Settings > Extensions). Now right-click on changeset 100 and select Modify History > Strip from the context menu. The function removes the selected changeset and its children. You can also do this from the terminal with hg strip 100.
With the second head removed, you should now be able to push your changes.
Edit: I just noticed that you probably already pushed the changesets 100/101 to the remote server. In this case you can't simply delete them. Instead, you could backout the redundant changes and rebase your latest changes on top of the initial branch:
It's easier to do this from the command-line:
hg up 101
hg backout 101
hg backout 100
hg rebase -s 102 -d 105
The backout commands creates two additional changesets, probably 104 and 105. rebase moves your two new changesets 102/103 on top of 105. Now you should be able to push.
I'm new to Mercurial, and I made the mistake of making different changes on different systems before the main repository was up to date. (I understand this is what Mercurial is built for, but my thick brain is struggling to resolve the issue.)
Now on my primary development server, everything is up to date and committed. However...
$ hg push
abort: push creates new remote branches: 4f2672f039d7!
(use 'hg push --new-branch' to create new remote branches)
I don't really want a new branch. I just want all the changes to be merged.
$ hg heads
changeset: 459:ff5f94e44aba
branch: 4f2672f039d7
tag: tip
parent: 458:e63d02baf4cf
parent: 455:267abda62069
user: mike#...
date: Tue Sep 13 14:25:16 2011 -0400
summary: Images from prof
changeset: 455:267abda62069
parent: 453:a74757e26357
user: mike#localhost.localdomain
date: Tue Sep 13 09:08:12 2011 -0400
summary: images for FLC
Point me in the right direction?
EDIT: (adding detail)
When I try to merge, I get the following result:
$ hg merge
abort: branch '4f2672f039d7' has one head - please merge with an explicit rev
(run 'hg heads' to see all heads)
I have tried hg merge ff5f94e44aba, and all of the revs listed above, and each one returns the same result:
$ hg merge 267abda62069
abort: merging with a working directory ancestor has no effect
It looks like you've accidentally created a branch with a silly name. What you most likely want to do is reapply your changes with a branch name that makes better sense. There's no totally automatic way of doing this, but you can extract each changeset as a patch, revert to the point where you messed up and reapply those changes on the proper branch.
Basically what you need to do is look at the changelog; probably by running hg out to see what's missing from the central repository. Make a note of each of the revs that you want to keep.
Next update to the last good revision. Make sure that you are on the branch you wanted your commits to be on.
Now you will apply each of the changes you made and commit each one. You can automate this process something like this:
BADREVS="123 124 125 126"
recommit() { hg di -c $1 | patch -p1; hg ci -m "$(hg log -r $1 --template '{desc}')";}
for rev in $BADREVS; do
recommit $rev
done
Now you've got your changes in your local repository twice; once as the commits on the weird branch and again on the right branch. You can push those changes to the central repo using hg push -b GOODBRANCH so that only the changes to the right branch go up; Alternatively, you can install the strip extension to remove the changes you didn't want from the local repo and then you can push as normal.
By the sound of it; you will still have to deal with the changes made to the central repository before you can push, since you pushed changes from another repo. You probably want to do this merging after you clean up the change history in the local repo.
Pull from remote and then update / merge / commit first. Then you won't make new branches.
I've had this happen when I missed a merge. I like the TortoiseHg workbench for this because it can be a little easier to find what you missed through visualization.
A good way to avoid this in the future, how I stopped getting this error, is the fetch extension. Set your post pull to fetch and it will automatically merge for you, which is very nice. If there's a conflict it brings up whatever conflict resolver you use.
I committed a bunch of changesets locally (23-28) and then I realized that I wanted to go back to revision 25, so I ran "hg up -r 25" to go back. Then I started working from there and committed a few changesets. Now I'm ready to push my changes to the server, but when I try to do that it complains with "abort: push creates new remote heads on branch 'default'!". I thought someone else may have committed to the repository so I did a hg pull, but did not get any changes.
Here is the revision tree that I am working with
23
|
24
|
25
/ \
26 29
| |
27 30
| |
28 31
|
32
|
33
|
34
|
35
Is it possible to remove revisions 26,27, and 28? How can I fix things so that I can run "hg push" without errors? Should I have used a different command to go back to revision 25?
Let me just throw in a voice of dissent on Lasse's answer. Mercurial is a system about building an immutable history. Think of a scientist working in his or her lab book on numbered pages in pen. Everything is important, even the stuff you wish you didn't write and don't want at this second. The strip command isn't enabled by default for a reason -- it violates the immutability that is a mercurial goal.
The more "Mercurial" way to address this would be to merge 26 into 35, selecting entirely the options from 35, so you're back down to one head. Then your push will still have only one head, but all of history is preserved.
Alternately you had the option to 'hg push -r 35' which would have given you no warning or error nor required -f because you'd be leaving the repo repo with only one head.
There's nothing wrong with strip, but it's not part of the traditional toolset or mindset in Mercurial.
Well, there's two ways I know of.
Note: Please make a backup, or a clone to experiment on, I do not take responsibility for any lost work
First, if you got MQ extension enabled, you can strip those off. I only know how to do that using TortoiseHg, but I'll find the right commands after posting here.
To do this, you would execute this command:
hg strip 26
Secondly, you can create a new clone locally of only some of the changesets, again I only know how to do that using TortoiseHg.
To do this, you would execute this command:
hg clone SOURCEDIRECTORY CLONEDIRECTORY -r35
Then, from your clone, after verifying that it contains the changesets you want, you push against the target repository.
As for answering what you should've done instead, you could've deleted your original clone and re-cloned from the server to get a clean clone only containing up to changeset 25, but of course you could use the strip command to get rid of the excess changesets then as well.
There's nothing inherently wrong with having multiple heads - Mercurial is just checking it's what you want. In this case, you might want to keep the abandoned development path for future reference. If so, just force the push (with hg -f push) and create the abandoned branch. If you just want to forget everything about it, #Lasse's answer is just fine.
There is a commit that just didn't work, so I want to abandon it without deleting it from history.
I have updated from an earlier revision and committed, thus creating a new head.
I don't have branches, I don't want branches, I just want to simply go on with the new head exactly as it is, nothing fancy, no merge, no worries, just go on forgetting the previous one.
I can't seem to find how to do that, and I'm starting to believe it can't be done. All I find is stuff about branches, or stuff about merging.
Update your repository to the head with the revision that you want to forget about, then use hg commit --close-branch to mark that (anonymous) branch as closed. Then update to the head of the branch that you do want, and continue working.
You can still see the closed branch if you use the -c option to hg heads, but it won't show up by default and hg merge will know not try to merge with the closed head.
You will need to use hg push --force the first time you push this closed head to another repository since you are actually create additional heads in the remote repository when you push. So tell Mercurial that this is okay with --force. People who pull the closed head wont be bothered by any warnings.
I know you don't want to work with branches at this stage, but that's exactly what you've done. When you went back to an earlier version and committed something that worked you created a branch - an unnamed branch, but a branch all the same.
There's no problem with just carrying on just as you are and not worrying about having multiple heads, but if you want to tidy things up so you don't accidentally pick the wrong head one time then you can kill off the old branch.
There's a good section in the Mercurial documentation that takes you through a number of options around Pruning Dead Branches.
I think the best option for you is to mark the old branch as "closed". If your old head is revision "123" then:
hg update -r 123
hg commit --close-branch -m 'Closing old branch'
hg update -C default
First of all, type:
hg heads
Imagine, you have three heads listed:
changeset: 223:d1c3deae6297
user: Your name <your#email.com>
date: Mon Jun 09 02:24:23 2014 +0200
summary: commit description #3
changeset: 123:91c5402959z3
user: Your name <your#email.com>
date: Sat Dec 23 16:05:38 2013 +0200
summary: commit description #2
changeset: 59:81b9804156a8
user: Your name <your#email.com>
date: Sat Sep 14 13:14:40 2013 +0200
summary: commit description #1
Let's say, you want to keep the last head active (223) and close the rest.
You would then do as follows:
Close head #59
hg up -r 59
hg ci --close-branch -m "clean up heads; approach abandoned"
Close head #123
hg up -r 123
hg ci --close-branch -m "clean up heads; approach abandoned"
Commit the changes
hg push
Don't forget to switch to the right head at the end
hg up -r 223
And you're done.
You want to use hg backout. This removes the changes made by the changeset from any child changeset.
Check this out for a good explanation.
Mercurial Backout
An alternative to closing or stripping the unwanted branch would be to merge it in a way that totally discards its effects, but leaves it in history. This approach will allow those unwanted changes to propagate in a push - so only use this if that is the intended effect.
Let's say the changeset history looks like this:
1-2-3-4-5-6
\
7-8-*
and it is 5 and 6 which are no longer wanted.
You can do this:
hg up 8
hg merge -r 6 -t :local
hg commit ...
which will create this:
1-2-3-4-5-6
\ \
7-8-9-*
The update to 8 ensures you are working at the desired head in history, which you want to keep.
The -t :local instructs hg to use the merge "tool" called local which tells it to ignore changes from the other branch, i.e., the one NOT represented by the current working folder state. More info.
Thus the unwanted changes in 5 and 6 are preserved in history but do not affect anything more recent.
Both Niall's and Nick's answers are straight on. Because I find myself creating lots of dangling heads, I ended up writing an alias to close heads more easily. By adding this to your .hgrc:
[alias]
behead = !REV=$($HG id -i); $HG update $# -q && $HG ci --close-branch -m "Closing dead head" && $HG update $REV -q
(if you already have an [alias] section, you can append to it instead)
You can now close a head in one single-command (and without having to update to a different changeset manually) like this:
$ hg behead 123
Note: the alias takes advantage of the fact that Mercurial aliases can be shell commands. This means that this will probably only work on UNIX, not on Windows.
This is a use case for the Evolve extension. It's currently not bundled with Mercurial, so it is technically a third party extension. But it's being used quite heavily by a bunch of people, including Mercurial developers, is being very actively developed, and isn't going anywhere.
With the Evolve extension, you simply do
hg prune -r revname
and get on with your life. The cset will still be there, but obsoleted. It won't be visible unless you pass the --hidden option to Mercurial commands, and by default won't be pushed to remote repositories. Though I think you can force it if you really want to.
If the cset you are pruning has ancestors you want to keep, then you'll have to run hg evolve to rebase those changesets. hg evolve will do so automatically. Otherwise, you don't have to do anything.
You may clone your corrupted repo to a new one without cloning that unwanted head. Then remove old repository, move newly created clone to the original place and continue working with it. This will take some time, but you'll get a perfectly clean repository without a sign of that unwanted revision.
hg clone --rev myGoodResition myDirtyRepo myCleanRepo
I have run into this issue many times when I want to behead a head that was created in error. I always want to see it disappear off the face of the Earth.
On your local copy, get the latest and then:
Find the beginning of a head you want to strip (where a new neck starts to branch off), get the revision number
Strip it.
Source: TipsAndTricks.
Source: PruningDeadBranches#Using_strip.
hg --config extensions.hgext.mq= strip -n <rev>
Make a trivial file update (add a whitespace to a file), commit and push.
Your repo should now have the head stripped. The last step is important as stripping doesn't create any changes you can push to your central repository. Without the last step you only have stripped the head locally.
It seems naming a previously unnamed branch doesn't really work out. It creates a nasty multiple heads problem that I can't find a solution for.
Here is the workflow...
UserA starts working on feature that they expect to be small, so they just start working(off the default branch). The change turns out to be a large project and will need multiple contributors. So UserA issues... hg branch "Feature1" and continues working, committing locally s needed.
UserA then pulls down the changes from the central repo so he can push.
At this point, why does hg heads return 3 heads? It shows 2 for default and 1 for Feature1. The first head for default is the latest change by another user on the branch(irrelevant). The second default head is the commit prior to the hg branch "Feature1" commit.
The central repository has rules enforced so that only 1 head per branch is allowed, so forcing a push isn't an option. The repo doesn't want multiple heads on the default branch.
UserA should be able to push these changes so that other users can see the Feature1 branch and help out. I can't seem to find a way to "correct" this. I don't think I can re-write the branch of the initial commits for the feature, before it was a named branch.
I know the initial changes before the named branch are technically on the default branch, but does that mean they will be heads until that Feature1 branch is merged?
I have found a solution without have to re-clone and merge changes in. I prefer this method mainly for historical purposes as I think it's valuable information on what happened with the feature (aka it started small and then was re-thought to be larger etc..)
In my example, UserA should update to the unwanted head on default and close that branch of default, as it is unwanted. This will leave 2 heads one for default and one for Feature1 as expected.
hg update -r X // X is the rev of the unwanted head.
hg commit --close-branch -m "Moved to Named Branch Feature1, cleaning up initial work"
Then update to the Feature1 branch, push and continue working.
Another workflow is almost the same except the UserA decided to push Feature1 for others to help and default has not been moved forward by anyone else. The local repo only has 2 heads and the user could push, but UserA does NOT want to just push as the tip of default would now be the changeset that really "belongs" to Feature1.
UserA should update to the latest, unwanted changeset of default. Then revert the default back to the revision before UserA starting working.
hg update default
hg revert -r Y // Y is the changeset before UserA started working on the feature
hg commit -m "Reverting changes that now exist in Feature1 branch"
Then update to the Feature1 branch, push and continue working.
The reason you're seeing two heads on the default branch in the local repo is because, after the most recent common ancestor, the changesets in the central repo have nothing in common with the changesets in the local repo.
To solve your problem:
Create a new local clone of the central repo at whatever revision you want (it will probably be easier if you use the most recent common ancestor).
hg clone -r common_ancestor central local2
Export the changes from the first local repo. Note the colon after first_local_change to get all the changes in that repo.
cd local1
hg export -r first_local_change: > ../local1.patch
Go to the new local repository, create the feature branch to import the changes into, then import them:
cd ../local2
hg branch feature
hg import ../local1.patch
hg import has an option to use the branch information in the patch file, but it's disabled by default.
At this point, you can continue using the new local repo in the original one's place. Also, I would double check to make sure that everything is as it should be in the new repo.
We found this to be a very big problem with our team (doing branch-per-feature) and ultimately stopped the hgweb.cgi script working (HTTP 414 Request too Long).
from hg help heads: hg heads with no args will show branch heads, which by definition are changesets that have no children on the same branch. hg heads --topo should give you result you need in this case.
Don't go via the central repository. Just have your developers pull from each other.