You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by gs...@apache.org on 2010/05/10 21:10:48 UTC

svn commit: r942851 - in /subversion/trunk/subversion/libsvn_wc: update_editor.c wc_db.c

Author: gstein
Date: Mon May 10 19:10:48 2010
New Revision: 942851

URL: http://svn.apache.org/viewvc?rev=942851&view=rev
Log:
Rebuild svn_wc_add_repos_file4() in terms of svn_wc__db_op_copy_file().
This is now a Proper function, using wc_db as it should.

* subversion/libsvn_wc/update_editor.c:
  (svn_wc_add_repos_file4): gut this thing, removing all the entry usage,
    a couple hacky DB "temp" calls, and the direct queuing of work.
    instead, make the (two) wc_db calls and have it queue the related work.

* subversion/libsvn_wc/wc_db.c:
  (svn_wc__db_op_copy_dir, svn_wc__db_op_copy_file,
      svn_wc__db_op_copy_symlink): correct the handling of ORIGINAL_*. if
    it is nil, then we do NOT want to create/fetch a repos_id.

Modified:
    subversion/trunk/subversion/libsvn_wc/update_editor.c
    subversion/trunk/subversion/libsvn_wc/wc_db.c

Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=942851&r1=942850&r2=942851&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Mon May 10 19:10:48 2010
@@ -5894,7 +5894,12 @@ svn_wc_add_repos_file4(svn_wc_context_t 
   svn_checksum_t *base_checksum;
   struct last_change_info *last_change = NULL;
   const char *source_abspath = NULL;
+  svn_skel_t *all_work_items;
   svn_skel_t *work_item;
+  const char *original_root_url;
+  const char *original_repos_relpath;
+  const char *original_uuid;
+  apr_hash_t *actual_props;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
   SVN_ERR_ASSERT(new_base_contents != NULL);
@@ -5905,20 +5910,36 @@ svn_wc_add_repos_file4(svn_wc_context_t 
 
   /* Fabricate the anticipated new URL of the target and check the
      copyfrom URL to be in the same repository. */
-  {
-    const char *repos_root;
+  if (copyfrom_url != NULL)
+    {
+      const char *relative_url;
 
-    /* Find the repository_root via the parent directory, which
-       is always versioned before this function is called */
-    SVN_ERR(svn_wc__node_get_repos_info(&repos_root, NULL, wc_ctx,
-                                        dir_abspath, TRUE, FALSE, pool, pool));
-
-    if (copyfrom_url && !svn_uri_is_ancestor(repos_root, copyfrom_url))
-      return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-                               _("Copyfrom-url '%s' has different repository"
-                                 " root than '%s'"),
-                                 copyfrom_url, repos_root);
-  }
+      /* Find the repository_root via the parent directory, which
+         is always versioned before this function is called */
+      SVN_ERR(svn_wc__node_get_repos_info(&original_root_url,
+                                          &original_uuid,
+                                          wc_ctx,
+                                          dir_abspath,
+                                          TRUE /* scan_added */,
+                                          FALSE /* scan_deleted */,
+                                          pool, pool));
+
+      if (!svn_uri_is_ancestor(original_root_url, copyfrom_url))
+        return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                                 _("Copyfrom-url '%s' has different repository"
+                                   " root than '%s'"),
+                                 copyfrom_url, original_root_url);
+
+      relative_url = svn_uri_skip_ancestor(original_root_url, copyfrom_url);
+      original_repos_relpath = svn_path_uri_decode(relative_url, pool);
+    }
+  else
+    {
+      original_root_url = NULL;
+      original_repos_relpath = NULL;
+      original_uuid = NULL;
+      copyfrom_rev = SVN_INVALID_REVNUM;  /* Just to be sure.  */
+    }
 
   /* If we're replacing the file then we need to save the destination file's
      original text base and prop base before replacing it. This allows us to
@@ -5971,59 +5992,6 @@ svn_wc_add_repos_file4(svn_wc_context_t 
       }
   }
 
-  /* Schedule this for addition first, before the entry exists.
-   * Otherwise we'll get bounced out with an error about scheduling
-   * an already-versioned item for addition.
-   */
-  {
-    svn_wc_entry_t tmp_entry;
-    int modify_flags = SVN_WC__ENTRY_MODIFY_SCHEDULE;
-
-    tmp_entry.schedule = svn_wc_schedule_add;
-
-    if (copyfrom_url)
-      {
-        SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(copyfrom_rev));
-
-        tmp_entry.copyfrom_url = copyfrom_url;
-        tmp_entry.copyfrom_rev = copyfrom_rev;
-        tmp_entry.copied = TRUE;
-
-        modify_flags |= SVN_WC__ENTRY_MODIFY_COPYFROM_URL
-          | SVN_WC__ENTRY_MODIFY_COPYFROM_REV
-          | SVN_WC__ENTRY_MODIFY_COPIED;
-      }
-
-    SVN_ERR(svn_wc__loggy_entry_modify(&work_item, db, dir_abspath,
-                                       local_abspath, &tmp_entry,
-                                       modify_flags, pool));
-    SVN_ERR(svn_wc__db_wq_add(db, dir_abspath, work_item, pool));
-  }
-
-  /* ### Clear working node status in preparation for writing a new node. */
-  {
-    svn_wc_entry_t tmp_entry;
-
-    tmp_entry.kind = svn_node_file;
-    /* Indicate the file was locally modified and we didn't get to
-       calculate the true value, but we can't set it to UNKNOWN (-1),
-       because that would indicate absense of this value.
-       If it isn't locally modified,
-       we'll overwrite with the actual value later. */
-    tmp_entry.working_size = SVN_WC_ENTRY_WORKING_SIZE_UNKNOWN;
-    /* The same is true for the TEXT_TIME field, except that that doesn't
-       have an explicid 'changed' value, so we set the value to 'undefined'. */
-    tmp_entry.text_time = 0;
-
-    SVN_ERR(svn_wc__loggy_entry_modify(&work_item, db, dir_abspath,
-                                       local_abspath,  &tmp_entry,
-                                       SVN_WC__ENTRY_MODIFY_KIND
-                                         | SVN_WC__ENTRY_MODIFY_TEXT_TIME
-                                         | SVN_WC__ENTRY_MODIFY_WORKING_SIZE,
-                                       pool));
-    SVN_ERR(svn_wc__db_wq_add(db, dir_abspath, work_item, pool));
-  }
-
   /* Update LAST_CHANGE to reflect the entry props in NEW_BASE_PROPS, and
      filter NEW_BASE_PROPS so it contains only regular props. */
   {
@@ -6043,10 +6011,37 @@ svn_wc_add_repos_file4(svn_wc_context_t 
   }
 
   /* Add some work items to install the properties.  */
-  SVN_ERR(svn_wc__install_props(db, local_abspath, svn_wc__db_kind_file,
-                                new_base_props,
-                                new_props ? new_props : new_base_props,
-                                TRUE, pool));
+  {
+    SVN_ERR(build_write_base_props(&all_work_items,
+                                   local_abspath, svn_wc__db_kind_file,
+                                   new_base_props, pool));
+
+    if (new_props == NULL)
+      {
+        actual_props = NULL;
+      }
+    else
+      {
+        apr_array_header_t *prop_diffs;
+
+        SVN_ERR(svn_prop_diffs(&prop_diffs, new_props, new_base_props,
+                               pool));
+        if (prop_diffs->nelts == 0)
+          actual_props = NULL;
+        else
+          actual_props = new_props;
+      }
+
+    /* ### ideally, this would be queued to go along with the call to
+       ### db_op_set_props(), but we need correct ACTUAL props for some
+       ### of the work associated with creation of the WORKING node.
+       ### so... we'll lump it all together, and queue it on the set_props
+       ### (ie. all database state is correct/final).  */
+    SVN_ERR(build_write_actual_props(&work_item, local_abspath,
+                                     svn_wc__db_kind_file,
+                                     actual_props, pool));
+    all_work_items = svn_wc__wq_merge(all_work_items, work_item, pool);
+  }
 
   /* Copy NEW_BASE_CONTENTS into a temporary file so our log can refer to
      it, and set TMP_TEXT_BASE_ABSPATH to its path.  Compute its MD5
@@ -6093,37 +6088,9 @@ svn_wc_add_repos_file4(svn_wc_context_t 
       SVN_ERR(svn_wc__loggy_move(&work_item, db, dir_abspath,
                                  tmp_text_base_abspath, text_base_abspath,
                                  pool));
-      SVN_ERR(svn_wc__db_wq_add(db, dir_abspath, work_item, pool));
-
-      /* ### execute the work items which construct the node, allowing the
-         ### wc_db operation to tweak the WORKING_NODE row. these values
-         ### should be set some other way.  */
-      SVN_ERR(svn_wc__wq_run(db, dir_abspath,
-                             cancel_func, cancel_baton,
-                             pool));
-      SVN_ERR(svn_wc__db_temp_op_set_working_checksum(db, local_abspath,
-                                                      base_checksum, pool));
+      all_work_items = svn_wc__wq_merge(all_work_items, work_item, pool);
     }
 
