How to fix mercurial repository without default branch? - mercurial

I have a mercurial repository with only one main branch, the problem is that is a named branch called xml. Even the revision 0 is of branch "xml".
I think this happened because it was imported from a subversion branch. I have used it after this without problem, but now that I know a little more about mercurial I know that it is bad to have a repository like it.
So here is my question. How can I fix it so it is the default branch and called "default"? And if possible, can all revisions moved to "default" instead of be "xml" branch?
Note: My development team that use this repository is very small (2) so it isn't a problem if it is needed to re-clone or edit the history somehow.
Edit: I can only think in make a new branch named "default" from the actual tip, but I don't know if I will lose something important that have the really "default" branch. Also I have tried to do a hg checkout default but it tell that don't exist.

If you really do not mind editing the history, then you can use the convert extension with its --branchmap option, see:
https://www.mercurial-scm.org/wiki/ConvertExtension#A--branchmap
which will allow you to rename the "xml" branch to "default".

It's absolutely okay to just create a new comment on a branch named default. It won't matter at all that it's not a root.

Related

Edit commits in HG repo & mark as "closed"

I'm currently dealing with the fallout from BitBucket dropping HG support. We're going to be giving hg-git a try because, while my preference is self-hosting, my boss isn't quite mad enough at Atlassian to move away from BB yet. Taking this opportunity to clean up our existing HG repo before the conversion to GIT. Have used hg convert to remove some accidentally committed binaries to reduce size, etc.
One thing I've noticed is that we've got about two dozen old branches that are technically "open", but have been merged into default (no closing commit, but they're months to years old). Is there any way I can use a tool like hg histedit or during the hg convert to go back and specifically mark old branch heads with --close-branch?
Looking through docs I can find things about editing files, editing the contents of commits, or modifying commit messages, but nothing I can find mentions meta-data around whether a commit is "closed". I know this is just a flag on a given commit, but I don't know how to retroactively add it via any HG extension.
Edit: Just to add a bit more clarity, I recognise I can just update to each of these old branches & add a new commit that just closes the branch. There'll be a lot of dangling-looking, closed heads, but that'd work fine enough. However, I also then have to give each of them a bookmark in HG as well, or these additional "closing" commits are lost in the hg-git conversion. I'd rather avoid having to add ~30 additional branches to the git branch-list, just to have them show up as closed properly in HG without having to use revsets.
What I want to do isn't "essential" in the grand-scheme of the repo, but I'd be surprised if editing a commit's metadata to say --close-branch were impossible.
I tested out the rebase idea with a mock repository and it seemed to work.
Here was the starting repo:
And here was the state after rebase:
I think this example matches what the question was asking about. The original dangling close-branch changeset was moved to precede the merge.
I updated to default and ran the following command:
hg rebase --dest=4 --source=3 --keepbranches --config=ui.merge=internal:merge
I actually used Tortoise Workbench to execute the rebase and that is the command it used. So the final argument for ui.merge is probably not strictly necessary.
As you may have already noticed using hg convert its a really good idea to make new clones when you go to modify the repository. Thus if it gets messed up you have an easy undo option. I'd certainly recommend that approach for this operation as well.

How to revert a file to an earlier version in Mercurial?

I made some changes to a file and committed it. (In fact there were several commits).
Then I wanted to revert to the earlier version and lose all those changes.
I did something like:
hg update -r nnn where nnn was the reversion number of the changeset I wanted to go back to.
That worked. I was happy.
Then, later, I had to push my local repository to the remote. But when I did hg push I got a message about there being two heads on this branch and one of them not being known to the remote repositiory. It suggested I merge before pushing. (I think).
I googled this and found a page that suggested I do "hg merge". I did that. Now the resultant file is back to where I started. I.e. it contains all the changes I wanted to throw away.
Where did i go wrong?
EDIT:
I have found this post Mercurial — revert back to old version and continue from there
where it says:
If later you commit, you will effectively create a new branch. Then
you might continue working only on this branch or eventually merge the
existing one into it.
That sounds like my case. Something went wrong at the merging stage it seems. Was I on the wrong branch when I did "hg merge"?
You're past this point now but if it happens again, and it's just a single file you want to revert then consider:
hg revert --rev REVISION_YOU_LIKED path/to/just/one/file.txt
That doesn't update you whole repository to a different revision, and it doesn't create any commits. It just takes a single file in your working directory and makes it look like it used to. After doing that you can just commit and you're set.
That's not the way to go if you want to undo all the changes you've made to all files, but for reverting a single file use revert and avoid multiple heads and merging entirely.
No, nothing went wrong at the merge stage – Mercurial did exactly what you asked it to...
What merge means is that you take the changes on your current branch, and the changes on the 'other' branch, and you merge them. Since your original changes were in the 'other' branch, Mercurial carefully merged them back into your current branch.
What you needed to do was to discard the 'other' branch. There are various ways of doing that. The Mercurial help pages discuss the various techniques, but there are pointers in other SO questions: see for example Discard a local branch in Mercurial before it is pushed and Remove experimental branch.
(Edit) Afterthought: the reason you got a warning about there being two heads on the branch is because having two heads is often a temporary situation, so pushing them to a remote repository is something you don't want to do accidentally. Resolutions are (i) you did mean to push them, so use --force to create two heads in the remote repository; (ii) ooops!, you meant to merge them before pushing, so do that; or (iii) ooops!, you'd abandoned the 'other' one, so get rid of it. Your case was (iii).

HG: How to push some (but not all) changes to 'stable' branch?

Say I do my new feature development either in default, or an entirely new branch made just for the feature for a web site project. When it comes time to push the feature out to the live website, I want to move it to the live branch, which I then hg archive to my apache directory.
Throughout everything, I want to be absolutely sure not to push other, unrelated changes that are not yet ready to be published to the live branch.
Is this even a good idea? Or should I be doing something entirely different?
If the code is in default, how do I push only the one thing I need and not everything to live? If I push just the latest changeset, is it smart enough to send the latest version of those files, or will it only do the changesets?
If the code is in an entirely new branch, do I merge the whole branch into live? How do I get those changes back to my default branch so I see them there too?
I was reading the "Task Based Management" section of the Mercurial Kick Start guide and it mentions merging default into your branch. I found this very confusing and was wondering why you'd ever do this.
Thanks for any help you guys can provide.
[edit]
I'm using TortoiseHG BTW
[/edit]
HG now has Phases. Change a phase of a changeset to secret and it will not be pushed when you use push. You can do it using TortoiseHG GUI.
In addition to that, be aware that just pushing or pulling something does not automatically change any files in the working directory. It only makes some additional changesets available. Only by using update do you actually change any files in your working dir. (unless you configure hg to update automatically).
In the example you linked, there is a bug fix in the default branch. Bob wants to have this fix in his branch too, so he merges default branch with his branch. This is just an example to see how branching works. You do not have to use it in exactly the same way. If you just begin your Mercurial adventure, then you should better use just one branch until you have a good reason to use more.
For example: 3 developers work on the same project and all of them use just one branch (default). 1 of the developers wants to do a major refactoring of the code. He wants to commit several very unstable changesets (many "in the middle of work"). Doing so in the default branch might upset other developers. That is a good reason to create a branch. After his version is stable enough he will merge his branch into default. While he is doing development in his branch, he wants to be up-to-date with other developers, so he frequently merges default into his branch. Staying in a separate branch for too long might result in difficult merges. Luckily merging is very quick in HG, so merge often.

Mercurial clone cleanup to match upstream

I have a hg clone of a repository into which I have done numerous changes locally over a few months and pushed them to my clone at google code. Unfortunately as a noob I committed a whole bunch of changes on the default branch.
Now I would like to make sure my current default is EXACTLY as upstream and then I can do proper branching off default and only working on the branches..
However how do I do that cleanup though?
For reference my clone is http://code.google.com/r/mosabua-roboguice/source/browse
PS: I got my self into the same problem with git and got that cleaned up: Cleanup git master branch and move some commit to new branch?
First, there's nothing wrong with committing on the default branch. You generally don't want to create a separate named branch for every task in Mercurial, because named branches are forever. You might want to look at the bookmark feature for something closer to git branches ("hg help bookmarks"). So if the only thing wrong with your existing changesets is that they are on the default branch, then there really is nothing wrong with them. Don't worry about it.
However, if you really want to start afresh, the obvious, straightforward thing to do is reclone from upstream. You can keep your messy changesets by moving the existing repo and recloning. Then transplant the changesets from the old repo into the new one on a branch of your choosing.
If you don't want to spend the time/bandwidth for a new clone, you can use the (advanced, dangerous, not for beginners) strip command. First, you have to enable the mq extension (google it or see the manual -- I'm deliberately not explaining it here because it's dangerous). Then run
hg strip 'outgoing("http://upstream/path/to/repo")'
Note that I'm using the revsets feature added in Mercurial 1.7 here. If you're using an older version, there's no easy way to do this.
The best way to do this is with two clones. When working with a remote repo I don't control I always keep a local clone called 'virgin' to which I make no changes. For example:
hg clone -U https://code.google.com/r/mosabua-roboguice-clean/ mosabua-roboguice-clean-virgin
hg clone mosabua-roboguice-clean-virgin mosabua-roboguice-clean-working
Note that because Mercurial uses hard links for local clones and because that first clone was a clone with -U (no working directory (bare repo in git terms)) this takes up no additional disk space.
Work all you want in robo-guice working and pull in robo-guice virgin to see what's going on upstream, and pull again in roboguice-working to get upstream changes.
You can do something like this after the fact by creating a new clone of the remote repo and if diskspace is precious use the relink extension to associate them.
Preface - all history changes have sense only for non-published repos. You'll have to push to GoogleCode's repo from scratch after editing local history (delete repo on GC, create empty, push) - otherwise you'll gust get one more HEAD in default branch
Manfred
Easy (but not short) way - default only+MQ
as Greg mentioned, install MQ
move all your commits into MQ-patches on top of upstream code
leave your changes as pathes forever
check, edit if nesessary and re-integrate patches after each upstream pull (this way your own CG-repo without MQ-patches will become identical to upstream)
More complex - MQ in the middle + separate branches
above
above
create named branch, switch to it
"Finish" patches
Pull upstream, merge with your branch changes (from defaut to yourbranch)
Commit your changes only into yourbranch
Rebasing
Enable rebase extension
Create named branch (with changeset in it? TBT)
Rebase your changesets to the new ancestor, test results
See 5-6 from "More complex" chapter
Perhaps you could try the Convert extension. It can bring a repository in a better shape, while preserving history. Of course, after the modifications have been done, you will have to delete the old repo and upload the converted one.

CCNET Trunk start building because of changes set on branch

I am using CCNET in combination with Mercurial. I have a project that got a branch and a head. they are both configured in CCNET. The branch is running fine, it only start building when there are changes on this branch.
The trunk (called default) starts building every time modifications are checked, because it "sees" the change sets of the branch. It doesnt check them out (good think), but it keeps building every time.
How can I avoid the trunk project seeing the changesets of the branch?
<sourcecontrol type="hg">
<repo>http://repository/hg/hgwebdir.cgi/projectsname/</repo>
<workingDirectory>D:\projects\projectsname</workingDirectory>
<branch>default</branch>
</sourcecontrol>
It sounds like you found a CCNET bug, but in case it's helpful later, if you want CCNET pulling down only a specific named branch you can use this notation for your repo URL:
<repo>http://repository/hg/hgwebdir.cgi/projectsname/#branchname</repo>
Which comes from hg help urls:
An optional identifier after #
indicates a particular branch, tag, or
changeset to use from the remote
repository. See also 'hg help
revisions'.revisions'.
That assumes, of course, that CCNET is using mercurial under the covers, but that's a pretty safe bet.
Doing that will cause your CCNET to only clone down and track changesets with that branch name (which still could include multiple heads).
Hmm I looks like this is a CCNET bug, I added a changeset on the default and now it stopped building every 30 seconds
this bug is currently being worked on
http://groups.google.com/group/ccnet-devel/t/fe3f768a346a3796
so any help with testing is appreciated :-)