# HG changeset patch # User Dan Villiom Podlaski Christiansen # Date 1285776266 -7200 # Node ID 69c0e7c4faf99421c4e535bf3585c2ac00929769 # Parent 1041fb1bec8c813b83684aa6dcb5a6f41692b7da clone: call the wrapped function (fixes #181) This is a regression that was brought to my attention in #mercurial: hgsubversion breaks the --update flag. The cause is that we call hg.clone() directly rather than the original wrapped function. A comment in 'wrapper.py' noted that the call to hg.clone() should be kept in sync with 'mercurial/commands.py'. That didn't happen. The original reason for calling hg.clone() directly was that we needed its return values. Another wrapper is added (and cleared) within clone() to get them anyway. diff --git a/hgsubversion/wrappers.py b/hgsubversion/wrappers.py --- a/hgsubversion/wrappers.py +++ b/hgsubversion/wrappers.py @@ -6,6 +6,7 @@ from mercurial import hg from mercurial import util as hgutil from mercurial import node from mercurial import i18n +from mercurial import extensions import replay import pushmod @@ -417,20 +418,39 @@ def clone(orig, ui, source, dest=None, * them as well as other ways of customising the conversion process. """ - branch = opts.get('branch', None) - if branch: - ui.setconfig('hgsubversion', 'branch', branch[-1]) + data = {} + def hgclonewrapper(orig, ui, origsource, dest, **opts): + if isinstance(origsource, str): + source, branch, checkout = util.parseurl(ui.expandpath(origsource), + opts.get('branch')) + srcrepo = hg.repository(ui, source) + else: + srcrepo = origsource + + if srcrepo.capable('subversion'): + branches = opts.pop('branch', None) + if branches: + data['branches'] = branches + ui.setconfig('hgsubversion', 'branch', branches[-1]) + + data['srcrepo'], data['dstrepo'] = orig(ui, origsource, dest, **opts) for opt, (section, name) in optionmap.iteritems(): if opt in opts and opts[opt]: ui.setconfig(section, name, str(opts.pop(opt))) - # this must be kept in sync with mercurial/commands.py - srcrepo, dstrepo = hg.clone(util.remoteui(ui, opts), source, dest, - pull=opts.get('pull'), - stream=opts.get('uncompressed'), - rev=opts.get('rev'), - update=not opts.get('noupdate')) + # calling hg.clone directoly to get the repository instances it returns, + # breaks in subtle ways, so we double-wrap + orighgclone = extensions.wrapfunction(hg, 'clone', hgclonewrapper) + orig(ui, source, dest, **opts) + hg.clone = orighgclone + + # do this again; the ui instance isn't shared between the wrappers + if data.get('branches'): + ui.setconfig('hgsubversion', 'branch', data['branches'][-1]) + + dstrepo = data.get('dstrepo') + srcrepo = data.get('srcrepo') if dstrepo.local() and srcrepo.capable('subversion'): fd = dstrepo.opener("hgrc", "a", text=True) diff --git a/tests/run.py b/tests/run.py --- a/tests/run.py +++ b/tests/run.py @@ -27,6 +27,7 @@ def tests(): import test_tags import test_template_keywords import test_utility_commands + import test_unaffected_core import test_urls sys.path.append(os.path.dirname(__file__)) diff --git a/tests/test_unaffected_core.py b/tests/test_unaffected_core.py new file mode 100644 --- /dev/null +++ b/tests/test_unaffected_core.py @@ -0,0 +1,85 @@ +import test_util + +import os +import unittest + +from mercurial import commands +from mercurial import dispatch +from mercurial import error +from mercurial import hg +from mercurial import node +from mercurial import ui + +class TestMercurialCore(test_util.TestBase): + ''' + Test that the core Mercurial operations aren't broken by hgsubversion. + ''' + + @test_util.requiresoption('updaterev') + def test_update(self): + ''' Test 'clone --updaterev' ''' + ui = self.ui() + dispatch._dispatch(ui, ['init', self.wc_path]) + repo = self.repo + repo.ui.setconfig('ui', 'username', 'anonymous') + + fpath = os.path.join(self.wc_path, 'it') + f = file(fpath, 'w') + f.write('C1') + f.flush() + commands.add(ui, repo) + commands.commit(ui, repo, message="C1") + f.write('C2') + f.flush() + commands.commit(ui, repo, message="C2") + f.write('C3') + f.flush() + commands.commit(ui, repo, message="C3") + + self.assertEqual(len(repo), 3) + + updaterev = 1 + dispatch._dispatch(ui, ['clone', self.wc_path, self.wc_path + '2', + '--updaterev=%s' % updaterev]) + + repo2 = hg.repository(ui, self.wc_path + '2') + + self.assertEqual(str(repo[updaterev]), str(repo2['.'])) + + @test_util.requiresoption('branch') + def test_branch(self): + ''' Test 'clone --branch' ''' + ui = self.ui() + dispatch._dispatch(ui, ['init', self.wc_path]) + repo = self.repo + repo.ui.setconfig('ui', 'username', 'anonymous') + + fpath = os.path.join(self.wc_path, 'it') + f = file(fpath, 'w') + f.write('C1') + f.flush() + commands.add(ui, repo) + commands.branch(ui, repo, label="B1") + commands.commit(ui, repo, message="C1") + f.write('C2') + f.flush() + commands.branch(ui, repo, label="default") + commands.commit(ui, repo, message="C2") + f.write('C3') + f.flush() + commands.branch(ui, repo, label="B2") + commands.commit(ui, repo, message="C3") + + self.assertEqual(len(repo), 3) + + branch = 'B1' + dispatch._dispatch(ui, ['clone', self.wc_path, self.wc_path + '2', + '--branch', branch]) + + repo2 = hg.repository(ui, self.wc_path + '2') + + self.assertEqual(repo[branch].hex(), repo2['.'].hex()) + +def suite(): + all = [unittest.TestLoader().loadTestsFromTestCase(TestMercurialCore)] + return unittest.TestSuite(all)