-  /* ### HACK: The following code should be performed in the same transaction as the install */
-  if (last_change)
-    {
-      /* ### execute the work items which construct the node, allowing the
-         ### wc_db operation to tweak the WORKING_NODE row. these values
-         ### should be set some other way.  */
-      SVN_ERR(svn_wc__wq_run(db, dir_abspath,
-                             cancel_func, cancel_baton,
-                             pool));
-      SVN_ERR(svn_wc__db_temp_op_set_working_last_change(
-                db, local_abspath,
-                last_change->cmt_rev,
-                last_change->cmt_date,
-                last_change->cmt_author,
-                pool));
-    }
-  
-  /* ### /HACK */
-
   /* For added files without NEW_CONTENTS, then generate the working file
      from the provided "pristine" contents.  */
   if (new_contents == NULL && copyfrom_url == NULL)
@@ -6148,11 +6115,7 @@ svn_wc_add_repos_file4(svn_wc_context_t 
                                           FALSE /* use_commit_times */,
                                           record_fileinfo,
                                           pool, pool));
-    /* ### we should pass WORK_ITEM to some wc_db api that constructs
-       ### this new node. but alas, we do so much of this in pieces,
-       ### and not using wc_db apis. so just manually add the work item
-       ### into the queue.  */
-    SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, pool));
+    all_work_items = svn_wc__wq_merge(all_work_items, work_item, pool);
 
     /* If we installed from somewhere besides the official pristine, then
        it is a temporary file, which needs to be removed.  */
