views:

230

answers:

2

I'd like to be able to manage my app dependencies in Mercurial such that inside my app I have a fork/clone of the dependency repository. I'd like to make and commit changes to the dependency repository inside the app, but still pull and merge changes from the dependency's primary repository. Pushing my app should push the dependency repository with it, but the dependency files shouldn't be "tracked" by the app repository. Is this possible?

The directory structure:

-- app
   -- .hg
   -- dependency
      -- .hg

When I commit to the app repository, it's OK but not preferable to commit any changes in the dependency repository.

When I push my app repository, it's NOT OK to try to push the dependency repository.

The session below explores the isssue trying to use subrepos. The scenario emulates one where the app and lib are on a hosted repository like Google Code. I have also tried unsuccessfully to tell Mercurial to ignore the subrepository.

# Make library on Google Code
mkdir libOnGCode
cd libOnGCode/
hg init
echo "this library is really complex" > libfile
hg add
hg ci -m "I'm so awesome..."
cd ..

# Make app on Google Code
mkdir appOnGCode
cd appOnGCode/
hg init
echo "my base app" > appfile
hg add
hg ci -m "Initial app commit"
cd ..

# Bring down local copy of app
hg clone appOnGCode appLocal
cd appLocal
hg clone ../libOnGCode/ lib
# abort: path 'lib/libfile' is inside repo 'lib'
echo "I'm gonna use a library" >> appfile
hg add lib
hg add lib/*
hg ci -m "Added a library"
hg push # It's not tracking lib

echo "Trying subrepos round 1..."
echo lib = lib > .hgsub
hg add .hgsub
hg ci -m "Adding subrepo"
# committing subrepository lib
hg push
# pushing to /workingdir/appOnGCode
# pushing subrepo lib
# abort: repository /workingdir/appOnGCode/lib not found!

echo "Trying subrepos round 2..."
echo lib = ../libOnGCode > .hgsub
hg ci -m "Adding subrepo"
hg push
# Cool, the subrepo worked, pulling app pulls lib
cd lib
echo "My addition to the lib" >> libfile
hg ci -m "Adding extra functionality"
cd ..
hg push
cd ../libOnGCode
hg update
echo "Argh, it updated the lib on google code"
echo "If I didn't have permission to push on the lib repo, pushing the app would fail"
cat libfile
echo "Removing those changes"
hg backout -m "Removing those changes" tip
cd ../appLocal/lib/
hg pull -u
echo "Trying to add extra functionality again" >> libfile
hg ci -m "Trying again"
cd .hg/
echo "Removing hgrc, which only has path info"
rm hgrc
cd ../../
hg push
cd ../appOnGCode
hg update
cat lib/libfile
# Tears hair out

PS. If anyone can fix the formatting on that I'd be grateful.

A: 

Instead of cloning the libOnGCode repo locally, can you first clone it into the hosted appOnGCode repo and add it as a subrepo there? Then when you clone the appOnGCode repo, the copy of libOnGCode that you have will have its default path pointing at the appOnGCode/lib repo on Google Code. Basically, this sequence:

hg init libOnGCode
# Do stuff in libOnGCode
hg commit -m "Library is all set up"

hg init appOnGCode
# Do some stuff in appOnGCode
hg clone libOnGCode lib
echo lib = lib > .hgsub
hg add
hg commit -m "App is all set up"

# on your local system...
hg clone /path/to/appOnGCode app
cat app/lib/.hg/hgrc # Shows default is in appOnGCode/lib
# Do some stuff to app and/or lib
hg commit -m "Local stuff"
hg push  # Only goes to /appOnGCode.

If you also need to pull changes from the original libOnGCode repo, you can either pull them into the appOnGCode repo or directly into your local repo; either way, everything should sync up.

Niall C.
I don't think it's possible to clone it into Google Code.
Craig Younkins
A: 

This is the best solution I have found so far: http://rklophaus.com/articles/20100124-SubmodulesAndSubreposDoneRight.html

Rusty Klophaus wrote this small script to rename the .hg directory to .subhg, effectively tricking Mercurial into thinking there isn't a nested repository. The script also proxies hg commands to the real hg, setting the directory to work on as the .subhg, so pretty much everything just works as long as you have his subhg script. You can optionally add the .subhg directory to your .hgignore so you don't pull/push all the subrepository's history.

The downsides of this are that contributors must have subhg to commit to the nested repository. I would love to see this kind of functionality in Mercurial.

Craig Younkins