Mercurial - hg update to a specific date on a named branch - date

I'm am currently working on a project which has several mercurial repositories. Each mercurial repository contains the source code for either a library or a binary, all of which are being actively developed.
You can imagine that compatability between products created from each repository can quickly become a problem. One way to relieve this problem is to update each local repository to be on compatible branches and then update to a particular date on these branches - with the view that at any point in time the branches were compatible.
On a named branch, say V0.X, at V0.1 tag
hg identify
gives
934ad264137e (V0.X) V0.1
Then update to a particular date ( I still want to stay on the V0.X branch )
hg update -d "<10/28/11"
now identify
hg identify; hg branch
gives
51a072771de7 tip
default
Does anyone know how to update along a named branch to a date without the danger of jumping off to another branch?
Any help would be appreciated.
Jon.

hg help revset
"branch(string or set)"
All changesets belonging to the given branch or the branches of the
given changesets.
...
"date(interval)"
Changesets within the interval, see "hg help dates".
give us workflow like
hg log -r "branch('V0.X') and sort(date('<10/28/11'), date)"
find revision N in list
hg update -r N

Related

Created a named branch from the wrong parent

I am stuck in a scenario in which I have created a branch on Mercurial Workbench from a wrong parent branch. In other words I had to create a feature branch from parent : xxx and I have created it from parent : yyy.
Please note that I have also committed the changes, Is there any way I can either redirect my feature branch to xxx or I can delete the branch and re-create it with the same name (please note that having the same name is important) but this time I can create it from xxx.
I have exported the patches of my commits so after creating a branch even if my commits are lost I can import the patches again.
If you needed to change the branch name you would want hg graft (see Graft vs. Transplant). But since you don't want to change the name, you only want to redo the base of the commits, you want hg rebase.
See Hg: How to do a rebase like git's rebase and also In Mercurial what's the difference between hg graft and hg rebase. Note that rebase is an extension, but is a bundled one: you merely need to enable it.

Merging two mercurcial repositories of the same project

I have an old mercurial repository for a project that has the changes before a certain date, and I have another repository for the same project with all the changes after that date.
I want to merge these two repositories so the history reflects that the first commit in the latter repository is the child of the last commit in the former repository.
Is this possible? Or do I just have to merge both heads?
Reading here:
http://blog.experimentalworks.net/2009/03/merge-vs-rebase-a-deep-dive-into-the-mysteries-of-revision-control/
and here:
https://www.mercurial-scm.org/wiki/RebaseExtension
I looks like what I am wanting to accomplish can be done with a rebase, with some caveats.
I pull the changes from the newer repo into the older repo. This results in two heads since both repos only have the 'default' branch. In the older repo folder, I ran:
hg pull -f ../newer-repo
Then I have to use hg phases to make the pulled changes malleable. Normally, this is a bad idea, but since I know I am the only developer on this project, I can do this safely.
hg phase -f -d -r 15 16 ...
Finally, I can now rebase because the history pulled in from the newer repo begins with the same state as the last changelist in the old repo.
hg rebase -s 15 -d 14
I have a single history and no conflicts.
This probably wont work for everyone, but in this narrow circumstance, this was exactly what was needed.

Move a specific branch to new repository

I have a mercurial repository in which I had created a branch 7-8 months back. And now this branch is the one in which I do most of the development and I don't have anything fruitful in default branch and other branches that I have.
I want to create a new repository that represent only this branch. i.e. I want to move this branch to a new repository with history.
I tried to use HG convert tool with following syntax:
hg convert --filemap ~filemap.txt --branchmap branchmap.txt --source-type hg --dest-type hg "E:\MyStuff\Dev\MyOldRepo" "E:\NewRepo"
File map I have defined all my file that I want to include. In branchmap file i had defined
MyOldNamedBranch default
Convert tool do rename MyOldNamedBranch to default but it also brings the changesets from other branch that I don't need.
I also tried to set the following in setting file but no results:
[convert]
hg.usebranchnames=0
hg.startrev=5262
Please suggest how I can move a branch to new repository with history and leaving other branches behind.
I have set the start revision number in command only and it worked.
hg convert --config convert.hg.startrev=5262 --branchmap branchmap.txt "E:\MyStuff\Dev\MyOldRepo" "E:\NewRepo"
And it worked like a charm.
Try this:
Clone only the branch you need:
hg clone E:\MyStuff\Dev\MyOldRepo -b MyOldNamedBranch .\NewRepo
Then inside the NewRepo, convert all the changesets to the draft phase:
hg phase -r 0 -d -f
Then update to the patent of MyOldBranch (I assume, that the parent is in the default branch)
hg update -r "parents(min(branch(MyOldBranch)))"
Then rebase MyOldBranch on the exactly the same changeset.
hg rebase -s "min(branch(MyOldBranch))" -d .
Do exactly the same with the rest of the branches.
To be honest I'm not sure if this is the best method but it worked for me.

