Change branch name of Revision 0 in Mercurial repo - mercurial

The Mercurial repository has two branches that originate from revision 0. Branch names are 2x and 4x.
Rev. 0 itself belongs to branch 4x.
How can I move Rev. 0 to branch 2x keeping everything else the same?
PS. I assume its is totally possible, since the Rev. 0 does not have any dependencies on previous revisions.
PPS. This situation happend after converting the whole repository from incorrectly organized SVN.

You cannot change a branch name without also changing the changeset hash (ID). Changing a changeset hash will also require a change to all descendant changesets. So it doesn't help that revision 0 doesn't have any ancestor changesets — it's the child changesets that complicate things.
My advice: just leave it as it is. Be sure to read the recommendations on named branches for some good workflow advices.

Related

How to remove a changeset from hg repo without loosing changesets commited after that

I need to remove a changeset say 123b which is somewhere in the middle of several changesets in a branch. I have commited many changesets after 123b. How do I remove the changeset 123b whithout losing recent changes
Say you have changesets:
A-B-C-D-....
(Where your 123b could be represented by, say B here).
If B, C and none of their descendants have been pushed yet (so they only exist in your local repository) then you could first rebase C to A, and then strip B.
Technically, you can't: A changeset includes all of its parent history, so by removing 123b, you destroy all its descendants. Any immediate children are now damaged as they refer to the nonexistent 123b, and any children of those children are indirectly damaged, and so on.
However, there is a bright side. You can replace all of the descendants with new, improved descendants. To do that, use hg histedit. This is a bundled extension that you must enable first. (See, e.g., What are the best and must-have hg / mercurial extensions?) (Alternatively, it's possible to use rebase or graft, but I don't recommend that—histedit is simpler.)
Note that histedit is essentially equivalent to stripping the changeset and all its descendants and then adding new changesets. As such, if you've made the changeset public by sending it to another clone, it will come right back from that other clone later, along with all of its descendants. By default, histedit won't let you edit public changesets, so that you don't make this mistake. See also https://book.mercurial-scm.org/read/changing-history.html.
(There is a better (my opinion) way, but it involves adding a non-bundled extension, specifically the evolve extension. See this answer to a related question. I have not actually used evolve, I just like the theory behind it.)

How to clone from a specific revision to the last one using Mercurial?

In Mercurial , How to clone from a specific revision to the last one using ?
For example repo A have one line history from changeset 0 to changeset 100. and I want to clone A to my local repo from changeset 90 to last one (100).
Looking through the help, I noticed the -r flag but that only clone 1 specific changeset.
And if there is no way to do it can somebody explain why its not implemented ? its considered a bad thing to do ?
Thanks.
You can't.
The current state of the project is all changesets from the beginning of time up until the specific changeset, you cannot prune older changesets without rewriting the history of the repository to permanently get rid of them. This will also make the repository incompatible with the original that contains the old history.
In short, you will have to do one of the following:
Prune the old history, permanently getting rid of it, which will make it impossible to push/pull with original clones that still has that history
Live with the history
The parameters to the clone command that specifies revsets thus only allow you to set an upper limit. This may allow you to avoid whole branches, if they aren't merged into the branch you end up cloning, but the clone command will always clone everything from the beginning of time.
For every changeset you clone, every predecessor will be cloned as well, and this cannot be avoided.

Mercurial - How to pull all revisions on all branches up to a specific point?

