Mercurial > hg > hgforest
changeset 38:b29f327bdc10
fix hg fcmd -R toprepo ...
Refactor the code so more commands use a ForestSnapshot instance. The
current directory does not influence their behavior and thus using the
global -R option to specify a toplevel repository other than '.' works.
author | Robin Farine <robin.farine@terminus.org> |
---|---|
date | Fri, 22 Dec 2006 02:14:02 +0100 |
parents | 44e66014dd8d |
children | 62227d7f2d23 |
files | forest.py test-forest test-forest.out |
diffstat | 3 files changed, 106 insertions(+), 78 deletions(-) [+] |
line wrap: on
line diff
--- a/forest.py Thu Dec 21 16:51:24 2006 +0100 +++ b/forest.py Fri Dec 22 02:14:02 2006 +0100 @@ -52,20 +52,14 @@ return res -def enumerate_repos(ui, top='.'): +def enumerate_repos(ui, top): """Generate a lexicographically sorted list of repository roots. - When explicit, top must be a normalized path. + The roots are absolute paths in the filesystem representation. """ - res = util.walkrepos(top) - pfxlen = len(top + os.sep) - res = [p[pfxlen:] for p in res] + res = list(util.walkrepos(top)) res.sort() - # when the prefix is removed from top itself, it yields the empty string; - # let's replace it with '.' - res.remove('') - res.insert(0, '.') return res @@ -159,14 +153,16 @@ self.rootmap[root] = tree self.trees.append(tree) - def __call__(self, ui, toprepo, func, pathalias=None): + def __call__(self, ui, toprepo, func, pathalias=None, mq_check=True): """Apply a function to trees matching a snapshot entry. - Call func(repo, rev, path) for each repo in toprepo and its - nested repositories where repo matches a snapshot entry. + Call func(repo, root, path, rev, mq_applied) for each repo in + toprepo and its nested repositories where repo matches a + snapshot entry. """ repo = None + pfx = toprepo.root for t in self.trees: root, rev, path = t.info(pathalias) ui.write("[%s]\n" % root) @@ -178,18 +174,17 @@ repo = toprepo else: try: - repo = repository(ui, util.localpath(root)) + repo = repository(ui, + os.path.join(pfx, util.localpath(root))) except RepoError: ui.write(_("skipped, no valid repo found\n\n")) continue - if mq_patches_applied(repo.root): - ui.write(_("skipped, mq patches applied\n\n")) - continue - func(repo, path, rev) + func(repo, root, path, rev, + mq_check and mq_patches_applied(repo.root)) ui.write("\n") - def update(self, ui, repo, **opts): + def update(self, ui, repo, mq_fatal, tip=False): """Update a snapshot by scanning a forest. If the ForestSnapshot instance to update was initialized from @@ -201,13 +196,16 @@ rootmap = {} self.trees = [] - for rpath in enumerate_repos(ui): - root = util.pconvert(rpath) - if mq_patches_applied(rpath): + pfxlen = len(repo.root + os.sep) + for rpath in enumerate_repos(ui, repo.root): + root = util.pconvert(rpath[pfxlen:]) + if root == '': + root = '.' + else: + repo = repository(ui, rpath) + if mq_fatal and mq_patches_applied(rpath): raise util.Abort(_("'%s' has mq patches applied") % root) - if rpath != '.': - repo = repository(ui, rpath) - if opts['tip']: + if tip: rev = 'tip' else: rev = node.hex(repo.dirstate.parents()[0]) @@ -233,28 +231,23 @@ def clone(ui, source, dest, **opts): """Clone a local forest.""" - source = os.path.normpath(source) dest = os.path.normpath(dest) - opts['rev'] = [] - roots = [] - for rpath in enumerate_repos(ui, source): - if rpath == '.': - srcpath = source + + def doit(repo, root, path, rev, *unused): + if root == '.': destpath = dest else: - srcpath = os.path.join(source, rpath) - destpath = os.path.join(dest, rpath) - if mq_patches_applied(srcpath): - raise util.Abort( - _("'%s' has mq patches applied") % util.pconvert(rpath)) - roots.append((rpath, srcpath, destpath)) - for root in roots: - destpfx = os.path.dirname(root[2]) - if destpfx and not os.path.exists(destpfx): - os.makedirs(destpfx) - ui.write("[%s]\n" % util.pconvert(root[0])) - commands.clone(ui, root[1], root[2], **opts) - ui.write("\n") + destpath = os.path.join(dest, util.localpath(root)) + destpfx = os.path.dirname(destpath) + if not os.path.exists(destpfx): + os.makedirs(destpfx) + opts['rev'] = [rev] + commands.clone(ui, repo.root, destpath, **opts) + + snapshot = ForestSnapshot() + repo = repository(ui, source) + snapshot.update(ui, repo, True) + snapshot(ui, repo, doit, mq_check=False) def pull(ui, toprepo, snapfile, pathalias, **opts): @@ -271,8 +264,11 @@ opts['force'] = None opts['rev'] = [] - def doit(repo, path, *unused): - commands.pull(repo.ui, repo, path, **opts) + def doit(repo, root, path, rev, mq_applied): + if mq_applied: + ui.write(_("skipped, mq patches applied\n")) + else: + commands.pull(repo.ui, repo, path, **opts) snapshot = ForestSnapshot(snapfile) snapshot(ui, toprepo, doit, pathalias) @@ -292,8 +288,11 @@ opts['force'] = None opts['rev'] = [] - def doit(repo, path, *unused): - commands.push(repo.ui, repo, path, **opts) + def doit(repo, root, path, rev, mq_applied): + if mq_applied: + ui.write(_("skipped, mq patches applied\n")) + else: + commands.push(repo.ui, repo, path, **opts) snapshot = ForestSnapshot(snapfile) snapshot(ui, toprepo, doit, pathalias) @@ -336,30 +335,33 @@ """Generate a new or updated forest snapshot and display it.""" snapshot = ForestSnapshot(snapfile) - snapshot.update(ui, repo, **opts) + snapshot.update(ui, repo, True, **opts) snapshot.write(ui) def status(ui, repo, *pats, **opts): """Display the status of a forest of working directories.""" - for rpath in enumerate_repos(ui): - mqflag = "" - if mq_patches_applied(rpath): - mqflag = " *mq*" - ui.write("[%s]%s\n" % (util.pconvert(rpath), mqflag)) - repo = repository(ui, rpath) + def doit(repo, root, path, rev, mq_applied): + if mq_applied: + ui.write("*mq*\n") commands.status(repo.ui, repo, *pats, **opts) - ui.write("\n") + + snapshot = ForestSnapshot() + snapshot.update(ui, repo, False) + snapshot(ui, repo, doit) -def trees(ui, *unused, **opts): +def trees(ui, repo, **opts): """List the roots of the repositories.""" if opts['convert']: - l = [util.pconvert(p) for p in enumerate_repos(ui)] + pfxlen = len(repo.root + os.sep) + l = [util.pconvert(p[pfxlen:]) for p in enumerate_repos(ui, repo.root)] + l.remove('') + l.insert(0, '.') else: - l = enumerate_repos(ui) + l = enumerate_repos(ui, repo.root) for t in l: ui.write(t + '\n') @@ -378,18 +380,18 @@ if snapfile is not None and tip or snapfile is None and not tip: raise util.Abort(_("need either --tip or SNAPSHOT-FILE")) if tip: - for rpath in enumerate_repos(ui): - repo = repository(ui, rpath) - ui.write("[%s]\n" % util.pconvert(rpath)) - commands.update(repo.ui, repo, node='tip', **opts) - ui.write("\n") + snapshot = ForestSnapshot() + snapshot.update(ui, toprepo, False, True) else: + snapshot = ForestSnapshot(snapfile) - def doit(repo, path, rev): + def doit(repo, root, path, rev, mq_applied): + if mq_applied: + ui.write(_("skipped, mq patches applied\n")) + else: commands.update(repo.ui, repo, node=rev, **opts) - snapshot = ForestSnapshot(snapfile) - snapshot(ui, toprepo, doit) + snapshot(ui, toprepo, doit) def uisetup(ui):
--- a/test-forest Thu Dec 21 16:51:24 2006 +0100 +++ b/test-forest Fri Dec 22 02:14:02 2006 +0100 @@ -49,14 +49,14 @@ hg commit --cwd toplevel/t/t -m "new line" -d "0 0" echo "f2" > toplevel/d/d/f2 hg commit --cwd toplevel/d/d -A -m "new file" -d "0 0" -hg fsnap --cwd toplevel > top-snap2 +hg fsnap -R toplevel > top-snap2 diff -u top-snap1 top-snap2 | \ sed -e 's/--- top-snap1.*$/--- top-snap1/' \ -e 's/+++ top-snap2.*$/+++ top-snap2/' echo "# fupdate" hg fclone toplevel newtop > /dev/null -hg fupdate --cwd newtop ../top-snap > /dev/null +hg fupdate -R newtop top-snap > /dev/null hg parents --cwd newtop/d/d/t hg parents --cwd newtop/t/t hg fupdate --cwd newtop --tip > /dev/null @@ -66,10 +66,10 @@ echo "# fseed" hg clone toplevel newtop -hg fseed --cwd newtop ../top-snap default +hg fseed -R newtop top-snap default rm -rf newtop hg fseed --root newtop top-snap default >/dev/null -hg --cwd newtop fsnap | sed "s@$HGTMP@HGTMP@g" +hg fsnap --cwd newtop | sed "s@$HGTMP@HGTMP@g" rm -rf newtop echo "# fpull" @@ -78,9 +78,9 @@ echo "# fpush" echo "t/t/f" > topcopy/t/t/f hg commit --cwd topcopy/t/t -m "delete new line" -d "0 0" -hg remove --cwd topcopy d/d/f2 -hg commit --cwd topcopy/d/d -m "remove new file" -d "0 0" -hg fpush --cwd topcopy ../top-snap default | sed "s@$HGTMP@HGTMP@g" +hg remove --cwd topcopy/d/d f2 +hg commit -R topcopy -m "remove new file" -d "0 0" +hg fpush -R topcopy top-snap default | sed "s@$HGTMP@HGTMP@g" echo "# fseed and fpull, missing section" cat top-snap | \ @@ -88,14 +88,14 @@ -e '/\[tree2.paths\]/,/^$/ d' > top-snap-missing # with --root hg fseed --root missing top-snap-missing default -hg ftrees --cwd missing +hg ftrees --cwd missing --convert rm -rf missing # without --root hg init missing hg fseed --cwd missing ../top-snap-missing default -hg ftrees --cwd missing +hg ftrees -R missing --convert # pull (should find toplevel changesets) -hg fpull --cwd missing ../top-snap-missing default \ +hg fpull -R missing top-snap-missing default \ | sed "s@$HGTMP@HGTMP@g" rm -rf missing @@ -103,7 +103,7 @@ cat top-snap | \ sed 's/\[tree2/\[treenamed/' > top-snap-named hg fseed --root named top-snap-named default -hg ftrees --cwd named +hg ftrees --cwd named --convert # pull (should find nothing) hg fpull --cwd named ../top-snap-named default \ | sed "s@$HGTMP@HGTMP@g"
--- a/test-forest.out Thu Dec 21 16:51:24 2006 +0100 +++ b/test-forest.out Fri Dec 22 02:14:02 2006 +0100 @@ -37,18 +37,43 @@ # fclone [.] +requesting all changes +adding changesets +adding manifests +adding file changes +added 1 changesets with 3 changes to 3 files 3 files updated, 0 files merged, 0 files removed, 0 files unresolved [d/d/t] +requesting all changes +adding changesets +adding manifests +adding file changes +added 1 changesets with 1 changes to 1 files 1 files updated, 0 files merged, 0 files removed, 0 files unresolved [e/d] +requesting all changes +adding changesets +adding manifests +adding file changes +added 1 changesets with 1 changes to 1 files 1 files updated, 0 files merged, 0 files removed, 0 files unresolved [t] +requesting all changes +adding changesets +adding manifests +adding file changes +added 1 changesets with 1 changes to 1 files 1 files updated, 0 files merged, 0 files removed, 0 files unresolved [t/t] +requesting all changes +adding changesets +adding manifests +adding file changes +added 1 changesets with 1 changes to 1 files 1 files updated, 0 files merged, 0 files removed, 0 files unresolved # fsnap @@ -334,7 +359,8 @@ [e/d] -[t] *mq* +[t] +*mq* [t/t]