When are Mercurial bookmarks pushed/pulled implicitly? - mercurial

Short of explicitly pushing/pulling an individual bookmark, when do bookmarks get copied/updated from repo to repo?
In my testing with two local repos, I couldn't deduce a consistent behavior. Sometimes a push/pull from A to B or B to A would copy/update the bookmarks, sometimes it wouldn't. In some cases, a bookmark gets copied even if the dest repo doesn't already have a bookmark of that name. In other cases, the bookmark is not copied even though the dest does have a bookmark of that name but pointing to a different changeset. This does not jive with the explanation given at https://www.mercurial-scm.org/wiki/Bookmarks.
When does the # renaming enter the picture?

The explanation given at...
States conditions in short pure English, AFAICS
When you clone a repository
When present on both the local and the remote repositories

Related

How to properly use hg share extension?

Say I have cloned a repo to a directory called ~/trunk and I want to share a branch named my-new-branch to the directory ~/my-new-branch. How would I do that with the hg share extension?
This is what I've been doing:
cd ~
hg share trunk my-new-branch
But then when I cd into the new directory I have to hg up to the branch?
Confused.
IMO share is a very useful command which has some great advantages over clone in some cases. But I think it is unfortunately overlooked in many instances.
What share does is to re-use the 'store' of Mercurial version control information between more than one local repository. (It has nothing directly to do with branching.)
The 'store' is a bunch of files which represents all the history Mercurial saves for you. You don't interact with it directly. Its a black box 99.99% of the time.
share differs from the more commonly-used clone command in that clone would copy the information store, taking longer to run and using potentially a lot more disk space.
The "side effect" of using share rather than clone is that you will instantly see all the same commits in every shared repository. It is as if push/pull were to happen automatically among all the shared repos. This would not be true with clone, you'd have to explicitly push/pull first. This is quite useful but something to be mindful of in your workflow because it may surprise you the first time you use it if you are only used to clone.
If you want to work in multiple branches (named or unnamed) of your project simultaneously,
either clone or share will work fine. One you have created the second repository, yes you need to update it to whatever changeset you want to begin working on.
Concrete example using share:
hg clone path\to\source\repo working1 # Create local repo working1 cloned from somewhere
cd working1
hg up branchname1
cd ..
hg share working1 working2 # shares the 'store' already used for working1 with working2
cd working2
hg up branchname2 # some other branch or point to start working from
As soon as you commit something in working1 that commit will be visible in the history of working2. But since they are not on the same branch this has no real immediate effect on working2.
working2 will retain path\to\source\repo as its default push/pull location, just like working1.
My own practice has been to create numerous locally shared repositories (quick, easy, saves space) and work in various branches. Often I'll even have a few of them on the same named branch but set to different points in history, for various reasons. I no longer find much need to actually clone locally (on the same PC).
A caveat -- I would avoid using share across a network connection - like to a repo on a mapped network drive. I think that could suffer some performance or even reliability issues. In fact, I wouldn't work off a network drive with a Mercurial repo (if avoidable) in any circumstance. Cloning locally would be safer.
Secondly -- I would read the docs, there are a few weird scenarios you might encounter; but I think these are not likely just based on my own experience.
Final note: although share is implemented as an "extension" to Mercurial, it has been effectively a part of it since forever. So there is nothing new or experimental about it, don't let the "extension" deal put you off.

Mercurial: how do I create a new repository containing a subrange of revisions from an existing repo?