Mercurial: Merging from unknown divergant 'branch'

I'm trying to do some work on a project called NS-3, but my problem isn't project specific so I thought I'd ask here as well as the relevant mailing list.
Basically, a copy of the then current project code was made, and a fresh repo made of that code. Work was done on both the 'forked' version and the trunk.
So cloned the forked source, cd in, and hg pull <latest-dev>, hg merge, and while it wasn't a perfect merge, the changes that were unmergable were all related to one library change, so easily fixed (in theory). Naturally this optimistic attempt failed to build.
Now I'm not entirely sure where to go from here, I'm new to DCVS so please; ideas directed towards a 5 year old!
How can I find out which changeset of the forked version was last merged against the dev-trunk since they're separate but related repos?
The Case Where You Started With a Copy Not a Clone:
If this is what happened:
Project Exists
Copy (not clone) of project is made
hg init is run in each separate copy, creating two unrelated repositories
work is done in both copies
Then to merge them you want to do this in the newest of the two unrelated repos:
hg update 0, which jumps the repository back to its earliest point -- the point where it last looked identical to the other
copy in the contents of the working directory from the other repository
hg commit, which creates a new head
hg merge, which merges the two heads and also provides a base revision, which helps the merge process.
The key is getting a base revision involved if possible. What DVCS systems bring to the table that CVS and SVN don't is that every merge is a 3-way merge between two heads and the most recent common ancestor. Faking that common ancestor by creating the new head off the last point the two repos looked the same (revision 0 in the copy) simulates a base revision.
The Case Where You Started With a Clone Not a Copy
This is the classic DVCS case and there shouldn't be much you need to do. Just go into one of the clones, hg pull from the other and fire off the hg merge. If the merge requires input you'll use hg resolve to provide it, and when you're done hg commit.
If at this point your code isn't building/running then you need to just start debugging. Use hg blame to see what was being done near the lines that won't compile and try to suss out what was being done and how to work on it.
The merge process is much easier the more frequently you do it. Pull in up-stream changes daily, not monthly.
You can turn on the GraphLog extension and use the hg log -G command to see the point at which the two lines of development diverged, but in the end merging is development, and you just need to approach a non-building merge like you would any other software defect.

How do I send a patch to another developer and avoid merge conflicts?

How do I get a patch from a commit in order to send it to another developer? And how do I best avoid a merge conflict with this patch when merging our trees at a later date?
If you know how please explain how to do this in your VCS of choice such as subversion, git, Mercurial, bzr or etc.
In git you can pipe the output of git-diff between two commits like this:
git diff fa1afe1 deadbeef > patch.diff
Send the patch.diff to the developer and let him git-apply it to his workspace like this:
git apply patch.diff
If the other developer already has the commits available in his repository he could always pipe it in himself without merging like this:
git apply < git diff fa1afe1 deadbeef
You can then add and commit the changes in the diff the usual way.
Now here comes the interesting part when you have to merge the patch back to the master branch (that is public). Consider the following revision tree where C* is the applied patch from C in the master branch:
A---B---C---D master, public/master
\
E---C*---F feature_foo
You can use git-rebase to update the topic branch (in this example named feature_foo) with it's upstream head. What that means is when you type in the following:
git rebase master feature_foo
Git will rearrange the revision tree like this and will also apply the patch itself:
A---B---C---D master, public/master
\
E*---F* feature_foo
Merging to the upstream branch will now be an easy fast-forward merge. Also check that the new commits E* and F* work as the previous E and F respectively.
You can do the same thing against another developer's branch using the same steps but instead of doing it on a public repo, you'll be fetching revisions from the developer's repository. This way you won't have to ask the other developer for a patch if it is already available from what he published at his repo.
Please note to never rebase a public branch because the command will rewrite git history which is something you don't want to do on branches that people depend on and will create a mess when merging to remote repositories. Also never forget to integrate often so others in your team can take part of your changes.
In SVN you can simply make your changes then before commiting, pipe the output of the svn diff to a file as such
svn diff > mypatch.diff
you can then revert your changes and apply the patch at a later date using
patch -p0 -i mypatch.diff
As always don't blindly apply patches to your code and always inspect them first.
You may also find that the patch will break your source code if the source files have changed significantly enough since the patch was taken.
You also can not guarantee that there will not be merge conflicts when you attempt to check in the code.
Bzr handles sending a "merge directive", meaning it sends the patch for you so that the other party can simply click "OK" to merge and there's less futzing around with patch/apply etc.
just:
$ bzr send -o mycode.patch
In Subversion there is no nice way of doing this. Yes, you can use svn diff + patch but this will only postpone your problems until you are going to merge and by then chances are that you've forgotten about it.
The way you would do it in Subversion would be to create a branch, do the commit on the branch and ask the recipient of the patch to switch to the branch. Then you can merge the branch back to trunk in the usual way.