I guess I must have misunderstood the author of this post when he said:
hg pull -r X -f repo # ... will give me all changesets up to X
Because when I did that (in a freshly-created repository), I only got those changesets that were ancestors of the branch that revision X is on.
What I wanted was all the changesets that had been committed to the remote repo up to and including X, chronologically. In other words, in addition to the branch that X is on (and its ancestors), I also wanted all other branches (including closed branches) committed before X that hadn't been merged to X's branch.
How would I express the command to do that?
BTW, in this particular repo, there are closed branches that have names that are identical to currently open/active branches, so if the solution involves enumerating all the branch names (which would be tedious, but do-able), it would still need to get the closed occurrences of such branches as well as the open ones.
(For completeness I suppose I should also say that I ran the command from the command-line of TortoiseHG 2.7 on Windows, in case the behavior of hg pull that I've described above isn't what I should have expected.)
You can't do that on pull in a single command. "Chronologically" means a lot less than you think it might. Anyone can do a commit with any timestamp they want, so the dates aren't good selectors. If you mean "with an earlier revision number" those too can change from repo to repo, so pulling all revisions with a revision number lower than N could give different results for different invocations.
If you want to try the revision-number-based version anyway, you'd probably have your best luck pulling everything to a trash repo locally and then pushing only what you want to a new local repository:
hg clone http://remotehost/path local-clone # clones everything
hg init another-local-clone
hg push --repository local-clone --rev '0:X' another-local-clone
after that another-local-clone will have all the changesets whose revision numbers is X or lower in local-clone, which is (but isn't guaranteed to be) the same as the remote clone
If that seems awkward it's because "committed before" isn't a terribly useful concept in DVCS land -- it assumes a linearity that neither git not Mercurial consider important.

Mercurial different heads

we are a team of 3 developers using Mercurial as a SCM tool, and I recently noticed the current heads (revision numbers) are different between the 3 of us, after everybody has pulled the latest changeset from the central repository. I'm at 2483 and the others are at 2482 (numbers are arbitrary, but mine is +1 compared to the others'). Is this something normal? Because it looks to me as a problem.
We've recently worked on a branch, then switched back to the default branch and merged with the branch. The only thing I can think of is that 2 of us did the merge and pushed the merge to the central repository, instead of only one doing the merge, pushing, and the others pulling the merge. Can someone help with an idea, maybe this is normal after all?
Things to look at:
12455:8b908304cb1c is the revision number of my current head. 12455 is a local number, it's only valid for my local repository, it's not global identifier portable between my own repos, or between my repos and my coworkers. 8b908304cb1c on the other hand is a globally usable identifier. 8b908304cb1c locally can be used to refer to the exactly same revision in every repository that contains that commit
hg outgoing will show you what needs to be pushed. hg incoming will show you what you've forgotten to pull.
hg heads --topo will show you the topological, unclosed, heads. This will quickly show you if you've got unmerged changes in a branch, or multiple heads in a single branch.

mercurial team repository / picking and choosing

I have a small team and I would like to do the following:
I have my trunk, I'll just call it TRUNK
Now, TRUNK is a project that's already in production and running. Now, the inevitable defects come in, but into bugzilla and are assigned to users.
Each user clones TRUNK to their local repositories and makes changes and pushes them to a directory TRUNK/projects (projects is not a clone of TRUNK, just a regular directory)
Now, the day comes where I want to create a new build called RELEASE and I want to merge some of the bug fixes (not all, just some) into RELEASE.
Notice, I am not committed to the idea of having TRUNK/projects/[bugfixes list], but that's what I currently have now and am more than open to any / all suggestions.
What are some ideas? Is there something I can do / should do differently? Again, I am open to any / all suggestions, including completely changing the above procedure (except for using Mercurial as that's what the company makes us use)
There are two ways to do this and they diverge not at release time, but when you do the bug fixes depending on what parent you give the bugfix changesets. The "good" way uses only push, pull, and merge. The less good way (it's not entirely bad, but it's certainly sub-optimal) is called cherry picking and it has drawbacks. The tricky part is that whether or not you're going to be able to move bugfixes into RELEASE via merge without moving everything from TRUNK into RELEASE is something you have to decide before you make that change.
Here's a really complete answer for a similar question that explains what's going on: Some help with merging legacy branch in Mercurial
The key concept though, is that you can merge a changeset into any branch you want but it brings with it all of its ancestor changesets. So you want your bug fixed to have minimal ancestry. That means fixing a bug not in a new changeset in TRUNK that happens to be the latest feature you added, but instead, first, hg updateing to a changeset that already exists in both your TRUNK and your RELEASE, and there are two great candidates for that. Either:
the changeset where RELEASE and TRUNK diverged
or
the changeset where the bug was introduced
My preference is for the later. If a bug was introduced in changeset 666 then every clone, branch, and build that has changeset 666 will want your fix. So when fixing it just do:
hg update 666
.. fix the bug ..
hg commit -m "fixed bug 55" # creats changeset 999 which a new head
Then you can do this:
hg update TRUNK
hg merge 999
and you'll know you're only pulling in a single changeset. Later when you're ready to release you can do:
hg update RELEASE
hg merge 999
and you're again only getting the single changeset you want.
The advantage of this mode of working over cherrypicking (using export/import or transplant) is that your fix exists only once in your repo. If you have 99 different vendor branches for various finicky customers and you want to see if they have the fix for bug 55 you can just do:
hg log -r 'descendants(999) and heads(FUSSYCUSTOMERBRANCHNAME)'
and if there are no results then that customer doesn't have 999 and thus doesn't have the fix for bug 55 in changeset 666. When you re-do the same work with multiple changesets (which is the result of export/import and transplant) that's harder to verify.
Common practice is to create topic branches.
Each new issue/ticket/enhancement is commited into separate branch.
Anytime maintainer wants to make new release he can merge all (or only some) that branches into "default" or even new branch called e.g. "release_1_x".
To be more precise. Developer working on code can still clone repository, then create local branch and finally, after one or more commits to that branch, pushes local changes to one centralized clone (from which every other developer in team can pull/clone again).