mercurialdvcssourcegear-vault

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


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.


Solution

  • 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! :-)