@@ -6161,14 +6124,37 @@ svn_wc_add_repos_file4(svn_wc_context_t 
         SVN_ERR(svn_wc__wq_build_file_remove(&work_item,
                                              db, source_abspath,
                                              pool, pool));
-        /* ### we should pass WORK_ITEM to some wc_db api that constructs
-           ### this new node. but alas, we do so much of this in pieces,
-           ### and not using wc_db apis. so just manually add the work item
-           ### into the queue.  */
-        SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, pool));
+        all_work_items = svn_wc__wq_merge(all_work_items, work_item, pool);
       }
   }
 
+  /* ### ideally, we would have a single DB operation, and queue the work
+     ### items on that. for now, we'll queue them with the second call.  */
+
+  SVN_ERR(svn_wc__db_op_copy_file(db, local_abspath,
+                                  new_base_props,
+                                  last_change
+                                    ? last_change->cmt_rev
+                                    : SVN_INVALID_REVNUM,
+                                  last_change ? last_change->cmt_date : 0,
+                                  last_change ? last_change->cmt_author : NULL,
+                                  original_repos_relpath,
+                                  original_root_url,
+                                  original_uuid,
+                                  copyfrom_rev,
+                                  base_checksum,
+                                  NULL /* conflict */,
+                                  NULL /* work_items */,
+                                  pool));
+
+  /* ### if below fails, then the above db change would remain :-(  */
+
+  SVN_ERR(svn_wc__db_op_set_props(db, local_abspath,
+                                  actual_props,
+                                  NULL /* conflict */,
+                                  all_work_items,
+                                  pool));
+
   return svn_error_return(svn_wc__wq_run(db, dir_abspath,
                                          cancel_func, cancel_baton,
                                          pool));

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=942851&r1=942850&r2=942851&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Mon May 10 19:10:48 2010
@@ -1469,6 +1469,7 @@ insert_working_node(void *baton,
   SVN_ERR(svn_sqlite__bind_properties(stmt, 18, piwb->props, scratch_pool));
 
   /* Do not bind 'keep_local' (19).  */
+  /* 'symlink_target' (20) is bound above.  */
 
   SVN_ERR(svn_sqlite__insert(NULL, stmt));
 
@@ -2759,7 +2760,6 @@ svn_wc__db_op_copy_dir(svn_wc__db_t *db,
   svn_wc__db_pdh_t *pdh;
   const char *local_relpath;
   insert_working_baton_t iwb;
-  apr_int64_t original_repos_id;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
   SVN_ERR_ASSERT(props != NULL);
@@ -2775,10 +2775,6 @@ svn_wc__db_op_copy_dir(svn_wc__db_t *db,
                               scratch_pool, scratch_pool));
   VERIFY_USABLE_PDH(pdh);
 
-  SVN_ERR(create_repos_id(&original_repos_id,
-                          original_root_url, original_uuid,
-                          pdh->wcroot->sdb, scratch_pool));
-
   blank_iwb(&iwb);
 
   iwb.presence = svn_wc__db_status_normal;
@@ -2790,11 +2786,17 @@ svn_wc__db_op_copy_dir(svn_wc__db_t *db,
   iwb.changed_rev = changed_rev;
   iwb.changed_date = changed_date;
   iwb.changed_author = changed_author;
-  iwb.original_repos_id = original_repos_id;
-  iwb.original_repos_relpath = original_repos_relpath;
-  iwb.original_revnum = original_revision;
   iwb.moved_here = FALSE;
 
+  if (original_root_url != NULL)
+    {
+      SVN_ERR(create_repos_id(&iwb.original_repos_id,
+                              original_root_url, original_uuid,
+                              pdh->wcroot->sdb, scratch_pool));
+      iwb.original_repos_relpath = original_repos_relpath;
+      iwb.original_revnum = original_revision;
+    }
+
   iwb.children = children;
   iwb.depth = depth;
 
@@ -2853,7 +2855,6 @@ svn_wc__db_op_copy_file(svn_wc__db_t *db
   svn_wc__db_pdh_t *pdh;
   const char *local_relpath;
   insert_working_baton_t iwb;
-  apr_int64_t original_repos_id;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
   SVN_ERR_ASSERT(props != NULL);
@@ -2867,10 +2868,6 @@ svn_wc__db_op_copy_file(svn_wc__db_t *db
                               scratch_pool, scratch_pool));
   VERIFY_USABLE_PDH(pdh);
 
-  SVN_ERR(create_repos_id(&original_repos_id,
-                          original_root_url, original_uuid,
-                          pdh->wcroot->sdb, scratch_pool));
-
   blank_iwb(&iwb);
 
   iwb.presence = svn_wc__db_status_normal;
@@ -2882,11 +2879,17 @@ svn_wc__db_op_copy_file(svn_wc__db_t *db
   iwb.changed_rev = changed_rev;
   iwb.changed_date = changed_date;
   iwb.changed_author = changed_author;
-  iwb.original_repos_id = original_repos_id;
-  iwb.original_repos_relpath = original_repos_relpath;
-  iwb.original_revnum = original_revision;
   iwb.moved_here = FALSE;
 
+  if (original_root_url != NULL)
+    {
+      SVN_ERR(create_repos_id(&iwb.original_repos_id,
+                              original_root_url, original_uuid,
+                              pdh->wcroot->sdb, scratch_pool));
+      iwb.original_repos_relpath = original_repos_relpath;
+      iwb.original_revnum = original_revision;
+    }
+
   iwb.checksum = checksum;
 
   iwb.work_items = work_items;
@@ -2919,7 +2922,6 @@ svn_wc__db_op_copy_symlink(svn_wc__db_t 
   svn_wc__db_pdh_t *pdh;
   const char *local_relpath;
   insert_working_baton_t iwb;
-  apr_int64_t original_repos_id;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
   SVN_ERR_ASSERT(props != NULL);
@@ -2933,10 +2935,6 @@ svn_wc__db_op_copy_symlink(svn_wc__db_t 
                               scratch_pool, scratch_pool));
   VERIFY_USABLE_PDH(pdh);
 
-  SVN_ERR(create_repos_id(&original_repos_id,
-                          original_root_url, original_uuid,
-                          pdh->wcroot->sdb, scratch_pool));
-
   blank_iwb(&iwb);
 
   iwb.presence = svn_wc__db_status_normal;
@@ -2948,11 +2946,17 @@ svn_wc__db_op_copy_symlink(svn_wc__db_t 
   iwb.changed_rev = changed_rev;
   iwb.changed_date = changed_date;
   iwb.changed_author = changed_author;
-  iwb.original_repos_id = original_repos_id;
-  iwb.original_repos_relpath = original_repos_relpath;
-  iwb.original_revnum = original_revision;
   iwb.moved_here = FALSE;
 
+  if (original_root_url != NULL)
+    {
+      SVN_ERR(create_repos_id(&iwb.original_repos_id,
+                              original_root_url, original_uuid,
+                              pdh->wcroot->sdb, scratch_pool));
+      iwb.original_repos_relpath = original_repos_relpath;
+      iwb.original_revnum = original_revision;
+    }
+
   iwb.target = target;
 
   iwb.work_items = work_items;