Mercurial > hgsubversion
comparison tests/test_push_renames.py @ 70:49b7cbe4c8e3
push_cmd: handle copies at file level
Mercurial store knows only file-level copies, directory copies are handle with
heuristics. Implement the former one in svn backends.
| author | Patrick Mezard <pmezard@gmail.com> |
|---|---|
| date | Wed, 05 Nov 2008 13:37:08 +0100 |
| parents | |
| children | 072010a271c6 |
comparison
equal
deleted
inserted
replaced
| 69:63ece4ea25c9 | 70:49b7cbe4c8e3 |
|---|---|
| 1 import os | |
| 2 import shutil | |
| 3 import sys | |
| 4 import tempfile | |
| 5 import unittest | |
| 6 | |
| 7 from mercurial import context | |
| 8 from mercurial import commands | |
| 9 from mercurial import hg | |
| 10 from mercurial import node | |
| 11 from mercurial import ui | |
| 12 from mercurial import revlog | |
| 13 | |
| 14 import fetch_command | |
| 15 import push_cmd | |
| 16 import test_util | |
| 17 | |
| 18 class TestPushRenames(unittest.TestCase): | |
| 19 def setUp(self): | |
| 20 self.oldwd = os.getcwd() | |
| 21 self.tmpdir = tempfile.mkdtemp('svnwrap_test') | |
| 22 self.repo_path = '%s/testrepo' % self.tmpdir | |
| 23 self.wc_path = '%s/testrepo_wc' % self.tmpdir | |
| 24 test_util.load_svndump_fixture(self.repo_path, 'pushrenames.svndump') | |
| 25 fetch_command.fetch_revisions(ui.ui(), | |
| 26 svn_url='file://%s' % self.repo_path, | |
| 27 hg_repo_path=self.wc_path) | |
| 28 | |
| 29 # define this as a property so that it reloads anytime we need it | |
| 30 @property | |
| 31 def repo(self): | |
| 32 return hg.repository(ui.ui(), self.wc_path) | |
| 33 | |
| 34 def tearDown(self): | |
| 35 shutil.rmtree(self.tmpdir) | |
| 36 os.chdir(self.oldwd) | |
| 37 | |
| 38 def _commitchanges(self, repo, changes): | |
| 39 parentctx = repo['tip'] | |
| 40 | |
| 41 changed, removed = [], [] | |
| 42 for source, dest, newdata in changes: | |
| 43 if dest is None: | |
| 44 removed.append(source) | |
| 45 else: | |
| 46 changed.append(dest) | |
| 47 | |
| 48 def filectxfn(repo, memctx, path): | |
| 49 if path in removed: | |
| 50 raise IOError() | |
| 51 entry = [e for e in changes if path == e[1]][0] | |
| 52 source, dest, newdata = entry | |
| 53 if newdata is None: | |
| 54 newdata = parentctx[source].data() | |
| 55 copied = None | |
| 56 if source != dest: | |
| 57 copied = source | |
| 58 return context.memfilectx(path=dest, | |
| 59 data=newdata, | |
| 60 islink=False, | |
| 61 isexec=False, | |
| 62 copied=copied) | |
| 63 | |
| 64 ctx = context.memctx(repo, | |
| 65 (parentctx.node(), node.nullid), | |
| 66 'automated test', | |
| 67 changed + removed, | |
| 68 filectxfn, | |
| 69 'an_author', | |
| 70 '2008-10-07 20:59:48 -0500') | |
| 71 return repo.commitctx(ctx) | |
| 72 | |
| 73 def _debug_print_copies(self, ctx): | |
| 74 w = sys.stderr.write | |
| 75 for f in ctx.files(): | |
| 76 if f not in ctx: | |
| 77 w('R %s\n' % f) | |
| 78 else: | |
| 79 w('U %s %r\n' % (f, ctx[f].data())) | |
| 80 if ctx[f].renamed(): | |
| 81 w('%s copied from %s\n' % (f, ctx[f].renamed()[0])) | |
| 82 | |
| 83 def assertchanges(self, changes, ctx): | |
| 84 for source, dest, data in changes: | |
| 85 if dest is None: | |
| 86 self.assertTrue(source not in ctx) | |
| 87 else: | |
| 88 self.assertTrue(dest in ctx) | |
| 89 if data is None: | |
| 90 data = ctx.parents()[0][source].data() | |
| 91 self.assertEqual(data, ctx[dest].data()) | |
| 92 if dest != source: | |
| 93 copy = ctx[dest].renamed() | |
| 94 self.assertEqual(copy[0], source) | |
| 95 | |
| 96 def test_push_renames(self, commit=True): | |
| 97 repo = self.repo | |
| 98 | |
| 99 changes = [ | |
| 100 # Regular copy of a single file | |
| 101 ('a', 'a2', None), | |
| 102 # Copy and update of target | |
| 103 ('a', 'a3', 'aa\n'), | |
| 104 # Regular move of a single file | |
| 105 ('b', 'b2', None), | |
| 106 ('b', None, None), | |
| 107 # Regular move and update of target | |
| 108 ('c', 'c2', 'c\nc\n'), | |
| 109 ('c', None, None), | |
| 110 # Copy and update of source and targets | |
| 111 ('d', 'd2', 'd\nd2\n'), | |
| 112 ('d', 'd', 'd\nd\n'), | |
| 113 # Double copy and removal (aka copy and move) | |
| 114 ('e', 'e2', 'e\ne2\n'), | |
| 115 ('e', 'e3', 'e\ne3\n'), | |
| 116 ('e', None, None), | |
| 117 ] | |
| 118 self._commitchanges(repo, changes) | |
| 119 | |
| 120 hg.update(repo, repo['tip'].node()) | |
| 121 push_cmd.push_revisions_to_subversion(ui.ui(), repo=self.repo, | |
| 122 hg_repo_path=self.wc_path, | |
| 123 svn_url='file://'+self.repo_path) | |
| 124 tip = self.repo['tip'] | |
| 125 # self._debug_print_copies(tip) | |
| 126 self.assertchanges(changes, tip) | |
| 127 | |
| 128 def suite(): | |
| 129 all = [unittest.TestLoader().loadTestsFromTestCase(TestPushRenames), | |
| 130 ] | |
| 131 return unittest.TestSuite(all) |