I have a repo with subrepos, with a long history. At some point the main subrepo became fully self-contained (doesn't depend on other sister subrepos).
I don't care anymore about the history of the whole thing before the main subrepo became self-contained. So I want to start a new repo that contains just what the subrepo has in it from that moment on. If possible, please describe in terms of TortoiseHg commands.
You probably want to make use of mercurial's convert extension. You can specify revisions to be converted, paths, branches and files to include or exclude in the newly-created repository.
hg convert from-path new-repo
Convert is a default extension which just needs activation.
You might be able to weed out any other changesets you don't need by using the hg strip command.
It will entirely remove changesets (and their ancestors) from a repository. Most likely you would want to make a fresh clone and then work on stripping it down.
One potential pitfall is that the final stripped repo would still have shared parentage with the original; therefore the potential exists for someone to accidentally pull down again changesets which were stripped.
The hg convert command (noted in another answer) does not have this downside.

Rename a local-only mercurial branch?

I find a lot of questions about renaming hg branches that have already been pushed/pulled by other people, but I've got a situation here where work has been done on a set of branhces (10 in total) that all have the "wrong" name - wrong in the sense that the repo (on bitbucket.org) has restrictions on the naming of branches.
Any developer can open a new branch named app-feature-xxxx (where xxxx can be anything), but a boatload of work has been done by a new dev, and none of the branches follow this naming pattern (the branches are effectively the xxxx part without the app-feature- prefix)
Currently these branches are known only on his machine - they've never been pushed to BitBucket.org, nor pulled by anyone else
Can they be renamed in-situ, before they're pushed? Right now hg is attempting to commit his history to BitBucket with these branch names and it's failing. If the branches can be renamed before that happens, everything should be golden.. And there aren't the usual "but what about everyone else's history?" problems, because only one person has these commits..
The easiest I've been able to come up with right now is to clone the repo again, just make one app-feature-lotsofupdates branch, and then keep switching working copy in the original repo, and use a diff tool to apply the code from the original repo (with the wrong names) to this newly cloned repo, committing after every diff/copy - effectively a manual merge of all the various features into one branch (that will then be merged into production)
You can do this using the convert extension to Mercurial, and the branchmap option.
The branchmap is a file that allows you to rename a branch when it is
being brought in from whatever external repository. When used in
conjunction with a splicemap, it allows for a powerful combination to
help fix even the most badly mismanaged repositories and turn them
into nicely structured Mercurial repositories. The branchmap contains
lines of the form
original_branch_name new_branch_name
original_branch_name is the name
of the branch in the source repository, and new_branch_name is the
name of the branch is the destination repository.
The command line to do this would be something like:
hg convert --branchmap branchmap.txt path\to\source\repo path\to\converted\repo
Documentation.

Remove branches in Mercurial but keep changes?

I just found out that we're not supposed to create named branches in our local Mercurial repos, because they get carried along and pushed to the upstream repo, where they live forever.
Unfortunately, I already have multiple feature branches in my local repo, which I was all set to merge to default and push up to the main repo. So, what I need to do is keep the work in these branches (somehow) but remove the named branches.
Is there a way to do this, short of a lot of horrible manual revert/cut/paste?
Using TortoiseHg:
(Ensure rebase extension is enabled in File -> Settings -> Extensions)
Update to parent of the first change set of the named branch.
Right click on the first change set of the nambed branch and click rebase.
Ensure "Keep orignal branch names (--keepbranches)" is NOT checked.
Ensure "Rebase entire source branch (-b/--base)" is checked.
Click rebase.
Another approach would be to use the hg convert command (a standard extension) and the branchmap option.
For a private repository or at least one with changesets which have not been published this would work fine, even though like a rebase it would modify history.
An advantage as opposed to using rebase is that it could be used to deal with multiple branches (named or unnamed) all at once. That might be quicker / easier if there was a lot of things to move around.
A secondary plus is that since convert will create a NEW repository there is no risk to the original if something doesn't work as expected. (Of course when using rebase you could make a backup first which I think is a reasonable precaution.)

Merge a mercurial repository into a subdirectory of another one

I need to merge the all new changesets of a mercurial repository (lets call it A) into a subdirectory of another mercurial repository (lets call it B) on a regular basis. This means, just copying all files is not an option, as the files in B may also be changed and a proper merge must be done.
The only thing I've found to far is http://hgtip.com/tips/advanced/2009-11-17-combining-repositories/, which is about combining repositories, and not really merging over and over again including changesets.
Any ideas? Thanks in advance.
This sounds like a case where you want to make use of sub-repositories: Including repository A as a sub-repository into the parent repository B.
Let's assume, that everything of A is found in the path B/A.
That way, you would have locally your repository B and inside it another repository. You can then go to repository A, pull from the other repository A' and do the merge however you see fit. Then go back to parent level, to repository B. Update the tracked status of A and that's it. If you want to make any local changes which affect both, A and B, use the recursive hg commit --subrepos. See https://www.mercurial-scm.org/wiki/Subrepository for a more verbose description.
Mind however, that sub-repositories are a feature of last resort; that means it has some rough edges. One of them is that it's virtually impossible to undo the entanglement of the two repositories.
Maybe similar features like Guest Repositories, HG Nested or Forest Extensions are better suited for your actual use case.