= Information for ClearCase/UCM Users = == ClearCase/UCM Concepts == == Syncing with a Mercurial Repository == It's simple enough to have a stream in !ClearCase coexist with a Mercurial repository. All you need is to create a snapshot view on the stream in question. After the files are updated and on a local disk, turn the snapshot view into a Mercurial repository. {{{ hg init hg addremove hg ci -m "Initial checkin" }}} From there you can push the repository anywhere you like. === ClearCase to Hg === As you pick up updates via rebasing in !ClearCase and updating your snapshot view, {{{hg status}}} will tell you what is out of sync with your repository. {{{hg addremove}}} is a wonderful command to keep files in sync with respect to new files and deleted files. === Hg to ClearCase === This is a little tougher. !ClearCase, quite incorrectly, likes to own the mode on files, and keeps them read-only until they're checked-out. To update from Hg, I do the following {{{ # I use cygwin for this on win32 find . -type f | xargs chmod u+w hg pull hg up }}} From !ClearCase's perspective, you've just hijacked some files. If you update from !ClearCase using the gui, it will prompt you to check them out and check them in again. {{{ ct update -graphical }}} To batch process this is more difficult, and that doesn't even cover files being renamed, removed, added, etc. === Another Alternative === If you can live with a one-way push from Mercurial into !ClearCase (i.e. if !ClearCase is your ultimate source of record, but all checkins happen in Mercurial), then you can also make this work with a dynamic view rather than a snapshot view. The trick is to use the {{{clearfsimport}}} command to import your changes from Mercurial to !ClearCase. I've been refining the shell script shown below for a few years now. It's not the prettiest thing in the world, but hopefully it will offer a decent starting point for others in the same boat as me. To push code into !ClearCase takes two steps. First, I clone my working repository into {{{/home/pronovic/mercurial/MyProject}}}. Then, I run the script below. The script takes {{{/home/pronovic/mercurial/MyProject}}} and pushes it into {{{/vobs/ken/MyProject}}}. Mercurial is the source, and the import process adds and removes files as necessary to make the vob target match the Mercurial source. You'll find that {{{clearfsimport}}} is kind of clunky. The arguments are not really "source" and "target". They're more like "source" and "target directory". So, you really tell it: "please import {{{/home/pronovic/mercurial/MyProject}}} into {{{/vobs/ken}}}" and that ends up creating or modifying {{{/vobs/ken/MyProject}}}. -- KennethPronovici {{{ #!/bin/ksh # Sync configuration typeset -x MERCURIALDIR="/home/pronovic/mercurial" typeset -x VOBDIR="/vobs/ken" typeset -x SOURCE="${MERCURIALDIR}/MyProject" typeset -x TARGET="${VOBDIR}/MyProject" typeset -x COMMENT="$1" # Script configuration typeset -x IMPORT="/usr/atria/bin/clearfsimport" typeset -x STANDARD_OPTIONS="-nsetevent -recurse -rmname" typeset -x PREVIEW_OPTION="-preview" # Handle commend line if [[ $# -eq 1 ]] then typeset -x PREVIEW="false" typeset -x COMMENT="$1" typeset -x OPTIONS="$STANDARD_OPTIONS" elif [[ $# -eq 2 ]] then if [[ "$1" != "--preview" ]] then print "Usage: sync-mercurial [--preview] comment" print "Syncs $SOURCE into $VOBDIR" exit 1 fi print "*** Operating in preview mode..." typeset -x PREVIEW="true" typeset -x COMMENT="$2" typeset -x OPTIONS="$STANDARD_OPTIONS $PREVIEW_OPTION" else print "Usage: sync-mercurial [--preview] comment" print "Syncs $SOURCE into $VOBDIR" exit 1 fi # Invoke clearfsimport to get things into ClearCase "$IMPORT" $OPTIONS -c "$COMMENT" "$SOURCE" "$VOBDIR" # Check that the two repositories are indeed equivalent if [[ "$PREVIEW" != "true" ]] then if [[ $(diff -Naur "$SOURCE" "$TARGET" | wc -l) -ne 0 ]] then print "Error: recursive diff yielded inconsistencies between source and target!" print "To compare, use 'diff -Naur $SOURCE $TARGET" fi fi }}}