You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2010/05/30 20:26:13 UTC

svn commit: r949552 - in /subversion/trunk/subversion/libsvn_wc: adm_ops.c entries.c entries.h update_editor.c wc_db.c wc_db.h

Author: rhuijben
Date: Sun May 30 18:26:13 2010
New Revision: 949552

URL: http://svn.apache.org/viewvc?rev=949552&view=rev
Log:
Insert not present switched nodes when adding new file externals, to
reduce the hack called 'file-externals' a bit. This removes some entry
operations and resolves an open entry caching issue triggered in
update_editor.c.

* subversion/libsvn_wc/adm_ops.c
  (svn_wc__set_file_external_location):
    Use svn_wc__db_temp_op_set_file_external for setting the file external.

* subversion/libsvn_wc/entries.c
  (fold_entry): Remove file external support.

* subversion/libsvn_wc/entries.h
  (SVN_WC__ENTRY_MODIFY_FILE_EXTERNAL): Delete macro.

* subversion/libsvn_wc/update_editor.c
  (merge_file): Revert to the old behavior where we expect to see file
    externals as added nodes.

* subversion/libsvn_wc/wc_db.c
  (svn_wc__db_temp_op_set_file_external): New function.

* subversion/libsvn_wc/wc_db.h
  (svn_wc__db_temp_op_set_file_external): New function.

Modified:
    subversion/trunk/subversion/libsvn_wc/adm_ops.c
    subversion/trunk/subversion/libsvn_wc/entries.c
    subversion/trunk/subversion/libsvn_wc/entries.h
    subversion/trunk/subversion/libsvn_wc/update_editor.c
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/libsvn_wc/wc_db.h

