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)