# HG changeset patch # User Brad Hall # Date 1339111745 25200 # Node ID 92bd7b3678ea443bf3d63cd0e89324de9ff96e4d # Parent 761a8713450164a5754adff55223d6f08e37cfab Add a changegroup hook to update svn metadata diff --git a/hgsubversion/hooks/__init__.py b/hgsubversion/hooks/__init__.py new file mode 100644 diff --git a/hgsubversion/hooks/updatemeta.py b/hgsubversion/hooks/updatemeta.py new file mode 100644 --- /dev/null +++ b/hgsubversion/hooks/updatemeta.py @@ -0,0 +1,31 @@ +# Mercurial hook to update/rebuild svn metadata if there are svn changes in +# the incoming changegroup. +# +# To install, add the following to your hgrc: +# [hooks] +# changegroup = python:hgsubversion.hooks.updatemeta.hook + +from mercurial import node + +import hgsubversion +import hgsubversion.util +import hgsubversion.svncommands + +def hook(ui, repo, **kwargs): + updatemeta = False + startrev = repo[node.bin(kwargs["node"])].rev() + # Check each rev until we find one that contains svn metadata + for rev in xrange(startrev, len(repo)): + svnrev = hgsubversion.util.getsvnrev(repo[rev]) + if svnrev and svnrev.startswith("svn:"): + updatemeta = True + break + + if updatemeta: + try: + hgsubversion.svncommands.updatemeta(ui, repo, args=[]) + ui.status("Updated svn metadata\n") + except Exception, e: + ui.warn("Failed to update svn metadata: %s" % str(e)) + + return False diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -118,7 +118,7 @@ setup( long_description=open(os.path.join(os.path.dirname(__file__), 'README')).read(), keywords='mercurial', - packages=('hgsubversion', 'hgsubversion.svnwrap'), + packages=('hgsubversion', 'hgsubversion.hooks', 'hgsubversion.svnwrap'), package_data={ 'hgsubversion': ['help/subversion.rst'] }, platforms='any', install_requires=requires, diff --git a/tests/run.py b/tests/run.py --- a/tests/run.py +++ b/tests/run.py @@ -18,6 +18,7 @@ def tests(): import test_fetch_renames import test_fetch_symlinks import test_fetch_truncated + import test_hooks import test_pull import test_push_command import test_push_renames diff --git a/tests/test_hooks.py b/tests/test_hooks.py new file mode 100644 --- /dev/null +++ b/tests/test_hooks.py @@ -0,0 +1,48 @@ +import sys +import test_util +import unittest + +from mercurial import hg +from mercurial import commands + +class TestHooks(test_util.TestBase): + def setUp(self): + super(TestHooks, self).setUp() + + def _loadupdate(self, fixture_name, *args, **kwargs): + kwargs = kwargs.copy() + kwargs.update(stupid=False, noupdate=False) + repo, repo_path = self.load_and_fetch(fixture_name, *args, **kwargs) + return repo, repo_path + + def test_updatemetahook(self): + repo, repo_path = self._loadupdate('single_rev.svndump') + state = repo.parents() + self.add_svn_rev(repo_path, {'trunk/alpha': 'Changed'}) + commands.pull(self.repo.ui, self.repo) + + # Clone to a new repository and add a hook + new_wc_path = "%s-2" % self.wc_path + commands.clone(self.repo.ui, self.wc_path, new_wc_path) + newrepo = hg.repository(test_util.testui(), new_wc_path) + newrepo.ui.setconfig('hooks', 'changegroup.meta', + 'python:hgsubversion.hooks.updatemeta.hook') + + # Commit a rev that should trigger svn meta update + self.add_svn_rev(repo_path, {'trunk/alpha': 'Changed Again'}) + commands.pull(self.repo.ui, self.repo) + + self.called = False + import hgsubversion.svncommands + oldupdatemeta = hgsubversion.svncommands.updatemeta + def _updatemeta(ui, repo, args=[]): + self.called = True + hgsubversion.svncommands.updatemeta = _updatemeta + + # Pull and make sure our updatemeta function gets called + commands.pull(newrepo.ui, newrepo) + hgsubversion.svncommands.updatemeta = oldupdatemeta + self.assertTrue(self.called) + +def suite(): + return unittest.findTestCases(sys.modules[__name__])