mirror of
https://github.com/facebook/sapling.git
synced 2024-10-09 16:31:02 +03:00
Performance fix for branches-from-tags in real replay, which is tied up with
changes that fix problems when trunk is not the oldest branch. Also includes fixes for copying from a tag that we chose not to create (eg tagging a vendor branch) and includes tests for all of those things.
This commit is contained in:
parent
189fd9396a
commit
8c7063dc0f
@ -435,7 +435,8 @@ def stupid_svn_server_pull_rev(ui, svn, hg_editor, r):
|
||||
files_touched.add(d)
|
||||
if delete_all_files:
|
||||
for p in hg_editor.repo[parent_ha].manifest().iterkeys():
|
||||
files_touched.add(p)
|
||||
if p:
|
||||
files_touched.add(p)
|
||||
if not used_diff:
|
||||
for p in reduce(operator.add, [[os.path.join(x[0], y) for y in x[2]]
|
||||
for x in
|
||||
@ -447,7 +448,8 @@ def stupid_svn_server_pull_rev(ui, svn, hg_editor, r):
|
||||
files_touched.add(p_real)
|
||||
for p in hg_editor.repo[parent_ha].manifest().iterkeys():
|
||||
# TODO this might not be a required step.
|
||||
files_touched.add(p)
|
||||
if p:
|
||||
files_touched.add(p)
|
||||
date = r.date.replace('T', ' ').replace('Z', '').split('.')[0]
|
||||
date += ' -0000'
|
||||
def filectxfn(repo, memctx, path):
|
||||
@ -465,6 +467,8 @@ def stupid_svn_server_pull_rev(ui, svn, hg_editor, r):
|
||||
extra = {}
|
||||
if b:
|
||||
extra['branch'] = b
|
||||
if '' in files_touched:
|
||||
files_touched.remove('')
|
||||
if parent_ha != node.nullid or files_touched:
|
||||
# TODO(augie) remove this debug code? Or maybe it's sane to have it.
|
||||
for f in files_touched:
|
||||
|
@ -246,16 +246,17 @@ class HgChangeReceiver(delta.Editor):
|
||||
added_branches = {}
|
||||
added_tags = {}
|
||||
tags_to_delete = set()
|
||||
branches_to_delete = set()
|
||||
for p in paths:
|
||||
if self._is_path_valid(p):
|
||||
fi, br = self._path_and_branch_for_path(p)
|
||||
if fi == '' and br not in self.branches:
|
||||
# TODO handle creating a branch from a tag
|
||||
src_p = paths[p].copyfrom_path
|
||||
src_rev = paths[p].copyfrom_rev
|
||||
src_tag = self._is_path_tag(src_p)
|
||||
|
||||
if not src_p or not (self._is_path_valid(src_p) or src_tag):
|
||||
if not ((src_p and self._is_path_valid(src_p)) or
|
||||
(src_tag and src_tag in self.tags)):
|
||||
# we'll imply you're a branch off of trunk
|
||||
# if you have no path, but if you do, it must be valid
|
||||
# or else we assume trunk as well
|
||||
@ -272,6 +273,10 @@ class HgChangeReceiver(delta.Editor):
|
||||
(src_p,
|
||||
src_branch) = self._path_and_branch_for_path(src_p)
|
||||
added_branches[br] = src_branch, src_rev, revision.revnum
|
||||
elif fi == '' and br in self.branches:
|
||||
br2 = br or 'default'
|
||||
if br2 not in self.repo.branchtags() and paths[p].action == 'D':
|
||||
branches_to_delete.add(br)
|
||||
elif br in added_branches:
|
||||
if paths[p].copyfrom_rev > added_branches[br][1]:
|
||||
x,y,z = added_branches[br]
|
||||
@ -302,6 +307,8 @@ class HgChangeReceiver(delta.Editor):
|
||||
tags_to_delete.add(t_name)
|
||||
for t in tags_to_delete:
|
||||
del self.tags[t]
|
||||
for br in branches_to_delete:
|
||||
del self.branches[br]
|
||||
self.tags.update(added_tags)
|
||||
self.branches.update(added_branches)
|
||||
self._save_metadata()
|
||||
@ -339,11 +346,8 @@ class HgChangeReceiver(delta.Editor):
|
||||
parents = (self.get_parent_revision(rev.revnum, branch),
|
||||
revlog.nullid)
|
||||
if branch is not None:
|
||||
if branch not in self.branches:
|
||||
if branch not in self.branches and branch not in self.repo.branchtags():
|
||||
continue
|
||||
if parents == (revlog.nullid, revlog.nullid):
|
||||
assert False, ('a non-trunk branch should probably have'
|
||||
' parents figured out by this point')
|
||||
extra['branch'] = branch
|
||||
parent_ctx = self.repo.changectx(parents[0])
|
||||
def filectxfn(repo, memctx, path):
|
||||
@ -353,9 +357,9 @@ class HgChangeReceiver(delta.Editor):
|
||||
raise IOError()
|
||||
# TODO(augie) tag copies from files
|
||||
flags = parent_ctx.flags(path)
|
||||
is_exec = self.current_files_exec.get(current_file,
|
||||
is_exec = self.current_files_exec.get(current_file,
|
||||
'x' in flags)
|
||||
is_link = self.current_files_symlink.get(current_file,
|
||||
is_link = self.current_files_symlink.get(current_file,
|
||||
'l' in flags)
|
||||
if current_file in self.current_files:
|
||||
data = self.current_files[current_file]
|
||||
@ -497,7 +501,7 @@ class HgChangeReceiver(delta.Editor):
|
||||
self.base_revision = None
|
||||
if path in self.deleted_files:
|
||||
del self.deleted_files[path]
|
||||
if (self._is_path_valid(path) and
|
||||
if (self._is_path_valid(path) and
|
||||
self._path_and_branch_for_path(path)[0]):
|
||||
self.current_file = path
|
||||
self.should_edit_most_recent_plaintext = False
|
||||
@ -533,12 +537,22 @@ class HgChangeReceiver(delta.Editor):
|
||||
self.commit_branches_empty[branch] = False
|
||||
if not self._is_path_valid(path) or not copyfrom_path:
|
||||
return
|
||||
if copyfrom_path and not self._is_path_valid(copyfrom_path):
|
||||
self.missing_plaintexts.add('%s/' % path)
|
||||
return
|
||||
if copyfrom_path:
|
||||
tag = self._is_path_tag(copyfrom_path)
|
||||
if tag not in self.tags:
|
||||
tag = None
|
||||
if not self._is_path_valid(copyfrom_path) and not tag:
|
||||
self.missing_plaintexts.add('%s/' % path)
|
||||
return
|
||||
|
||||
cp_f, br_from = self._path_and_branch_for_path(copyfrom_path)
|
||||
new_hash = self.get_parent_revision(copyfrom_revision + 1, br_from)
|
||||
if tag:
|
||||
source_branch, source_rev = self.tags[tag]
|
||||
cp_f = ''
|
||||
else:
|
||||
source_rev = copyfrom_revision
|
||||
cp_f, source_branch = self._path_and_branch_for_path(copyfrom_path)
|
||||
new_hash = self.get_parent_revision(source_rev + 1,
|
||||
source_branch)
|
||||
if new_hash == node.nullid:
|
||||
self.missing_plaintexts.add('%s/' % path)
|
||||
return
|
||||
|
@ -337,7 +337,7 @@ class SubversionRepo(object):
|
||||
except core.SubversionException, e:
|
||||
# can I depend on this number being constant?
|
||||
if (e.message == "Server doesn't support the replay command"
|
||||
or e.apr_err == 170003
|
||||
or e.apr_err == 170003
|
||||
or e.message == 'The requested report is unknown.'
|
||||
or e.apr_err == 200007):
|
||||
raise SubversionRepoCanNotReplay, ('This Subversion server '
|
||||
|
325
tests/fixtures/tagged_vendor_and_oldest_not_trunk.svndump
vendored
Normal file
325
tests/fixtures/tagged_vendor_and_oldest_not_trunk.svndump
vendored
Normal file
@ -0,0 +1,325 @@
|
||||
SVN-fs-dump-format-version: 2
|
||||
|
||||
UUID: 0e935f28-8caa-dd11-b3dc-00105ae0362c
|
||||
|
||||
Revision-number: 0
|
||||
Prop-content-length: 56
|
||||
Content-length: 56
|
||||
|
||||
K 8
|
||||
svn:date
|
||||
V 27
|
||||
2008-11-04T16:18:04.048615Z
|
||||
PROPS-END
|
||||
|
||||
Revision-number: 1
|
||||
Prop-content-length: 102
|
||||
Content-length: 102
|
||||
|
||||
K 7
|
||||
svn:log
|
||||
V 3
|
||||
btt
|
||||
K 10
|
||||
svn:author
|
||||
V 5
|
||||
durin
|
||||
K 8
|
||||
svn:date
|
||||
V 27
|
||||
2008-11-04T16:18:29.661251Z
|
||||
PROPS-END
|
||||
|
||||
Node-path: branches
|
||||
Node-kind: dir
|
||||
Node-action: add
|
||||
Prop-content-length: 10
|
||||
Content-length: 10
|
||||
|
||||
PROPS-END
|
||||
|
||||
|
||||
Node-path: tags
|
||||
Node-kind: dir
|
||||
Node-action: add
|
||||
Prop-content-length: 10
|
||||
Content-length: 10
|
||||
|
||||
PROPS-END
|
||||
|
||||
|
||||
Node-path: trunk
|
||||
Node-kind: dir
|
||||
Node-action: add
|
||||
Prop-content-length: 10
|
||||
Content-length: 10
|
||||
|
||||
PROPS-END
|
||||
|
||||
|
||||
Revision-number: 2
|
||||
Prop-content-length: 119
|
||||
Content-length: 119
|
||||
|
||||
K 7
|
||||
svn:log
|
||||
V 19
|
||||
Add the vendor dir.
|
||||
K 10
|
||||
svn:author
|
||||
V 5
|
||||
durin
|
||||
K 8
|
||||
svn:date
|
||||
V 27
|
||||
2008-11-04T16:19:16.816658Z
|
||||
PROPS-END
|
||||
|
||||
Node-path: vendor
|
||||
Node-kind: dir
|
||||
Node-action: add
|
||||
Prop-content-length: 10
|
||||
Content-length: 10
|
||||
|
||||
PROPS-END
|
||||
|
||||
|
||||
Node-path: vendor/foobaz
|
||||
Node-kind: dir
|
||||
Node-action: add
|
||||
Prop-content-length: 10
|
||||
Content-length: 10
|
||||
|
||||
PROPS-END
|
||||
|
||||
|
||||
Node-path: vendor/foobaz/alpha
|
||||
Node-kind: file
|
||||
Node-action: add
|
||||
Prop-content-length: 10
|
||||
Text-content-length: 6
|
||||
Text-content-md5: 9f9f90dbe3e5ee1218c86b8839db1995
|
||||
Content-length: 16
|
||||
|
||||
PROPS-END
|
||||
alpha
|
||||
|
||||
|
||||
Node-path: vendor/foobaz/beta
|
||||
Node-kind: file
|
||||
Node-action: add
|
||||
Prop-content-length: 10
|
||||
Text-content-length: 5
|
||||
Text-content-md5: f0cf2a92516045024a0c99147b28f05b
|
||||
Content-length: 15
|
||||
|
||||
PROPS-END
|
||||
beta
|
||||
|
||||
|
||||
Node-path: vendor/foobaz/delta
|
||||
Node-kind: file
|
||||
Node-action: add
|
||||
Prop-content-length: 10
|
||||
Text-content-length: 6
|
||||
Text-content-md5: d2840cc81bc032bd1141b56687d0f93c
|
||||
Content-length: 16
|
||||
|
||||
PROPS-END
|
||||
delta
|
||||
|
||||
|
||||
Node-path: vendor/foobaz/gamma
|
||||
Node-kind: file
|
||||
Node-action: add
|
||||
Prop-content-length: 10
|
||||
Text-content-length: 6
|
||||
Text-content-md5: 303febb9068384eca46b5b6516843b35
|
||||
Content-length: 16
|
||||
|
||||
PROPS-END
|
||||
gamma
|
||||
|
||||
|
||||
Revision-number: 3
|
||||
Prop-content-length: 139
|
||||
Content-length: 139
|
||||
|
||||
K 7
|
||||
svn:log
|
||||
V 39
|
||||
Adding oldest data, which is not trunk.
|
||||
K 10
|
||||
svn:author
|
||||
V 5
|
||||
durin
|
||||
K 8
|
||||
svn:date
|
||||
V 27
|
||||
2008-11-04T16:22:06.704260Z
|
||||
PROPS-END
|
||||
|
||||
Node-path: branches/oldest
|
||||
Node-kind: dir
|
||||
Node-action: add
|
||||
Prop-content-length: 10
|
||||
Content-length: 10
|
||||
|
||||
PROPS-END
|
||||
|
||||
|
||||
Node-path: branches/oldest/five
|
||||
Node-kind: file
|
||||
Node-action: add
|
||||
Prop-content-length: 10
|
||||
Text-content-length: 5
|
||||
Text-content-md5: 014835e36358e38c7f7897d6571e4529
|
||||
Content-length: 15
|
||||
|
||||
PROPS-END
|
||||
five
|
||||
|
||||
|
||||
Node-path: branches/oldest/four
|
||||
Node-kind: file
|
||||
Node-action: add
|
||||
Prop-content-length: 10
|
||||
Text-content-length: 5
|
||||
Text-content-md5: 75ffdb827341e578959bfcabde3789d8
|
||||
Content-length: 15
|
||||
|
||||
PROPS-END
|
||||
four
|
||||
|
||||
|
||||
Node-path: branches/oldest/one
|
||||
Node-kind: file
|
||||
Node-action: add
|
||||
Prop-content-length: 10
|
||||
Text-content-length: 4
|
||||
Text-content-md5: 5bbf5a52328e7439ae6e719dfe712200
|
||||
Content-length: 14
|
||||
|
||||
PROPS-END
|
||||
one
|
||||
|
||||
|
||||
Node-path: branches/oldest/three
|
||||
Node-kind: file
|
||||
Node-action: add
|
||||
Prop-content-length: 10
|
||||
Text-content-length: 6
|
||||
Text-content-md5: febe6995bad457991331348f7b9c85fa
|
||||
Content-length: 16
|
||||
|
||||
PROPS-END
|
||||
three
|
||||
|
||||
|
||||
Node-path: branches/oldest/two
|
||||
Node-kind: file
|
||||
Node-action: add
|
||||
Prop-content-length: 10
|
||||
Text-content-length: 4
|
||||
Text-content-md5: c193497a1a06b2c72230e6146ff47080
|
||||
Content-length: 14
|
||||
|
||||
PROPS-END
|
||||
two
|
||||
|
||||
|
||||
Revision-number: 4
|
||||
Prop-content-length: 105
|
||||
Content-length: 105
|
||||
|
||||
K 7
|
||||
svn:log
|
||||
V 6
|
||||
delete
|
||||
K 10
|
||||
svn:author
|
||||
V 5
|
||||
durin
|
||||
K 8
|
||||
svn:date
|
||||
V 27
|
||||
2008-11-04T16:22:49.936769Z
|
||||
PROPS-END
|
||||
|
||||
Node-path: trunk
|
||||
Node-action: delete
|
||||
|
||||
|
||||
Revision-number: 5
|
||||
Prop-content-length: 124
|
||||
Content-length: 124
|
||||
|
||||
K 7
|
||||
svn:log
|
||||
V 24
|
||||
create trunk from branch
|
||||
K 10
|
||||
svn:author
|
||||
V 5
|
||||
durin
|
||||
K 8
|
||||
svn:date
|
||||
V 27
|
||||
2008-11-04T16:23:00.562964Z
|
||||
PROPS-END
|
||||
|
||||
Node-path: tags/foobaz_1
|
||||
Node-kind: dir
|
||||
Node-action: add
|
||||
Node-copyfrom-rev: 2
|
||||
Node-copyfrom-path: vendor/foobaz
|
||||
Prop-content-length: 34
|
||||
Content-length: 34
|
||||
|
||||
K 13
|
||||
svn:mergeinfo
|
||||
V 0
|
||||
|
||||
PROPS-END
|
||||
|
||||
|
||||
Node-path: trunk
|
||||
Node-kind: dir
|
||||
Node-action: add
|
||||
Node-copyfrom-rev: 3
|
||||
Node-copyfrom-path: branches/oldest
|
||||
Prop-content-length: 34
|
||||
Content-length: 34
|
||||
|
||||
K 13
|
||||
svn:mergeinfo
|
||||
V 0
|
||||
|
||||
PROPS-END
|
||||
|
||||
|
||||
Revision-number: 6
|
||||
Prop-content-length: 146
|
||||
Content-length: 146
|
||||
|
||||
K 7
|
||||
svn:log
|
||||
V 46
|
||||
copy data from a vendor branch tag into trunk.
|
||||
K 10
|
||||
svn:author
|
||||
V 5
|
||||
durin
|
||||
K 8
|
||||
svn:date
|
||||
V 27
|
||||
2008-11-04T16:23:32.980956Z
|
||||
PROPS-END
|
||||
|
||||
Node-path: trunk/foobaz
|
||||
Node-kind: dir
|
||||
Node-action: add
|
||||
Node-copyfrom-rev: 5
|
||||
Node-copyfrom-path: tags/foobaz_1
|
||||
|
||||
|
@ -109,6 +109,18 @@ class TestBasicRepoLayout(unittest.TestCase):
|
||||
'file_renamed_in_from_outside_btt.svndump')
|
||||
self.assert_('LICENSE.file' in repo['tip'])
|
||||
|
||||
def test_oldest_not_trunk_and_tag_vendor_branch(self):
|
||||
repo = self._load_fixture_and_fetch(
|
||||
'tagged_vendor_and_oldest_not_trunk.svndump')
|
||||
self.assertEqual(node.hex(repo['oldest'].node()),
|
||||
'd73002bcdeffe389a8df81ee43303d36e79e8ca4')
|
||||
self.assertEqual(repo['tip'].parents()[0].parents()[0],
|
||||
repo['oldest'])
|
||||
self.assertEqual(node.hex(repo['tip'].node()),
|
||||
'9cf09e6ff7fa938188c3bcc9dd87abd7842c080c')
|
||||
#'1316ef606dda89354ee8c4df725e6264177b5129')
|
||||
|
||||
|
||||
class TestStupidPull(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.oldwd = os.getcwd()
|
||||
@ -140,6 +152,21 @@ class TestStupidPull(unittest.TestCase):
|
||||
self.assertEqual(repo['tip'], repo['default'])
|
||||
self.assertEqual(len(repo.heads()), 2)
|
||||
|
||||
def test_oldest_not_trunk_and_tag_vendor_branch(self):
|
||||
test_util.load_svndump_fixture(self.repo_path,
|
||||
'tagged_vendor_and_oldest_not_trunk.svndump')
|
||||
fetch_command.fetch_revisions(ui.ui(),
|
||||
svn_url='file://%s' % self.repo_path,
|
||||
hg_repo_path=self.wc_path,
|
||||
stupid=True)
|
||||
repo = hg.repository(ui.ui(), self.wc_path)
|
||||
self.assertEqual(node.hex(repo['oldest'].node()),
|
||||
'd73002bcdeffe389a8df81ee43303d36e79e8ca4')
|
||||
self.assertEqual(repo['tip'].parents()[0].parents()[0],
|
||||
repo['oldest'])
|
||||
self.assertEqual(node.hex(repo['tip'].node()),
|
||||
'9cf09e6ff7fa938188c3bcc9dd87abd7842c080c')
|
||||
|
||||
def suite():
|
||||
all = [unittest.TestLoader().loadTestsFromTestCase(TestBasicRepoLayout),
|
||||
unittest.TestLoader().loadTestsFromTestCase(TestStupidPull),
|
||||
|
Loading…
Reference in New Issue
Block a user