Commits

Dan Villiom Podlaski Christiansen  committed 69c0e7c

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.

  • Participants
  • Parent commits 1041fb1

Comments (0)

Files changed (3)

File hgsubversion/wrappers.py

 from mercurial import util as hgutil
 from mercurial import node
 from mercurial import i18n
+from mercurial import extensions
 
 import replay
 import pushmod
     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)

File tests/run.py

     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__))

File tests/test_unaffected_core.py

+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)