How to use mercurial locally with a central CVS repository? - mercurial

Currently my company is using cvs for version control. I want to use mercurial locally because of it's flexibility and merging capabilities. This will make my job a lot easier.
How should this be done?

First: Get the CVS repository locally.
Second: Create a mercurial repositories locally over this CVS repository. This will be used as your remote mercurial server.
Third: Clone this mercurial repository and do you work here.
Mercurial provides better merge support than cvs and will make your work easier. Commit back to CVS needs an extra step. Here is how this works, step-by-step. The workflow looks complicated, but is actually easy. Keep the flow-charts close.
1) Local CVS repository: Create a local repo with CVS checkout.
2) Remote HG repository: Make a mercurial repo over this CVS repo. (HG init; HG add; HG commit). The repo will be used like a remote mercurial repository. Keep this folder clean and use this only to transfer files from-and-to CVS.
3) Local HG repository: Create a new folder where you will do all your work. (HG clone). Add all CVS files to the hg-ignore-list.
4) Development: Do the work here and ‘hg add/commit’ when needed.
Preparation before pushing your work back to CVS: (step 5-8)
5) CVS update: (local CVS repository = remote HG repository)
CVS update: Update the local CVS repository
hg commit: Commit the CVS updated code in the remote mercurial branch
hg update: Update your working copy to make the CVS changes active.
6) HG pull: Check for changes on your local mercurial repo and pull the changes.
7) HG merge: Merge all CVS changes on your local mercurial repo. Most changes will merge automatically.
8) HG commit: Commit your changes after merge.
Now you are ready to push your work to the remote HG repo and CVS.
9) Local HG push: Push your local work to the remote repo.
10) Remote HG update: Update to let your working copy view the pushed changes.
11) CVS commit: Commit the changes in your remote mercurial repo to CVS with a CVS commit.
2 view on this work:
Step-by-step:
Container view:

Related

Mecurial repository files lost - How do I recreate and push to the original cloned repo?

I just lost my .hg* files for my repository after a migration and I have made a bunch of unpushed changes to some code.
I need to Init a new repository and then push my changes to an existing remote repository. Do I just need to init a new repo and then specify the remote repo in the hgrc and push? Thanks!
If you remember the changeset you had in your original repo as its working parent (let's call it A), then you can do this:
$ hg clone http://server/upstream newrepo
$ cd newrepo
$ hg up A
Then copy the working copy of the original repo to the new repo (with an additional precaution of deleting all files from the new repo if you renamed / deleted anything in the old repo). Afterwards, commit and push from the new repo:
$ hg commit
$ hg push
If the upstream repo has anything on top of A, rebase or merge before pushing.

hg reset local repository to the state of remote one

how can I reset my local repository, to the state of remote one?
I have commited local changes (didn't push).
I want to delete all the differencies.
There are several options:
Make a new clone of the remote repo and throw away the old clone.
Make a new clone of the local repo, but limit it to the last revision in the remote. (e.g. hg clone -r <last remote changeset> <local_repo_old> <local_repo_new>).
Use the hg strip command from the mq extension to remove the changesets from your local repo
NOTE: When trying options 2 or 3, you can use the hg outgoing command to see which changesets have not yet been pushed to the remote repo.

How to apply a collapsed revisions patch to trunk in Mercurial?

I am looking for best practices to do the following:
When I need to implement a feature or fix a bug, I am creating new Mercurial repository from the main one (a trunk).
Then, within some days, or weeks, I am implementing the task in newly created repository, making commits and periodically merging with trunk. After the code in new repository will pass all code reviews, I should provide a repository with all changes collapsed into single revision.
My common way to do this (rdiff extension should be enabled):
hg clone ~/repos/trunk ~/repos/new-collapsed
cd ~/repos/new-collapsed
hg diff ~/repos/new > new.diff
patch -p1 < new.diff
hg commit
This works almost well except when there are binary files present in the changes from ~/repos/new. Another way could be:
hg clone ~/repos/trunk ~/repos/new-collapsed
cd ~/repos/new-collapsed
hg pull ~/repos/new
hg update
hg rollback
then resolve possible conflicts and manually commit the changes
Both ways look for me somewhat ugly and non-native, so I am looking how this operation could be simplified. I've played with rebase extension, but seems its hg rebase --collapse command does not work with workflow described above.
Any ideas are welcome.
Sounds like a good case for mercurial queues.
I do something similar with the histedit extension.
My workflow is something like:
clone a central repo
commit incremental changes to local repo
clone my local repo to make collapsed repo
hg histedit and select/discard/fold the revisions as needed
hg push the collapsed repo to central repo
pull central repo to local or refresh local from scratch
I ensure that my local repo never gets pushed to the central repo by adding an invalid default-push path to the .hg/hgrc file in the local repo root directory.
Solved: Just add
[diff]
git = True
to your hgrc file, and then use my first solution with rdiff extension, replacing patch with hg import:
hg clone ~/repos/trunk ~/repos/new-collapsed
cd ~/repos/new-collapsed
hg diff ~/repos/new > new.diff
hg import new.diff
hg commit

Is there an easy way to clear a mercurial repository of artifacts?

Sometimes I have to return to a really old branch when I depended on a ton of external libraries. Updating to the current branch removes the source files for those dependencies, but the artifacts are left there, as well as a few folders and such.
I would like to have a way to force a mercurial repo to be as if I had just cloned it from the remote (master) repository. I don't want to just nuke my repo and re-clone it, because that forces me to download hundreds of MB from the remote server.
Why don't you clone not from remote server, but from your local repository? After that you could nuke your repo with old untracked files.
hg clone path_to_your_local_repo your_new_repo
After this you could map your new repo to your remote server in hgrc file
You can use the purge extension, or if you are on an UNIX-like system: hg st -nu0 | xargs -0 rm.

Correct command to retrieve remote mercurial updates pushed from my second machine

I'm new to Mercurial.
I initialized a Mercurial project on Machine A, committed my changes and uploaded them to a remote repository.
Then I cloned that repository on Machine B, committed some additional changes and uploaded them to the same remote repository.
In both cases, I uploaded the changes with the same command:
hg push https://username:password#domain/user/repository/
Now I'm back on Machine A and I'm not sure how to update my local repository with the last changes I uploaded to the remote repository from Machine B.
The commands hg clone or hg pull look like they might work but I'm not sure.
Would appreciate any guidance. Thanks.
hg pull will transfer any remote changesets not present in your local repo. Afterwards, you'll need to either hg update or hg merge depending on the presence of local changes.
Use hg pull; pull transfers only changesets which are missing in the existing destination repository.
hg clone creates local copy of a remote repository.
See also this so question.