Is it possible to pull from/push to SourceGear Vault repository using Mercurial?
Asked Answered
C

1

7

I noticed that this kind of functionality exists for subversion and it works very nicely. I was wondering if there is such thing for SourceGear Vault.

Cistaceous answered 9/7, 2010 at 4:52 Comment(0)
C
11

Nope, I'm afraid we only have two-way bridges for Subversion and Git. I have not heard of anyone writing a bridge for SourceGear Vault.

However, you can still use Mercurial on top of the other system. This is a general technique that works for all version control systems (VCSs). What you do is the following:

Checkout the latest version of the code from your foreign version control system. Initialize a Mercurial repository, add all files, and make a commit:

# checkout foreign VCS
$ hg init
$ hg addremove
$ hg commit

The working copy is now both a Mercurial working copy as well as a working copy for the foreign system. You will be doing development in Mercurial and periodically import it into the foreign system, and you will periodically import changes from the foreign VCS into Mercurial.

We will use the branch called default to track the history of the foreign system, and a named branch called hg to track the development we do in Mercurial.

Note: Anton comments below that Vault will show too many files if you use named branches to separate the two lines of development — use two clones instead if this is a problem for you.

Let us make the hg branch:

$ hg branch hg
$ hg commit -m "Started hg branch"

You can now develop something:

# work, work, work...
$ hg commit -m 'Fixed bug 42'
# work, hack, work...
$ hg commit -m 'Customers will love this feature!'

As you work along like this, the default branch will begin to diverge from the hg branch -- the difference is exactly the changes that have yet to be exported to the foreign system. You can see the differences with

$ hg diff default:hg

To actually export the changes, you update to the default branch, merge hg into it and commit the change to your foreign system:

$ hg update default
$ hg merge hg
$ hg commit -m 'Merge with hg'
# get list of renamed files:
$ hg status --added --copies --change . | grep -A 1 '^ '
# commit to foreign VCS

You can then update back to the hg branch and continue working with Mercurial

$ hg update hg
# work, work, wok...

When changes are made by others in the foreign VCS, you have to merge them back into your hg branch. You first update to the default branch. This ensures that the working copy looks how the foreign VCS expects it to look like. You can then update the working copy -- this makes Mercurial see changes, which you commit to Mercurial:

$ hg update default
# update working copy using foreign VCS
$ hg addremove --similarity 90
$ hg commit -m 'Imported changes from foreign VCS'

The hg addremove step makes sure that Mercurial picks up any renames that has taken place in the foreign VCS. You will need to experiment with the similarity parameter to find a setting that suits you. Use hg status -C to see the scheduled renames.

You now need to merge these changes back into the hg branch so that you can incorporate them in your further Mercurial-based work:

$ hg update hg
$ hg merge default
$ hg commit -m 'Merge with default'

You continue working like this -- always making new local development on the hg branch, and always updating to the default branch before you use the foreign VCS commands (update, commit, etc).

I hope this guide can help you or someone else! :-)

Candycecandystriped answered 9/7, 2010 at 13:51 Comment(6)
Thank you for the answer. I guess I'll have to find other ways to convince my colleagues to try out mercurial (so that we could all then convince management that we don't like Vault). :/Cistaceous
Paulius: I've added a guide to how you use Mercurial in a hybrid way on top of your existing VCS -- I hope you find it useful.Candycecandystriped
Yeah, looks nice. One thing that bothers me, is that I'd have to manually track down all renames I'd do on hg branch and import them into foreign VCS. Not even sure if Vault could automatically find renames. Anyway, the guide looks good - I'll try it out.Cistaceous
Yes, exporting the renames from Mercurial to Vault is exactly the annoying step in the above recipe. You can ask Mercurial for the list of renamed files: executing something like hg status --added --copies --rev X:Y | grep -A 1 '^ ' does the trick. You can then take it from there either manually moving the files or with further scripting.Candycecandystriped
Good answer, but in the specific case of working with Vault I would suggest one change: Use clones instead of named branches, i.e. keep a pristine "Vault repo", clone it and work in the clone. Although the Vault client (as of 5.1.2) only commits files that have actually changed, it seems to rely purely on timestamps to decide which files to report as having changed, so you can end up with a "Pending Change Set" cluttered with annoying false positives.Liggins
@Anton: Thanks for the comment! I (obviously) don't know anything about Vault, so it's good to get feedback from those who do :) I've put a note about this into the answer.Candycecandystriped

© 2022 - 2024 — McMap. All rights reserved.