subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhuij...@apache.org
Subject svn commit: r1135743 - /subversion/trunk/subversion/libsvn_wc/copy.c
Date Tue, 14 Jun 2011 18:52:22 GMT
Author: rhuijben
Date: Tue Jun 14 18:52:22 2011
New Revision: 1135743

URL: http://svn.apache.org/viewvc?rev=1135743&view=rev
Log:
Resolve issue #3589 "file externals can break commits of WC->WC copies" and
at the same time undo the performance regression this would cause by passing
the checksum and tmpdir from the callers that do a svn_wc__db_read_info()
anyway.

* subversion/libsvn_wc/copy.c
  (copy_pristine_text_if_necessary): Add two arguments to avoid a database
    query. Assume pristines are always keyed by a sha1 checksum.
  (copy_versioned_file): Add two arguments to avoid db lookups. Update caller.
  (copy_versioned_dir): Forward tmpdir_abspath. Fetch checksum for files. Check
    for file externals and don't copy these: neither versioned, nor unversioned.
  (svn_wc_copy3): Update caller.

Modified:
    subversion/trunk/subversion/libsvn_wc/copy.c

Modified: subversion/trunk/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/copy.c?rev=1135743&r1=1135742&r2=1135743&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/copy.c (original)
+++ subversion/trunk/subversion/libsvn_wc/copy.c Tue Jun 14 18:52:22 2011
@@ -129,63 +129,42 @@ static svn_error_t *
 copy_pristine_text_if_necessary(svn_wc__db_t *db,
                                 const char *src_abspath,
                                 const char *dst_abspath,
+                                const char *tmpdir_abspath,
+                                const svn_checksum_t *checksum,
                                 svn_cancel_func_t cancel_func,
                                 void *cancel_baton,
                                 apr_pool_t *scratch_pool)
 {
-  const svn_checksum_t *checksum;
-
-  SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, &checksum, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               db, src_abspath,
-                               scratch_pool, scratch_pool));
-  if (checksum)
-    {
-      svn_boolean_t present;
-      svn_stream_t *src_pristine, *tmp_pristine;
-      const char *tmp_pristine_abspath;
-      const svn_checksum_t *sha1_checksum, *md5_checksum;
-      const char *tmpdir_abspath;
+  svn_boolean_t present;
+  svn_stream_t *src_pristine, *tmp_pristine;
+  const char *tmp_pristine_abspath;
+  const svn_checksum_t *sha1_checksum, *md5_checksum;
+
+  SVN_ERR_ASSERT(checksum->kind == svn_checksum_sha1);
+
+  /* If it's already in DST_ABSPATH's pristine store, we're done. */
+  SVN_ERR(svn_wc__db_pristine_check(&present, db, dst_abspath, checksum,
+                                    scratch_pool));
+  if (present)
+    return SVN_NO_ERROR;
+
+  sha1_checksum = checksum;
+  SVN_ERR(svn_wc__db_pristine_get_md5(&md5_checksum, db,
+                                      src_abspath, checksum,
+                                      scratch_pool, scratch_pool));
 
-      /* If it's already in DST_ABSPATH's pristine store, we're done. */
-      SVN_ERR(svn_wc__db_pristine_check(&present, db, dst_abspath, checksum,
-                                        scratch_pool));
-      if (present)
-        return SVN_NO_ERROR;
-
-      if (checksum->kind == svn_checksum_md5)
-        {
-          md5_checksum = checksum;
-          SVN_ERR(svn_wc__db_pristine_get_sha1(&sha1_checksum, db,
-                                               src_abspath, checksum,
-                                               scratch_pool, scratch_pool));
-        }
-      else
-        {
-          sha1_checksum = checksum;
-          SVN_ERR(svn_wc__db_pristine_get_md5(&md5_checksum, db,
-                                              src_abspath, checksum,
-                                              scratch_pool, scratch_pool));
-        }
-
-      SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmpdir_abspath, db, dst_abspath,
-                                             scratch_pool, scratch_pool));
-
-      SVN_ERR(svn_wc__db_pristine_read(&src_pristine, NULL, db,
-                                       src_abspath, sha1_checksum,
-                                       scratch_pool, scratch_pool));
-      SVN_ERR(svn_stream_open_unique(&tmp_pristine, &tmp_pristine_abspath,
-                                     tmpdir_abspath, svn_io_file_del_none,
-                                     scratch_pool, scratch_pool));
-      SVN_ERR(svn_stream_copy3(src_pristine, tmp_pristine,
-                               cancel_func, cancel_baton,
-                               scratch_pool));
-      SVN_ERR(svn_wc__db_pristine_install(db, tmp_pristine_abspath,
-                                          sha1_checksum, md5_checksum,
-                                          scratch_pool));
-    }
+  SVN_ERR(svn_wc__db_pristine_read(&src_pristine, NULL, db,
+                                   src_abspath, sha1_checksum,
+                                   scratch_pool, scratch_pool));
+  SVN_ERR(svn_stream_open_unique(&tmp_pristine, &tmp_pristine_abspath,
+                                 tmpdir_abspath, svn_io_file_del_none,
+                                 scratch_pool, scratch_pool));
+  SVN_ERR(svn_stream_copy3(src_pristine, tmp_pristine,
+                           cancel_func, cancel_baton,
+                           scratch_pool));
+  SVN_ERR(svn_wc__db_pristine_install(db, tmp_pristine_abspath,
+                                      sha1_checksum, md5_checksum,
+                                      scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -231,6 +210,8 @@ copy_versioned_file(svn_wc__db_t *db,
                     const char *src_abspath,
                     const char *dst_abspath,
                     const char *dst_op_root_abspath,
+                    const char *tmpdir_abspath,
+                    const svn_checksum_t *checksum,
                     svn_boolean_t metadata_only,
                     svn_boolean_t conflicted,
                     svn_cancel_func_t cancel_func,
@@ -241,16 +222,16 @@ copy_versioned_file(svn_wc__db_t *db,
 {
   svn_skel_t *work_items = NULL;
   const char *dir_abspath = svn_dirent_dirname(dst_abspath, scratch_pool);
-  const char *tmpdir_abspath;
-
-  SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmpdir_abspath, db, dst_abspath,
-                                         scratch_pool, scratch_pool));
 
   /* In case we are copying from one WC to another (e.g. an external dir),
      ensure the destination WC has a copy of the pristine text. */
-  SVN_ERR(copy_pristine_text_if_necessary(db, src_abspath, dst_abspath,
-                                          cancel_func, cancel_baton,
-                                          scratch_pool));
+
+  /* Checksum is NULL for local additions */
+  if (checksum != NULL)
+    SVN_ERR(copy_pristine_text_if_necessary(db, src_abspath, dst_abspath,
+                                            tmpdir_abspath, checksum,
+                                            cancel_func, cancel_baton,
+                                            scratch_pool));
 
   /* Prepare a temp copy of the filesystem node.  It is usually a file, but
      copy recursively if it's a dir. */
@@ -376,6 +357,7 @@ copy_versioned_dir(svn_wc__db_t *db,
                    const char *src_abspath,
                    const char *dst_abspath,
                    const char *dst_op_root_abspath,
+                   const char *tmpdir_abspath,
                    svn_boolean_t metadata_only,
                    svn_cancel_func_t cancel_func,
                    void *cancel_baton,
@@ -385,7 +367,6 @@ copy_versioned_dir(svn_wc__db_t *db,
 {
   svn_skel_t *work_items = NULL;
   const char *dir_abspath = svn_dirent_dirname(dst_abspath, scratch_pool);
-  const char *tmpdir_abspath;
   const apr_array_header_t *versioned_children;
   apr_hash_t *disk_children;
   svn_node_kind_t disk_kind;
@@ -397,10 +378,6 @@ copy_versioned_dir(svn_wc__db_t *db,
     {
       const char *tmp_dst_abspath;
 
-      SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmpdir_abspath, db,
-                                             dst_abspath,
-                                             scratch_pool, scratch_pool));
-
       SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &disk_kind, src_abspath,
                              tmpdir_abspath, FALSE, /* recursive */
                              cancel_func, cancel_baton, scratch_pool));
@@ -451,6 +428,7 @@ copy_versioned_dir(svn_wc__db_t *db,
       svn_wc__db_kind_t child_kind;
       svn_boolean_t op_root;
       svn_boolean_t conflicted;
+      const svn_checksum_t *checksum;
 
       svn_pool_clear(iterpool);
       if (cancel_func)
@@ -461,10 +439,10 @@ copy_versioned_dir(svn_wc__db_t *db,
       child_dst_abspath = svn_dirent_join(dst_abspath, child_name, iterpool);
 
       SVN_ERR(svn_wc__db_read_info(&child_status, &child_kind, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                   NULL, NULL, &conflicted, &op_root, NULL,
-                                   NULL, NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL, NULL, NULL,
+                                   &checksum, NULL, NULL, NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL, &conflicted,
+                                   &op_root, NULL, NULL, NULL, NULL, NULL,
                                    db, child_src_abspath,
                                    iterpool, iterpool));
 
@@ -478,17 +456,38 @@ copy_versioned_dir(svn_wc__db_t *db,
           || child_status == svn_wc__db_status_added)
         {
           /* We have more work to do than just changing the DB */
-         if (child_kind == svn_wc__db_kind_file)
-            SVN_ERR(copy_versioned_file(db,
-                                        child_src_abspath, child_dst_abspath,
-                                        dst_op_root_abspath,
-                                        metadata_only, conflicted,
-                                        cancel_func, cancel_baton, NULL, NULL,
-                                        iterpool));
+          if (child_kind == svn_wc__db_kind_file)
+            {
+              svn_boolean_t skip = FALSE;
+
+              /* We should skip this node if this child is a file external
+                 (issue #3589) */
+              if (child_status == svn_wc__db_status_normal)
+                {
+                  SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, NULL,
+                                                   NULL, NULL, NULL, NULL,
+                                                   NULL, NULL, NULL, NULL,
+                                                   NULL, NULL, &skip,
+                                                   db, src_abspath,
+                                                   scratch_pool,
+                                                   scratch_pool));
+                }
+
+              if (!skip)
+                SVN_ERR(copy_versioned_file(db,
+                                            child_src_abspath,
+                                            child_dst_abspath,
+                                            dst_op_root_abspath,
+                                            tmpdir_abspath, checksum,
+                                            metadata_only, conflicted,
+                                            cancel_func, cancel_baton,
+                                            NULL, NULL,
+                                            iterpool));
+            }
           else if (child_kind == svn_wc__db_kind_dir)
             SVN_ERR(copy_versioned_dir(db,
                                        child_src_abspath, child_dst_abspath,
-                                       dst_op_root_abspath,
+                                       dst_op_root_abspath, tmpdir_abspath,
                                        metadata_only,
                                        cancel_func, cancel_baton, NULL, NULL,
                                        iterpool));
@@ -604,6 +603,8 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
   svn_wc__db_kind_t src_db_kind;
   const char *dstdir_abspath;
   svn_boolean_t conflicted;
+  const svn_checksum_t *checksum;
+  const char *tmpdir_abspath;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath));
   SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath));
@@ -620,7 +621,7 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
 
     err = svn_wc__db_read_info(&src_status, &src_db_kind, NULL, NULL,
                                &src_repos_root_url, &src_repos_uuid, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, &checksum, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, &conflicted,
                                NULL, NULL, NULL, NULL, NULL, NULL,
                                db, src_abspath, scratch_pool, scratch_pool);
@@ -757,10 +758,15 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
                                                         scratch_pool));
     }
 
+  SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmpdir_abspath, db,
+                                         dst_abspath,
+                                         scratch_pool, scratch_pool));
+
   if (src_db_kind == svn_wc__db_kind_file
       || src_db_kind == svn_wc__db_kind_symlink)
     {
       SVN_ERR(copy_versioned_file(db, src_abspath, dst_abspath, dst_abspath,
+                                  tmpdir_abspath, checksum,
                                   metadata_only, conflicted,
                                   cancel_func, cancel_baton,
                                   notify_func, notify_baton,
@@ -769,6 +775,7 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
   else
     {
       SVN_ERR(copy_versioned_dir(db, src_abspath, dst_abspath, dst_abspath,
+                                 tmpdir_abspath,
                                  metadata_only,
                                  cancel_func, cancel_baton,
                                  notify_func, notify_baton,



Mime
View raw message