Hi!

[[[
As part of WC-NG, replace entry calls for revisions from
svn_wc_status2_t related code.

The entries code set the revision of newly added nodes to 0 but the db
sets them to -1. Since too many tests needs to be changed and 'svn info'
also uses 0, I'll change those values in a follow-up patch instead.

* subversion/tests/cmdline/copy_tests.py
  (repos_to_wc): Change revision to 0 since the node is added. Don't
    check against entries since the behavior differs.

* subversion/tests/cmdline/stat_tests.py
  (status_with_tree_conflicts): An copied node should not have a
    changed_rev or author.

* subversion/tests/cmdline/svntest/actions.py
  (run_and_verify_status): Add new parameter check_entries. We only
    check the entries if check_entries is set to True.

* subversion/tests/cmdline/merge_tests.py
  (merge_into_missing): Add revision to status output for missing dir.
    Previously, missing dirs did not have a revision, only files had.
    Don't check entries since the behavior differs.

* subversion/svn/status.c
  (print_status): Replace checks for revisions using entries with the
    direct fields in svn_wc_status3_t. Set the revision for added and
    replaced nodes to 0. WC-NG sets those revisions to -1, but changing
    all the involved tests is for a follow-up.

* subversion/include/svn_wc.h
  (svn_wc_status2_t): Add fields revision, changed_rev and
    changed_author.

* subversion/libsvn_wc/status.c
  (assemble_status): Fill in the new fields with data from the wc db.
  (svn_wc_dup_status3): Copy the changed_author field.
]]]

Quirks
========

Checking entries
-------------------
I need to tweak the status output when doing a compare against the
entries in run_and_verify_status(). The code changes the behaviour for
revisions in three ways:

i) Missing dirs, now have a revision
ii) Copies from foreign repos to wc has the rev set to -1
iii) A copied node should not have a changed_author or changed_rev set.

I could change tweak_for_entries_compare() to fix i) but for the
other two I would have to write a func for tweaking the status returned
by 'entries-dump'. Can't I just use the check_entries parameter I've
added to run_and_verify_status() instead? I would only disable the
entries check for three tests.

Getting revisions of deleted nodes
-----------------------------------
I'm using base_get_info() for both nodes having the op_root from a plain
delete and those from a delete within an add. In the later case, the
revision, changed_rev and changed_author will be set to the default nil
values which match what I would get from read_info().

Cheers,
Daniel
Index: subversion/tests/cmdline/copy_tests.py
===================================================================
--- subversion/tests/cmdline/copy_tests.py      (revision 936812)
+++ subversion/tests/cmdline/copy_tests.py      (working copy)
@@ -980,9 +980,10 @@ def repos_to_wc(sbox):
 
   expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
   expected_output.add({
-    'pi' : Item(status='A ',  wc_rev='1'),
+    'pi' : Item(status='A ',  wc_rev='0'),
     })
-  svntest.actions.run_and_verify_status(wc_dir, expected_output)
+  svntest.actions.run_and_verify_status(wc_dir, expected_output,
+                                        check_entries=False)
 
   # Revert everything and verify.
   svntest.actions.run_and_verify_svn(None, None, [], 'revert', '-R', wc_dir)
