You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ph...@apache.org on 2015/07/02 21:09:03 UTC
svn commit: r1688890 - in /subversion/branches/move-tracking-2/subversion:
include/private/svn_branch.h libsvn_delta/branch.c svnmover/svnmover.c
tests/cmdline/svnmover_tests.py tests/cmdline/svntest/wc.py
Author: philip
Date: Thu Jul 2 19:09:02 2015
New Revision: 1688890
URL: http://svn.apache.org/r1688890
Log:
On move-tracking-2 branch: add '--ui serial' for 'ls' and 'ls-br-r', use
it to verify eids in a test.
* subversion/include/private/svn_branch.h
(svn_branch_state_serialize): Declare.
* subversion/libsvn_delta/branch.c
(svn_branch_state_serialize): Make non-static.
* subversion/svnmover/svnmover.c
(UI_MODE_SERIAL): Add.
(ui_mode_map): Extend.
(execute): Implement ls-br-r and ls serial output.
* subversion/tests/cmdline/svnmover_tests.py
(test_svnmover3): New.
(merge_swap_abc): Use new function.
* subversion/tests/cmdline/svntest/wc.py
(_re_parse_eid_header, _re_parse_eid_branch, _re_parse_eid_ele,
_re_parse_split_branch_eid, from_eids): New.
(StateItem): Add eid attribute.
Modified:
subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h
subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c
subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c
subversion/branches/move-tracking-2/subversion/tests/cmdline/svnmover_tests.py
subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/wc.py
Modified: subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h?rev=1688890&r1=1688889&r2=1688890&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h Thu Jul 2 19:09:02 2015
@@ -759,6 +759,13 @@ svn_branch_revision_root_serialize(svn_s
svn_branch_revision_root_t *rev_root,
apr_pool_t *scratch_pool);
+/* Write to STREAM a parseable representation of BRANCH.
+ */
+svn_error_t *
+svn_branch_state_serialize(svn_stream_t *stream,
+ svn_branch_state_t *branch,
+ apr_pool_t *scratch_pool);
+
/* Branch all or part of an existing branch, making a new branch.
*
* Branch the subtree of FROM_BRANCH found at FROM_EID, to create
Modified: subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c?rev=1688890&r1=1688889&r2=1688890&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c Thu Jul 2 19:09:02 2015
@@ -1170,7 +1170,7 @@ svn_branch_revision_root_parse(svn_branc
/* Write to STREAM a parseable representation of BRANCH.
*/
-static svn_error_t *
+svn_error_t *
svn_branch_state_serialize(svn_stream_t *stream,
svn_branch_state_t *branch,
apr_pool_t *scratch_pool)
Modified: subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c?rev=1688890&r1=1688889&r2=1688890&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c Thu Jul 2 19:09:02 2015
@@ -77,13 +77,15 @@ check_lib_versions(void)
static svn_boolean_t quiet = FALSE;
/* UI mode: whether to display output in terms of paths or elements */
-enum { UI_MODE_EIDS, UI_MODE_PATHS };
+enum { UI_MODE_EIDS, UI_MODE_PATHS, UI_MODE_SERIAL };
static int the_ui_mode = UI_MODE_EIDS;
static const svn_token_map_t ui_mode_map[]
= { {"eids", UI_MODE_EIDS},
{"e", UI_MODE_EIDS},
{"paths", UI_MODE_PATHS},
{"p", UI_MODE_PATHS},
+ {"serial", UI_MODE_SERIAL},
+ {"s", UI_MODE_SERIAL},
{NULL, SVN_TOKEN_UNKNOWN} };
/* Is BRANCH1 the same branch as BRANCH2? Compare by full branch-ids; don't
@@ -2645,9 +2647,21 @@ execute(svnmover_wc_t *wc,
case ACTION_LIST_BRANCHES_R:
{
- /* (Note: BASE_REVISION is always a real revision number, here) */
- SVN_ERR(list_all_branches(wc->working_branch->rev_root, TRUE,
- iterpool));
+ if (the_ui_mode == UI_MODE_SERIAL)
+ {
+ svn_stream_t *stream;
+ SVN_ERR(svn_stream_for_stdout(&stream, iterpool));
+ SVN_ERR(svn_branch_revision_root_serialize(
+ stream,
+ wc->working_branch->rev_root,
+ iterpool));
+ }
+ else
+ {
+ /* Note: BASE_REVISION is always a real revision number, here */
+ SVN_ERR(list_all_branches(wc->working_branch->rev_root, TRUE,
+ iterpool));
+ }
}
break;
@@ -2661,8 +2675,19 @@ execute(svnmover_wc_t *wc,
arg[0]->el_rev->branch, arg[0]->el_rev->branch->root_eid, iterpool);
SVN_ERR(list_branch_elements(fb, iterpool));
}
+ else if (the_ui_mode == UI_MODE_EIDS)
+ {
+ SVN_ERR(list_branch_elements_by_eid(arg[0]->el_rev->branch,
+ iterpool));
+ }
else
- SVN_ERR(list_branch_elements_by_eid(arg[0]->el_rev->branch, iterpool));
+ {
+ svn_stream_t *stream;
+ SVN_ERR(svn_stream_for_stdout(&stream, iterpool));
+ SVN_ERR(svn_branch_state_serialize(stream,
+ arg[0]->el_rev->branch,
+ iterpool));
+ }
}
break;
Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/svnmover_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/svnmover_tests.py?rev=1688890&r1=1688889&r2=1688890&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/svnmover_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/svnmover_tests.py Thu Jul 2 19:09:02 2015
@@ -30,6 +30,7 @@ import os, re
XFail = svntest.testcase.XFail_deco
Issues = svntest.testcase.Issues_deco
Issue = svntest.testcase.Issue_deco
+Item = svntest.wc.StateItem
######################################################################
@@ -106,6 +107,21 @@ def sbox_build_svnmover(sbox, content=No
if content:
content(sbox)
+def test_svnmover3(sbox, relpath, expected_changes, expected_eids, *varargs):
+
+ test_svnmover2(sbox, relpath, expected_changes, *varargs)
+
+ if expected_eids:
+ exit_code, outlines, errlines = svntest.main.run_svnmover('-U',
+ sbox.repo_url,
+ '--ui=serial',
+ 'ls-br-r')
+ eid_tree = svntest.wc.State.from_eids(outlines)
+ try:
+ expected_eids.compare_and_display('eids', eid_tree)
+ except svntest.tree.SVNTreeError:
+ raise
+
def test_svnmover2(sbox, relpath, expected_changes, *varargs):
"""Run svnmover with the list of SVNMOVER_ARGS arguments. Verify that
its run results in a new commit with 'svnmover diff -c HEAD' changes
@@ -145,6 +161,7 @@ def test_svnmover2(sbox, relpath, expect
outlines = [l.strip() for l in outlines]
svntest.verify.verify_outputs(None, outlines, None, expected_changes, None)
+
def test_svnmover(repo_url, expected_path_changes, *varargs):
"""Run svnmover with the list of SVNMOVER_ARGS arguments. Verify that
its run results in a new commit with 'svn log -rHEAD' changed paths
@@ -1308,9 +1325,19 @@ def merge_swap_abc(sbox):
"merge swaps A and C in A/B/C"
sbox_build_svnmover(sbox)
- test_svnmover2(sbox, '',
+ expected_eids = svntest.wc.State('', {
+ '' : Item(eid=0),
+ 'X' : Item(eid=2),
+ 'X/A' : Item(eid=3),
+ 'X/A/a1' : Item(eid=4),
+ 'X/A/B' : Item(eid=5),
+ 'X/A/B/C' : Item(eid=6),
+ 'X/A/B/C/c1' : Item(eid=7),
+ })
+ test_svnmover3(sbox, '',
reported_br_diff('') +
reported_br_add('X'),
+ expected_eids,
'mkbranch X ' +
'mkdir X/A ' +
'mkdir X/A/a1 ' +
@@ -1318,24 +1345,48 @@ def merge_swap_abc(sbox):
'mkdir X/A/B/C ' +
'mkdir X/A/B/C/c1')
- test_svnmover2(sbox, '', None,
+ expected_eids.add({
+ 'Y' : Item(eid=2),
+ 'Y/A' : Item(eid=3),
+ 'Y/A/a1' : Item(eid=4),
+ 'Y/A/B' : Item(eid=5),
+ 'Y/A/B/C' : Item(eid=6),
+ 'Y/A/B/C/c1' : Item(eid=7),
+ })
+ test_svnmover3(sbox, '', None, expected_eids,
'branch X Y')
- test_svnmover2(sbox, '',
+ expected_eids.tweak('X/A', eid=6)
+ expected_eids.tweak('X/A/B/C', eid=3)
+ expected_eids.remove('X/A/a1', 'X/A/B/C/c1')
+ expected_eids.add({
+ 'X/A/c1' : Item(eid=7),
+ 'X/A/B/C/a1' : Item(eid=4),
+ })
+ test_svnmover3(sbox, '',
reported_br_diff('X') +
reported_move('A/B/C', 'A') +
reported_move('A/B', 'A/B') +
reported_move('A', 'A/B/C'),
+ expected_eids,
'mv X/A/B/C X/C ' +
'mv X/A/B X/C/B ' +
'mv X/A X/C/B/C ' +
'mv X/C X/A')
- test_svnmover2(sbox, '',
+ expected_eids.tweak('Y/A', eid=6)
+ expected_eids.tweak('Y/A/B/C', eid=3)
+ expected_eids.remove('Y/A/a1', 'Y/A/B/C/c1')
+ expected_eids.add({
+ 'Y/A/c1' : Item(eid=7),
+ 'Y/A/B/C/a1' : Item(eid=4),
+ })
+ test_svnmover3(sbox, '',
reported_br_diff('Y') +
reported_move('A/B/C', 'A') +
reported_move('A/B', 'A/B') +
reported_move('A', 'A/B/C'),
+ expected_eids,
'merge X Y X@2')
######################################################################
Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/wc.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/wc.py?rev=1688890&r1=1688889&r2=1688890&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/wc.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/wc.py Thu Jul 2 19:09:02 2015
@@ -116,6 +116,16 @@ _re_parse_co_restored = re.compile('^(Re
_re_parse_commit_ext = re.compile('^(([A-Za-z]+( [a-z]+)*)) \'(.+)\'( --.*)?')
_re_parse_commit = re.compile('^(\w+( \(bin\))?)\s+(.+)')
+#rN: eids 0 15 branches 4
+_re_parse_eid_header = re.compile('^r(-1|[0-9]+): eids ([0-9]+) ([0-9]+) '
+ 'branches ([0-9]+)$')
+# B0.2 root-eid 3 at X
+_re_parse_eid_branch = re.compile('^B([0-9.]+) root-eid ([0-9]+) at (.*)$')
+# e4: normal 6 C
+_re_parse_eid_ele = re.compile('^e([0-9]+): (none|normal|subbranch) '
+ '(-1|[0-9]+) (.*)$')
+# 25.34.78
+_re_parse_split_branch_eid = re.compile('^([0-9.]+)\.([0-9]+)$')
class State:
"""Describes an existing or expected state of a working copy.
@@ -750,6 +760,70 @@ class State:
return cls('', desc)
+ @classmethod
+ def from_eids(cls, lines):
+
+ # Need to read all elements in a branch before we can construct
+ # the full path to an element.
+
+ def eid_path(eids, eid):
+ ele = eids[eid]
+ if ele[0] == '-1':
+ return ele[1]
+ parent_path = eid_path(eids, ele[0])
+ if parent_path == '':
+ return ele[1]
+ return parent_path + '/' + ele[1]
+
+ def eid_full_path(eids, eid, root_path):
+ path = eid_path(eids, eid)
+ if root_path == '':
+ return eid_path(eids, eid)
+ if path == '':
+ return root_path
+ return root_path + '/' + eid_path(eids, eid)
+
+ def add_to_desc(eids, desc, branch_root_path):
+ for k, v in eids.items():
+ desc[eid_full_path(eids, k, branch_root_path)] = StateItem(eid=k)
+
+ branches = {}
+ branch = None
+ eids = {}
+ desc = {}
+ for line in lines:
+
+ match = _re_parse_eid_ele.search(line)
+ if match and match.group(2) != 'none':
+ eid = match.group(1)
+ parent_eid = match.group(3)
+ path = match.group(4)
+ if path == '.':
+ path = ''
+ eids[eid] = [parent_eid, path]
+
+ match = _re_parse_eid_branch.search(line)
+ if match:
+ if branch:
+ branches[branch[0]] = branch
+ add_to_desc(eids, desc, branch[3])
+ eids = {}
+ parent_branch_eid = None
+ branch_eid = match.group(1)
+ match2 = _re_parse_split_branch_eid.search(branch_eid)
+ if match2:
+ parent_branch_eid = branches[match2.group(1)]
+ root_eid = match.group(2)
+ path = match.group(3)
+ if path == '.':
+ path = ''
+ branch = [branch_eid, parent_branch_eid, root_eid, path]
+
+ branches[branch[0]] = branch
+ add_to_desc(eids, desc, branch[3])
+
+ return cls('', desc)
+
class StateItem:
"""Describes an individual item within a working copy.
@@ -764,7 +838,8 @@ class StateItem:
entry_rev=None, entry_status=None, entry_copied=None,
locked=None, copied=None, switched=None, writelocked=None,
treeconflict=None, moved_from=None, moved_to=None,
- prev_status=None, prev_verb=None, prev_treeconflict=None):
+ prev_status=None, prev_verb=None, prev_treeconflict=None,
+ eid=None):
# provide an empty prop dict if it wasn't provided
if props is None:
props = { }
@@ -772,6 +847,8 @@ class StateItem:
### keep/make these ints one day?
if wc_rev is not None:
wc_rev = str(wc_rev)
+ if eid is not None:
+ eid = str(eid)
# Any attribute can be None if not relevant, unless otherwise stated.
@@ -807,6 +884,7 @@ class StateItem:
# Relative paths to the move locations
self.moved_from = moved_from
self.moved_to = moved_to
+ self.eid = eid
def copy(self):
"Make a deep copy of self."
@@ -820,6 +898,8 @@ class StateItem:
# Refine the revision args (for now) to ensure they are strings.
if value is not None and name == 'wc_rev':
value = str(value)
+ if value is not None and name == 'eid':
+ value = str(value)
setattr(self, name, value)
def __eq__(self, other):
@@ -867,6 +947,8 @@ class StateItem:
atts['moved_from'] = self.moved_from
if self.moved_to is not None:
atts['moved_to'] = self.moved_to
+ if self.eid is not None:
+ atts['eid'] = self.eid
return (os.path.normpath(path), self.contents, self.props, atts)