subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gst...@apache.org
Subject svn commit: r931449 - in /subversion/trunk/subversion: libsvn_wc/entries.c tests/cmdline/switch_tests.py tests/cmdline/update_tests.py
Date Wed, 07 Apr 2010 07:05:28 GMT
Author: gstein
Date: Wed Apr  7 07:05:28 2010
New Revision: 931449

URL: http://svn.apache.org/viewvc?rev=931449&view=rev
Log:
Fix the inheritance handling for entry->copyfrom_*. The mapping code was
not properly considering the copyfrom data between "this" node and the
ancestor nodes.

This fixes merge_tests 34 and 134 (broken by r930162), but proceeds to
break diff_tests 41 and merge_tests 8. Two steps forward...

* subversion/libsvn_wc/entries.c:
  (read_entries_new): rework the logic that analyzes copyfrom information
    on "this" node and the ancestor nodes. it was not (properly)
    considering that an ancestor may imply "this" node is part of a copy.

* subversion/tests/cmdline/switch_tests.py:
  (tree_conflicts_on_switch_2_1): note that we fail because an (A)dd is
    incorrectly reported as a (M)odify, due to issues in wc_db.
  (test_list): mark the above as an XFail

* subversion/tests/cmdline/update_tests.py:
  (tree_conflicts_on_update_2_1, tree_conflict_uc2_schedule_re_add): leave
    comments about the breakage due to wc_db issues.
  (test_list): mark the above two tests as XFail

Modified:
    subversion/trunk/subversion/libsvn_wc/entries.c
    subversion/trunk/subversion/tests/cmdline/switch_tests.py
    subversion/trunk/subversion/tests/cmdline/update_tests.py

Modified: subversion/trunk/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/entries.c?rev=931449&r1=931448&r2=931449&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/entries.c (original)
+++ subversion/trunk/subversion/libsvn_wc/entries.c Wed Apr  7 07:05:28 2010
@@ -727,6 +727,8 @@ read_entries_new(apr_hash_t **result_ent
                || status == svn_wc__db_status_obstructed_add)
         {
           svn_wc__db_status_t work_status;
+          const char *op_root_abspath;
+          const char *scanned_original_relpath;
           svn_revnum_t original_revision;
 
           /* For child nodes, pick up the parent's revision.  */
@@ -817,17 +819,19 @@ read_entries_new(apr_hash_t **result_ent
             }
 
           SVN_ERR(svn_wc__db_scan_addition(&work_status,
-                                           NULL,
+                                           &op_root_abspath,
                                            &repos_relpath,
                                            &entry->repos,
                                            &entry->uuid,
-                                           NULL, NULL, NULL, &original_revision,
+                                           &scanned_original_relpath,
+                                           NULL, NULL, /* original_root|uuid */
+                                           &original_revision,
                                            db,
                                            entry_abspath,
                                            result_pool, iterpool));
-
+          SVN_DBG(("entry: work_status=%d  cmt_rev=%ld  relpath='%s'\n", work_status, entry->cmt_rev,
original_repos_relpath));
           if (!SVN_IS_VALID_REVNUM(entry->cmt_rev)
-              && original_repos_relpath == NULL)
+              && scanned_original_relpath == NULL)
             {
               /* There is NOT a last-changed revision (last-changed date and
                  author may be unknown, but we can always check the rev).
@@ -850,106 +854,146 @@ read_entries_new(apr_hash_t **result_ent
 
               /* Copied nodes need to mirror their copyfrom_rev, if they
                  don't have a revision of their own already. */
-              if (!SVN_IS_VALID_REVNUM(entry->revision))
+              if (!SVN_IS_VALID_REVNUM(entry->revision)
+                  || entry->revision == 0 /* added */)
                 entry->revision = original_revision;
             }
 
           /* Does this node have copyfrom_* information?  */