Index: subversion/tests/cmdline/stat_tests.py
===================================================================
--- subversion/tests/cmdline/stat_tests.py      (revision 936812)
+++ subversion/tests/cmdline/stat_tests.py      (working copy)
@@ -1593,7 +1593,7 @@ def status_with_tree_conflicts(sbox):
          ["                 2        2 jrandom      %s\n" % G,
           "D     C          2        2 jrandom      %s\n" % pi,
           "      >   local delete, incoming edit upon update\n",
-          "A  +  C          -        1 jrandom      %s\n" % rho,
+          "A  +  C          -       ?   ?           %s\n" % rho,
           "      >   local edit, incoming delete upon update\n",
           "!     C                                  %s\n" % tau,
           "      >   local delete, incoming delete upon update\n",
Index: subversion/tests/cmdline/svntest/actions.py
===================================================================
--- subversion/tests/cmdline/svntest/actions.py (revision 936812)
+++ subversion/tests/cmdline/svntest/actions.py (working copy)
@@ -1280,6 +1280,7 @@ def run_and_verify_commit(wc_dir_name, output_tree
 # This function always passes '-q' to the status command, which
 # suppresses the printing of any unversioned or nonexistent items.
 def run_and_verify_status(wc_dir_name, output_tree,
+                          check_entries = True,
                           singleton_handler_a = None,
                           a_baton = None,
                           singleton_handler_b = None,
@@ -1314,7 +1315,7 @@ def run_and_verify_status(wc_dir_name, output_tree
 
   # if we have an output State, and we can/are-allowed to create an
   # entries-based State, then compare the two.
-  if output_state:
+  if output_state and check_entries:
     entries_state = wc.State.from_entries(wc_dir_name)
     if entries_state:
       tweaked = output_state.copy()
Index: subversion/tests/cmdline/merge_tests.py
===================================================================
--- subversion/tests/cmdline/merge_tests.py     (revision 936812)
+++ subversion/tests/cmdline/merge_tests.py     (working copy)
@@ -2161,7 +2161,7 @@ def merge_into_missing(sbox):
   expected_status = wc.State(F_path, {
     ''      : Item(status='  ', wc_rev=1),
     'foo'   : Item(status='! ', wc_rev=2),
-    'Q'     : Item(status='! ', wc_rev='?'),
+    'Q'     : Item(status='! ', wc_rev='2'),
     })
   expected_skip = wc.State(F_path, {
     'Q'   : Item(),
@@ -2183,7 +2183,7 @@ def merge_into_missing(sbox):
   expected_status = wc.State(F_path, {
     ''      : Item(status=' M', wc_rev=1),
     'foo'   : Item(status='!M', wc_rev=2),
-    'Q'     : Item(status='! ', wc_rev='?'),
+    'Q'     : Item(status='! ', wc_rev='2'),
     })
   expected_mergeinfo_output = wc.State(F_path, {
     ''    : Item(status=' U'),
@@ -2214,9 +2214,10 @@ def merge_into_missing(sbox):
   expected_status.add({
     'A/B/F'     : Item(status=' M', wc_rev=1),
     'A/B/F/foo' : Item(status='!M', wc_rev=2),
-    'A/B/F/Q'   : Item(status='! ', wc_rev='?'),
+    'A/B/F/Q'   : Item(status='! ', wc_rev='2'),
     })
-  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+  svntest.actions.run_and_verify_status(wc_dir, expected_status,
+                                        check_entries=False)
 
 #----------------------------------------------------------------------
 # A test for issue 1738
Index: subversion/svn/status.c
===================================================================
--- subversion/svn/status.c     (revision 936812)
+++ subversion/svn/status.c     (working copy)
@@ -142,12 +142,20 @@ print_status(const char *path,
 
       if (! status->entry)
         working_rev = "";
-      else if (! SVN_IS_VALID_REVNUM(status->entry->revision))
-        working_rev = " ? ";
+      else if (! SVN_IS_VALID_REVNUM(status->revision))
+        {
+          if (status->copied)
+            working_rev = "-";
+          else if (text_status == svn_wc_status_added
+              || text_status == svn_wc_status_replaced)
+            working_rev = "0";
+          else
+            working_rev = " ? ";
+        }
       else if (status->copied)
         working_rev = "-";
       else
-        working_rev = apr_psprintf(pool, "%ld", status->entry->revision);
+        working_rev = apr_psprintf(pool, "%ld", status->revision);
 
       if (status->repos_text_status != svn_wc_status_none
           || status->repos_prop_status != svn_wc_status_none)
@@ -183,15 +191,15 @@ print_status(const char *path,
           const char *commit_rev;
           const char *commit_author;
 
-          if (status->entry && SVN_IS_VALID_REVNUM(status->entry->cmt_rev))
-            commit_rev = apr_psprintf(pool, "%ld", status->entry->cmt_rev);
+          if (SVN_IS_VALID_REVNUM(status->changed_rev))
+            commit_rev = apr_psprintf(pool, "%ld", status->changed_rev);
           else if (status->entry)
             commit_rev = " ? ";
           else
             commit_rev = "";
 
-          if (status->entry && status->entry->cmt_author)
-            commit_author = status->entry->cmt_author;
+          if (status->changed_author)
+            commit_author = status->changed_author;
           else if (status->entry)
             commit_author = " ? ";
           else
@@ -277,17 +285,17 @@ svn_cl__print_status_xml(const char *path,
     apr_hash_set(att_hash, "file-external", APR_HASH_KEY_STRING, "true");
   if (status->entry && ! status->entry->copied)
     apr_hash_set(att_hash, "revision", APR_HASH_KEY_STRING,
-                 apr_psprintf(pool, "%ld", status->entry->revision));
+                 apr_psprintf(pool, "%ld", status->revision));
   if (status->tree_conflict)
     apr_hash_set(att_hash, "tree-conflicted", APR_HASH_KEY_STRING,
                  "true");
   svn_xml_make_open_tag_hash(&sb, pool, svn_xml_normal, "wc-status",
                              att_hash);
 
-  if (status->entry && SVN_IS_VALID_REVNUM(status->entry->cmt_rev))
+  if (SVN_IS_VALID_REVNUM(status->changed_rev))
     {
-      svn_cl__print_xml_commit(&sb, status->entry->cmt_rev,
-                               status->entry->cmt_author,
+      svn_cl__print_xml_commit(&sb, status->changed_rev,
+                               status->changed_author,
                                svn_time_to_cstring(status->entry->cmt_date,
                                                    pool),
                                pool);
Index: subversion/include/svn_wc.h
===================================================================
--- subversion/include/svn_wc.h (revision 936812)
+++ subversion/include/svn_wc.h (working copy)
@@ -3617,6 +3617,21 @@ typedef struct svn_wc_status3_t
    */
   enum svn_wc_status_kind pristine_prop_status;
 
+  /** Base revision.
+   * @since New in 1.7
+   */
+  svn_revnum_t revision;
+
+  /** Last revision this was changed
+   * @since New in 1.7
+   */
+  svn_revnum_t changed_rev;
+
+  /** Last commit author of this item
+   * @since New in 1.7
+   */
+  const char *changed_author;
+
   /* NOTE! Please update svn_wc_dup_status3() when adding new fields here. */
 } svn_wc_status3_t;
 
Index: subversion/libsvn_wc/status.c
===================================================================
--- subversion/libsvn_wc/status.c       (revision 936812)
+++ subversion/libsvn_wc/status.c       (working copy)
@@ -297,6 +297,11 @@ assemble_status(svn_wc_status3_t **status,
   svn_boolean_t switched_p = FALSE;
   const svn_wc_conflict_description2_t *tree_conflict;
   svn_boolean_t file_external_p = FALSE;
+  svn_wc__db_status_t db_status;
+  svn_revnum_t revision;
+  svn_revnum_t changed_rev;
+  const char *changed_author;
+  svn_boolean_t base_shadowed;
 #ifdef HAVE_SYMLINK
   svn_boolean_t wc_special;
 #endif /* HAVE_SYMLINK */
@@ -376,6 +381,9 @@ assemble_status(svn_wc_status3_t **status,
 
       stat->repos_lock = repos_lock;
       stat->url = NULL;
+      stat->revision = SVN_INVALID_REVNUM;
+      stat->changed_rev = SVN_INVALID_REVNUM;
+      stat->changed_author = NULL;
       stat->ood_last_cmt_rev = SVN_INVALID_REVNUM;
       stat->ood_last_cmt_date = 0;
       stat->ood_kind = svn_node_none;
@@ -385,6 +393,51 @@ assemble_status(svn_wc_status3_t **status,
       return SVN_NO_ERROR;
     }
 
+  SVN_ERR(svn_wc__db_read_info(&db_status, NULL, &revision, NULL, NULL, NULL,
+                               &changed_rev, NULL, &changed_author,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, &base_shadowed, NULL,
+                               NULL, db, local_abspath, result_pool,
+                               scratch_pool));
+
+  if (db_status == svn_wc__db_status_deleted)
+    {
+      const char *work_del_abspath = NULL;
+      const char *base_del_abspath = NULL;
+      const char *op_root_abspath;
+      svn_boolean_t base_replaced;
+
+      SVN_ERR(svn_wc__db_scan_deletion(&base_del_abspath, &base_replaced,
+                                       NULL, &work_del_abspath, db,
+                                       local_abspath, scratch_pool,
+                                       result_pool));
+      if (work_del_abspath)
+        op_root_abspath = work_del_abspath;
+      else
+        op_root_abspath = base_del_abspath;
+
+      SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, &revision, NULL,
+                                       NULL, NULL, &changed_rev,
+                                       NULL, &changed_author, NULL,
+                                       NULL, NULL, NULL, NULL, NULL,
+                                       db, op_root_abspath,
+                                       result_pool, scratch_pool));
+    }
+  else if (base_shadowed)
+    {
+      SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, &revision, NULL, NULL, NULL,
+                                       &changed_rev, NULL, &changed_author,
+                                       NULL, NULL, NULL, NULL, NULL, NULL, db,
+                                       local_abspath, result_pool,
+                                       scratch_pool));
+    }
+  else if (db_status == svn_wc__db_status_added)
+    {
+      revision = SVN_INVALID_REVNUM;
+      changed_rev = SVN_INVALID_REVNUM;
+      changed_author = NULL;
+    }
+
   /* Someone either deleted the administrative directory in the versioned
      subdir, or deleted the directory altogether and created a new one.
      In any case, what is currently there is in the way.
@@ -606,6 +659,9 @@ assemble_status(svn_wc_status3_t **status,
   stat->copied = entry->copied;
   stat->repos_lock = repos_lock;
   stat->url = (entry->url ? entry->url : NULL);
+  stat->revision = revision;
+  stat->changed_rev = changed_rev;
+  stat->changed_author = changed_author;
   stat->ood_last_cmt_rev = SVN_INVALID_REVNUM;
   stat->ood_last_cmt_date = 0;
   stat->ood_kind = svn_node_none;
@@ -2457,6 +2513,9 @@ svn_wc_dup_status3(const svn_wc_status3_t *orig_st
   if (orig_stat->url)
     new_stat->url = apr_pstrdup(pool, orig_stat->url);
 
+  if (orig_stat->changed_author)
+    new_stat->changed_author = apr_pstrdup(pool, orig_stat->changed_author);
+
   if (orig_stat->ood_last_cmt_author)
     new_stat->ood_last_cmt_author
       = apr_pstrdup(pool, orig_stat->ood_last_cmt_author);

Reply via email to