# HG changeset patch # User Martijn Pieters # Date 1240843179 18000 # Node ID 521d9c1bb11d459eecebb102050ed3c5c2fc6186 # Parent 77892f67b1cd102d5d1528bb66ba201f4a395f21 Implement -u/--update support when pulling. Status messages now more closely follow standard hg pull. Added generic pull tests as well as specific tests for this change. diff --git a/tests/run.py b/tests/run.py --- a/tests/run.py +++ b/tests/run.py @@ -15,6 +15,7 @@ import test_fetch_mappings import test_fetch_renames import test_fetch_symlinks import test_fetch_truncated +import test_pull import test_push_command import test_push_renames import test_push_dirs @@ -36,6 +37,7 @@ def suite(): test_fetch_renames.suite(), test_fetch_symlinks.suite(), test_fetch_truncated.suite(), + test_pull.suite(), test_push_command.suite(), test_push_renames.suite(), test_push_dirs.suite(), diff --git a/tests/test_pull.py b/tests/test_pull.py new file mode 100644 --- /dev/null +++ b/tests/test_pull.py @@ -0,0 +1,72 @@ +import test_util + +import os.path +import subprocess +from mercurial import ui + +import wrappers + + +class TestPull(test_util.TestBase): + def setUp(self): + super(TestPull, self).setUp() + self.svn_wc = None + + def _load_fixture_and_fetch(self, fixture_name): + return test_util.load_fixture_and_fetch(fixture_name, self.repo_path, + self.wc_path, stupid=False, + noupdate=False) + + def _add_svn_rev(self, changes): + # changes is a dict of filename -> contents + if self.svn_wc is None: + self.svn_wc = os.path.join(self.tmpdir, 'testsvn_wc') + subprocess.call([ + 'svn', 'co', '-q', test_util.fileurl(self.repo_path), + self.svn_wc + ]) + + for filename, contents in changes.iteritems(): + # filenames are / separated + filename = filename.replace('/', os.path.sep) + filename = os.path.join(self.svn_wc, filename) + open(filename, 'w').write(contents) + subprocess.call(['svn', 'add', '-q', filename]) # may be redundant + subprocess.call([ + 'svn', 'commit', '-q', self.svn_wc, '-m', 'test changes']) + + def test_nochanges(self): + repo = self._load_fixture_and_fetch('single_rev.svndump') + state = repo.parents() + wrappers.pull(None, ui.ui(), repo) + self.assertEqual(state, repo.parents()) + + def test_onerevision_noupdate(self): + repo = self._load_fixture_and_fetch('single_rev.svndump') + state = repo.parents() + self._add_svn_rev({'trunk/alpha': 'Changed'}) + wrappers.pull(None, ui.ui(), repo) + self.assertEqual(state, repo.parents()) + self.assertTrue('tip' not in repo[None].tags()) + + def test_onerevision_doupdate(self): + repo = self._load_fixture_and_fetch('single_rev.svndump') + state = repo.parents() + self._add_svn_rev({'trunk/alpha': 'Changed'}) + wrappers.pull(None, ui.ui(), repo, update=True) + self.failIfEqual(state, repo.parents()) + self.assertTrue('tip' in repo[None].tags()) + + def test_onerevision_divergent(self): + repo = self._load_fixture_and_fetch('single_rev.svndump') + self.commitchanges((('alpha', 'alpha', 'Changed another way'),)) + state = repo.parents() + self._add_svn_rev({'trunk/alpha': 'Changed one way'}) + wrappers.pull(None, ui.ui(), repo, update=True) + self.assertEqual(state, repo.parents()) + self.assertTrue('tip' not in repo[None].tags()) + self.assertEqual(len(repo.heads()), 2) + +def suite(): + import unittest, sys + return unittest.findTestCases(sys.modules[__name__]) diff --git a/wrappers.py b/wrappers.py --- a/wrappers.py +++ b/wrappers.py @@ -8,6 +8,7 @@ from mercurial import patch from mercurial import hg from mercurial import util as hgutil from mercurial import node +from mercurial import i18n from svn import core from svn import delta @@ -288,6 +289,10 @@ def pull(orig, ui, repo, source="default raise hgutil.Abort('Revision skipping at repository initialization ' 'remains unimplemented.') + revisions = 0 + if not initializing_repo: + oldheads = len(repo.changelog.heads()) + # start converting revisions for r in svn.revisions(start=start): valid = True @@ -322,8 +327,22 @@ def pull(orig, ui, repo, source="default ui.status('Got a 502, retrying (%s)\n' % tries) else: raise hgutil.Abort(*e.args) + revisions += 1 util.swap_out_encoding(old_encoding) + if revisions == 0: + ui.status(i18n._("no changes found\n")) + return + else: + ui.status("added %d svn revisions\n" % revisions) + if not initializing_repo: + newheads = len(repo.changelog.heads()) + # postincoming needs to know if heads were added or removed + # calculation based on mercurial.localrepo.addchangegroup + # 0 means no changes, 1 no new heads, > 1 new heads, < 0 heads removed + modheads = newheads - oldheads + (newheads < oldheads and -1 or 1) + commands.postincoming(ui, repo, modheads, opts.get('update'), None) + def rebase(orig, ui, repo, **opts): """rebase current unpushed revisions onto the Subversion head