-          if (original_repos_relpath != NULL)
+          if (scanned_original_relpath != NULL)
             {
-              const char *parent_abspath;
-              svn_boolean_t set_copyfrom = TRUE;
-              svn_error_t *err;
-              const char *op_root_abspath;
-              const char *parent_repos_relpath;
-              const char *parent_root_url;
+              svn_boolean_t is_copied_child;
+              svn_boolean_t is_mixed_rev = FALSE;
 
               SVN_ERR_ASSERT(work_status == svn_wc__db_status_copied);
 
-              /* When we insert entries into the database, we will construct
-                 additional copyfrom records for mixed-revision copies. The
-                 old entries would simply record the different revision in
-                 the entry->revision field. That is not available within
-                 wc-ng, so additional copies are made (see the logic inside
-                 write_entry()). However, when reading these back *out* of
-                 the database, the additional copies look like new "Added"
-                 nodes rather than a simple mixed-rev working copy.
-
-                 That would be a behavior change if we did not compensate.
-                 If there is copyfrom information for this node, then the
-                 code below looks at the parent to detect if it *also* has
-                 copyfrom information, and if the copyfrom_url would align
-                 properly. If it *does*, then we omit storing copyfrom_url
-                 and copyfrom_rev (ie. inherit the copyfrom info like a
-                 normal child), and update entry->revision with the
-                 copyfrom_rev in order to (re)create the mixed-rev copied
-                 subtree that was originally presented for storage.  */
-
-              /* Get the copyfrom information from our parent.
-
-                 Note that the parent could be added/copied/moved-here. There
-                 is no way for it to be deleted/moved-away and have *this*
-                 node appear as copied.  */
-              parent_abspath = svn_dirent_dirname(entry_abspath, iterpool);
-              err = svn_wc__db_scan_addition(NULL,
-                                             &op_root_abspath,
-                                             NULL, NULL, NULL,
-                                             &parent_repos_relpath,
-                                             &parent_root_url,
-                                             NULL, NULL,
-                                             db,
-                                             parent_abspath,
-                                             iterpool, iterpool);
-              if (err)
+              /* If this node inherits copyfrom information from an
+                 ancestor node, then it must be a copied child.  */
+              is_copied_child = (original_repos_relpath == NULL);
+
+              /* If this node has copyfrom information on it, then it may
+                 be an actual copy-root, or it could be participating in
+                 a mixed-revision copied tree. So if we don't already know
+                 this is a copied child, then we need to look for this
+                 mixed-revision situation.  */
+              if (!is_copied_child)
+                {
+                  const char *parent_abspath;
+                  svn_error_t *err;
+                  const char *parent_repos_relpath;
+                  const char *parent_root_url;
+
+                  /* When we insert entries into the database, we will
+                     construct additional copyfrom records for mixed-revision
+                     copies. The old entries would simply record the different
+                     revision in the entry->revision field. That is not
+                     available within wc-ng, so additional copies are made
+                     (see the logic inside write_entry()). However, when
+                     reading these back *out* of the database, the additional
+                     copies look like new "Added" nodes rather than a simple
+                     mixed-rev working copy.
+
+                     That would be a behavior change if we did not compensate.
+                     If there is copyfrom information for this node, then the
+                     code below looks at the parent to detect if it *also* has
+                     copyfrom information, and if the copyfrom_url would align
+                     properly. If it *does*, then we omit storing copyfrom_url
+                     and copyfrom_rev (ie. inherit the copyfrom info like a
+                     normal child), and update entry->revision with the
+                     copyfrom_rev in order to (re)create the mixed-rev copied
+                     subtree that was originally presented for storage.  */
+
+                  /* Get the copyfrom information from our parent.
+
+                     Note that the parent could be added/copied/moved-here.
+                     There is no way for it to be deleted/moved-away and
+                     have *this* node appear as copied.  */
+                  parent_abspath = svn_dirent_dirname(entry_abspath, iterpool);
+                  err = svn_wc__db_scan_addition(NULL,
+                                                 &op_root_abspath,
+                                                 NULL, NULL, NULL,
+                                                 &parent_repos_relpath,
+                                                 &parent_root_url,
+                                                 NULL, NULL,
+                                                 db,
+                                                 parent_abspath,
+                                                 iterpool, iterpool);
+                  if (err)
+                    {
+                      if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+                        return svn_error_return(err);
+                      svn_error_clear(err);
+                    }
+                  else if (parent_root_url != NULL
+                           && strcmp(original_root_url, parent_root_url) == 0)
+                    {
+                      const char *relpath_to_entry = svn_dirent_is_child(
+                        op_root_abspath, entry_abspath, NULL);
+                      const char *entry_repos_relpath = svn_relpath_join(
+                        parent_repos_relpath, relpath_to_entry, iterpool);
+
+                      /* The copyfrom repos roots matched.
+
+                         Now we look to see if the copyfrom path of the parent
+                         would align with our own path. If so, then it means
+                         this copyfrom was spontaneously created and inserted
+                         for mixed-rev purposes and can be eliminated without
+                         changing the semantics of a mixed-rev copied subtree.
+
+                         See notes/api-errata/wc003.txt for some additional
+                         detail, and potential issues.  */
+                      if (strcmp(entry_repos_relpath,
+                                 original_repos_relpath) == 0)
+                        {
+                          is_copied_child = TRUE;
+                          is_mixed_rev = TRUE;
+                        }
+                    }
+                }
+
+              if (is_copied_child)
                 {
-                  if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
-                    return svn_error_return(err);
-                  svn_error_clear(err);
+                  /* We won't be settig the  copyfrom_url, yet need to
+                     clear out the copyfrom_rev. Thus, this node becomes a
+                     child of a copied subtree (rather than its own root).  */
+                  entry->copyfrom_rev = SVN_INVALID_REVNUM;
+
+                  /* Children in a copied subtree are schedule normal
+                     since we don't plan to actually *do* anything with
+                     them. Their operation is implied by ancestors.  */
+                  entry->schedule = svn_wc_schedule_normal;
+
+                  /* And *finally* we turn this entry into the mixed
+                     revision node that it was intended to be. This
+                     node's revision is taken from the copyfrom record
+                     that we spontaneously constructed.  */
+                  if (is_mixed_rev)
+                    entry->revision = original_revision;
                 }
-              else if (parent_root_url != NULL
-                       && strcmp(original_root_url, parent_root_url) == 0)
+              else if (original_repos_relpath != NULL)
+                {
+                  entry->copyfrom_url =
+                    svn_path_url_add_component2(original_root_url,
+                                                original_repos_relpath,
+                                                result_pool);
+                }
+              else
                 {
+                  /* NOTE: if original_repos_relpath == NULL, then the
+                     second call to scan_addition() will not have occurred.
+                     Thus, this use of OP_ROOT_ABSPATH still contains the
+                     original value where we fetched a value for
+                     SCANNED_REPOS_RELPATH.  */
                   const char *relpath_to_entry = svn_dirent_is_child(
                     op_root_abspath, entry_abspath, NULL);
                   const char *entry_repos_relpath = svn_relpath_join(
-                    parent_repos_relpath, relpath_to_entry, iterpool);
+                    scanned_original_relpath, relpath_to_entry, iterpool);
 
-                  /* The copyfrom repos roots matched.
-
-                     Now we look to see if the copyfrom path of the parent
-                     would align with our own path. If so, then it means
-                     this copyfrom was spontaneously created and inserted
-                     for mixed-rev purposes and can be eliminated without
-                     changing the semantics of a mixed-rev copied subtree.
-
-                     See notes/api-errata/wc003.txt for some additional
-                     detail, and potential issues.  */
-                  if (strcmp(entry_repos_relpath, original_repos_relpath) == 0)
-                    {
-                      /* Don't set the copyfrom_url and clear out the
-                         copyfrom_rev. Thus, this node becomes a child
-                         of a copied subtree (rather than its own root).  */
-                      set_copyfrom = FALSE;
-                      entry->copyfrom_rev = SVN_INVALID_REVNUM;
-
-                      /* Children in a copied subtree are schedule normal
-                         since we don't plan to actually *do* anything with
-                         them. Their operation is implied by ancestors.  */
-                      entry->schedule = svn_wc_schedule_normal;
-
-                      /* And *finally* we turn this entry into the mixed
-                         revision node that it was intended to be. This
-                         node's revision is taken from the copyfrom record
-                         that we spontaneously constructed.  */
-                      entry->revision = original_revision;
-                    }
+                  entry->copyfrom_url =
+                    svn_path_url_add_component2(original_root_url,
+                                                entry_repos_relpath,
+                                                result_pool);
                 }