Modified: subversion/trunk/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_ops.c?rev=949552&r1=949551&r2=949552&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_ops.c Sun May 30 18:26:13 2010
@@ -2768,28 +2768,33 @@ svn_wc__set_file_external_location(svn_w
                                    const char *repos_root_url,
                                    apr_pool_t *scratch_pool)
 {
-  svn_wc_entry_t entry = { 0 };
+  const char *external_repos_relpath;
+  const svn_opt_revision_t unspecified_rev = { svn_opt_revision_unspecified };
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+  SVN_ERR_ASSERT(!url || svn_uri_is_canonical(url, scratch_pool));
 
   if (url)
     {
-      /* A repository root relative path is stored in the entry. */
-      SVN_ERR_ASSERT(peg_rev);
-      SVN_ERR_ASSERT(rev);
-      entry.file_external_path = url + strlen(repos_root_url);
-      entry.file_external_peg_rev = *peg_rev;
-      entry.file_external_rev = *rev;
+      external_repos_relpath = svn_uri_is_child(repos_root_url, url, NULL);
+      SVN_ERR_ASSERT(external_repos_relpath != NULL);
+
+      external_repos_relpath = svn_path_uri_decode(external_repos_relpath,
+                                                   scratch_pool);
+
+      SVN_ERR_ASSERT(peg_rev != NULL);
+      SVN_ERR_ASSERT(rev != NULL);
     }
   else
     {
-      entry.file_external_path = NULL;
-      entry.file_external_peg_rev.kind = svn_opt_revision_unspecified;
-      entry.file_external_rev.kind = svn_opt_revision_unspecified;
+      external_repos_relpath = NULL;
+      peg_rev = &unspecified_rev;
+      rev = &unspecified_rev;
     }
 
-  SVN_ERR(svn_wc__entry_modify(wc_ctx->db, local_abspath,
-                               svn_node_unknown,
-                               &entry, SVN_WC__ENTRY_MODIFY_FILE_EXTERNAL,
-                               scratch_pool));
+  SVN_ERR(svn_wc__db_temp_op_set_file_external(wc_ctx->db, local_abspath,
+                                               external_repos_relpath, peg_rev,
+                                               rev, scratch_pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/trunk/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/entries.c?rev=949552&r1=949551&r2=949552&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/entries.c (original)
+++ subversion/trunk/subversion/libsvn_wc/entries.c Sun May 30 18:26:13 2010
@@ -2744,16 +2744,7 @@ fold_entry(svn_wc_entry_t *cur_entry,
       cur_entry->keep_local = FALSE;
     }
 
-  /* File externals. */
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_FILE_EXTERNAL)
-    {
-      cur_entry->file_external_path = (entry->file_external_path
-                                       ? apr_pstrdup(pool,
-                                                     entry->file_external_path)
-                                       : NULL);
-      cur_entry->file_external_peg_rev = entry->file_external_peg_rev;
-      cur_entry->file_external_rev = entry->file_external_rev;
-    }
+  /* File externals are no longer passed to entry_modify(). */
 
   return SVN_NO_ERROR;
 }

Modified: subversion/trunk/subversion/libsvn_wc/entries.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/entries.h?rev=949552&r1=949551&r2=949552&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/entries.h (original)
+++ subversion/trunk/subversion/libsvn_wc/entries.h Sun May 30 18:26:13 2010
@@ -80,7 +80,6 @@ svn_error_t *svn_wc__atts_to_entry(svn_w
 #define SVN_WC__ENTRY_MODIFY_PREJFILE           0x00002000
 #define SVN_WC__ENTRY_MODIFY_ABSENT             0x00004000
 /* ### gap  */
-#define SVN_WC__ENTRY_MODIFY_FILE_EXTERNAL      0x00010000
 
 /* ...ORed together with this to mean: just set the schedule to the new
    value, instead of treating the new value as a change of state to be

Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=949552&r1=949551&r2=949552&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Sun May 30 18:26:13 2010
@@ -4263,12 +4263,7 @@ merge_file(svn_skel_t **work_items,
                    conflicts, since this file was added as a place holder to
                    merge externals item from the repository.
 
-     ### Possible entry caching bug?  Before the removal of the access
-     batons a newly added file external caused svn_wc__get_entry to
-     return an entry with entry->schedule=svn_wc_schedule_add (the
-     entry was retrieved from the cache).  Now the svn_wc__get_entry
-     call reads the entries from the database the returned entry is
-     svn_wc_schedule_replace.  2 lines marked ### EBUG below. */
+     ### Newly added file externals have a svn_wc_schedule_add here. */
   if (fb->copied_working_text)
     {
       /* The file was copied here, and it came with both a (new) pristine
@@ -4280,9 +4275,9 @@ merge_file(svn_skel_t **work_items,
       is_locally_modified = TRUE;
     }
   else if (entry && entry->file_external_path
-           && entry->schedule == svn_wc_schedule_replace) /* ###EBUG */
+           && entry->schedule == svn_wc_schedule_add)
     {
-      is_locally_modified = FALSE;
+      is_locally_modified = FALSE; /* ### Or a conflict will be raised */
     }
   else if (! fb->obstruction_found)
     {
@@ -4310,8 +4305,7 @@ merge_file(svn_skel_t **work_items,
       is_locally_modified = FALSE;
     }
 
-  if (entry && entry->schedule == svn_wc_schedule_replace
-      && ! entry->file_external_path)  /* ### EBUG */
+  if (entry && entry->schedule == svn_wc_schedule_replace)
     is_replaced = TRUE;
 
   /* For 'textual' merging, we implement this matrix.
@@ -4363,7 +4357,7 @@ merge_file(svn_skel_t **work_items,
 
               /* ### sheesh. for file externals, there is a WORKING_NODE
                  ### row (during this transitional state), which means the
-                 ### node is reported as "replaced". further, this means
+                 ### node is reported as "added". further, this means
                  ### that the text base will be dropped into the "revert
                  ### base". even after everything stabilizes, the file
                  ### external's base will continue to reside in the revert
@@ -4373,7 +4367,7 @@ merge_file(svn_skel_t **work_items,
                  ### from the revert base for file externals.  */
               if (entry && entry->file_external_path)
                 {
-                  SVN_ERR_ASSERT(entry->schedule == svn_wc_schedule_replace);
+                  SVN_ERR_ASSERT(entry->schedule == svn_wc_schedule_add);
 
                   /* The revert-base will be installed later in this function.
                      To tell the caller to install the new working text from
@@ -4982,22 +4976,20 @@ close_file(void *file_baton,
        ### have a temp API into wc_db.  */
     if (kind != svn_node_none && serialised)
       {
-        const char *file_external_path;
+        const char *file_external_repos_relpath;
         svn_opt_revision_t file_external_peg_rev, file_external_rev;
-        svn_wc_entry_t tmp_entry;
 
-        SVN_ERR(svn_wc__unserialize_file_external(&file_external_path,
+        SVN_ERR(svn_wc__unserialize_file_external(&file_external_repos_relpath,
                                                   &file_external_peg_rev,
                                                   &file_external_rev,
                                                   serialised, pool));
-        tmp_entry.file_external_path = file_external_path;
-        tmp_entry.file_external_peg_rev = file_external_peg_rev;
-        tmp_entry.file_external_rev = file_external_rev;
-        SVN_ERR(svn_wc__entry_modify(eb->db, fb->local_abspath,
-                                     svn_node_file,
-                                     &tmp_entry,
-                                     SVN_WC__ENTRY_MODIFY_FILE_EXTERNAL,
-                                     pool));
+
+        SVN_ERR(svn_wc__db_temp_op_set_file_external(
+                                                  eb->db, fb->local_abspath,
+                                                  file_external_repos_relpath,
+                                                  &file_external_peg_rev,
+                                                  &file_external_rev,
+                                                  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=949552&r1=949551&r2=949552&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Sun May 30 18:26:13 2010
@@ -7544,3 +7544,91 @@ svn_wc__db_temp_remove_subdir_record(svn
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_wc__db_temp_op_set_file_external(svn_wc__db_t *db,
+                                     const char *local_abspath,
+                                     const char *repos_relpath,
+                                     const svn_opt_revision_t *peg_rev,
+                                     const svn_opt_revision_t *rev,
+                                     apr_pool_t *scratch_pool)
+{
+  svn_wc__db_pdh_t *pdh;
+  const char *local_relpath;
+  svn_sqlite__stmt_t *stmt;
+  svn_boolean_t got_row;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+  SVN_ERR_ASSERT(!repos_relpath 
+                 || svn_relpath_is_canonical(repos_relpath, scratch_pool));
+
+  SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&pdh, &local_relpath, db,
+                                             local_abspath,
+                                             svn_sqlite__mode_readwrite,
+                                             scratch_pool, scratch_pool));
+  VERIFY_USABLE_PDH(pdh);
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+                                    STMT_SELECT_BASE_NODE));
+
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
+
+  SVN_ERR(svn_sqlite__step(&got_row, stmt));
+  SVN_ERR(svn_sqlite__reset(stmt));
+
+  if (!got_row)
+    {
+      const char *repos_root_url, *repos_uuid;
+      apr_int64_t repos_id;
+
+      if (!repos_relpath)
+        return SVN_NO_ERROR; /* Don't add a BASE node */
+
+      SVN_ERR(svn_wc__db_scan_base_repos(NULL, &repos_root_url,
+                                         &repos_uuid, db, pdh->local_abspath,
+                                         scratch_pool, scratch_pool));
+
+      SVN_ERR(create_repos_id(&repos_id, repos_root_url, repos_uuid,
+                              pdh->wcroot->sdb, scratch_pool));
+
+      /* ### Insert a switched not present base node. Luckily this hack
+             is not as ugly as the original file externals hack. */
+      SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+                                        STMT_INSERT_BASE_NODE));
+
+      SVN_ERR(svn_sqlite__bindf(stmt, "isisstt",
+                                pdh->wcroot->wc_id,
+                                local_relpath,
+                                repos_id,
+                                repos_relpath,
+                                svn_relpath_dirname(local_relpath,
+                                                    scratch_pool),
+                                presence_map, svn_wc__db_status_not_present,
+                                kind_map, svn_wc__db_kind_file));
+
+      SVN_ERR(svn_sqlite__insert(NULL, stmt));
+    }
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+                                    STMT_UPDATE_FILE_EXTERNAL));
+
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id,
+                          local_relpath));
+
+  if (repos_relpath)
+    {
+      const char *str;
+
+      SVN_ERR(svn_wc__serialize_file_external(&str,
+                                              repos_relpath,
+                                              peg_rev,
+                                              rev,
+                                              scratch_pool));
+
+      SVN_ERR(svn_sqlite__bind_text(stmt, 3, str));
+    }
+
+  flush_entries(pdh);
+
+  return svn_error_return(svn_sqlite__step_done(stmt));
+}

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=949552&r1=949551&r2=949552&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Sun May 30 18:26:13 2010
@@ -2369,6 +2369,15 @@ svn_wc__db_temp_remove_subdir_record(svn
                                      const char *local_abspath,
                                      apr_pool_t *scratch_pool);
 
+/* Set file external information on LOCAL_ABSPATH to REPOS_RELPATH
+   at PEG_REV with revision REV*/
+svn_error_t *
+svn_wc__db_temp_op_set_file_external(svn_wc__db_t *db,
+                                     const char *local_abspath,
+                                     const char *repos_relpath,
+                                     const svn_opt_revision_t *peg_rev,
+                                     const svn_opt_revision_t *rev,
+                                     apr_pool_t *scratch_pool);
 
 /* @} */