-
-              if (set_copyfrom)
-                entry->copyfrom_url =
-                  svn_path_url_add_component2(original_root_url,
-                                              original_repos_relpath,
-                                              result_pool);
             }
         }
       else if (status == svn_wc__db_status_not_present)

Modified: subversion/trunk/subversion/tests/cmdline/switch_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/switch_tests.py?rev=931449&r1=931448&r2=931449&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/switch_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/switch_tests.py Wed Apr  7 07:05:28 2010
@@ -2545,6 +2545,11 @@ def tree_conflicts_on_switch_2_1(sbox):
     },
   }
 
+  ### D/D1/delta is locally-added during leaf_edit. when tree_del executes,
+  ### it will delete D/D1, and the switch reschedules local D/D1 for
+  ### local-copy from its original revision. however, right now, we cannot
+  ### denote that delta is a local-add rather than a child of that D/D1 copy.
+  ### thus, it appears in the status output as a (M)odified child.
   svntest.actions.deep_trees_run_tests_scheme_for_switch(sbox,
     [ DeepTreesTestCase("local_leaf_edit_incoming_tree_del",
                         leaf_edit,
@@ -2939,7 +2944,7 @@ test_list = [ None,
               tolerate_local_mods,
               tree_conflicts_on_switch_1_1,
               tree_conflicts_on_switch_1_2,
-              tree_conflicts_on_switch_2_1,
+              XFail(tree_conflicts_on_switch_2_1),
               tree_conflicts_on_switch_2_2,
               tree_conflicts_on_switch_3,
               single_file_relocate,

Modified: subversion/trunk/subversion/tests/cmdline/update_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/update_tests.py?rev=931449&r1=931448&r2=931449&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/update_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/update_tests.py Wed Apr  7 07:05:28 2010
@@ -4544,6 +4544,11 @@ def tree_conflicts_on_update_2_1(sbox):
     },
   }
 
+  ### D/D1/delta is locally-added during leaf_edit. when tree_del executes,
+  ### it will delete D/D1, and the update reschedules local D/D1 for
+  ### local-copy from its original revision. however, right now, we cannot
+  ### denote that delta is a local-add rather than a child of that D/D1 copy.
+  ### thus, it appears in the status output as a (M)odified child.
   svntest.actions.deep_trees_run_tests_scheme_for_update(sbox,
     [ DeepTreesTestCase("local_leaf_edit_incoming_tree_del",
                         leaf_edit,
@@ -5152,6 +5157,10 @@ def tree_conflict_uc2_schedule_re_add(sb
 
   # The status of the new and old scenarios should be identical...
   expected_status = get_status(wc2)
+  ### The following fails, as of Apr 6, 2010. The problem is that A/new_file
+  ### has been *added* within a copy, yet the wc_db datastore cannot
+  ### differentiate this from a copied-child. As a result, new_file is
+  ### reported as a (M)odified node, rather than (A)dded.
   svntest.actions.run_and_verify_status(wc2, expected_status)
 
   # ...except for the revision of the root of the WC and iota, because
@@ -5516,13 +5525,13 @@ test_list = [ None,
               restarted_update_should_delete_dir_prop,
               tree_conflicts_on_update_1_1,
               tree_conflicts_on_update_1_2,
-              tree_conflicts_on_update_2_1,
+              XFail(tree_conflicts_on_update_2_1),
               tree_conflicts_on_update_2_2,
               XFail(tree_conflicts_on_update_2_3),
               tree_conflicts_on_update_3,
               update_moves_and_modifies_an_edited_file,
               tree_conflict_uc1_update_deleted_tree,
-              tree_conflict_uc2_schedule_re_add,
+              XFail(tree_conflict_uc2_schedule_re_add),
               set_deep_depth_on_target_with_shallow_children,
               update_wc_of_dir_to_rev_not_containing_this_dir,
               XFail(update_deleted_locked_files),



Mime
View raw message