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/04/13 05:06:33 UTC

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

Author: gstein
Date: Tue Apr 13 03:06:33 2010
New Revision: 933471

URL: http://svn.apache.org/viewvc?rev=933471&view=rev
Log:
Fix a screwy edge case related to the new BASE handling in the update
editor. Sometimes base_get_children() returns a node that isn't really
there(!). We can detect and fix this case.

* subversion/libsvn_wc/update_editor.c:
  (complete_directory): if the expected BASE info is not there, then we'v
    got a faulty "subdir" record that needs to be tossed. do it.

* subversion/libsvn_wc/wc_db.h:
* subversion/libsvn_wc/wc_db.c:
  (svn_wc__db_temp_remove_subdir_record): new function to fix the DB

Modified:
    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/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=933471&r1=933470&r2=933471&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Tue Apr 13 03:06:33 2010
@@ -834,17 +834,46 @@ complete_directory(struct edit_baton *eb
       svn_wc__db_status_t status;
       svn_wc__db_kind_t kind;
       svn_revnum_t revnum;
+      svn_error_t *err;
 
       svn_pool_clear(iterpool);
 
       node_abspath = svn_dirent_join(local_abspath, name, iterpool);
 
-      SVN_ERR(svn_wc__db_base_get_info(&status, &kind, &revnum,
-                                       NULL, NULL, NULL,
-                                       NULL, NULL, NULL,
-                                       NULL, NULL, NULL, NULL, NULL, NULL,
-                                       eb->db, node_abspath,
-                                       iterpool, iterpool));
+      /* ### there is an edge case that we can run into right now: this
+         ### dir can have a "subdir" node in the BASE_NODE, but the
+         ### actual subdir does NOT have a record.
+         ###
+         ### in particular, copy_tests 21 and schedule_tests 10 can create
+         ### this situation. in short: the subdir is rm'd on the disk, and
+         ### a deletion of that directory is committed. a local-add then
+         ### reintroduces the directory and metadata (within WORKING).
+         ### before or after an update, the parent dir has the "subdir"
+         ### BASE_NODE and it is missing in the child. asking for the BASE
+         ### won't return status_obstructed since there is a true subdir
+         ### there now.
+         ###
+         ### at some point in the control flow, we should have removed
+         ### the "subdir" record. maybe there is a good place to remove
+         ### that record (or wait for single-dir). for now, we can correct
+         ### it when we detect it.  */
+      err = svn_wc__db_base_get_info(&status, &kind, &revnum,
+                                     NULL, NULL, NULL,
+                                     NULL, NULL, NULL,
+                                     NULL, NULL, NULL, NULL, NULL, NULL,
+                                     eb->db, node_abspath,
+                                     iterpool, iterpool);
+      if (err)
+        {
+          if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+            return svn_error_return(err);
+
+          svn_error_clear(err);
+
+          SVN_ERR(svn_wc__db_temp_remove_subdir_record(eb->db, node_abspath,
+                                                       iterpool));
+          continue;
+        }
 
       /* ### obsolete comment?
          Any entry still marked as deleted (and not schedule add) can now

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=933471&r1=933470&r2=933471&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Tue Apr 13 03:06:33 2010
@@ -7264,3 +7264,35 @@ svn_wc__db_get_pristine_md5(const svn_ch
   SVN_ERR_ASSERT((*md5_checksum)->kind == svn_checksum_md5);
   return svn_error_return(svn_sqlite__reset(stmt));
 }
+
+
+svn_error_t *
+svn_wc__db_temp_remove_subdir_record(svn_wc__db_t *db,
+                                     const char *local_abspath,
+                                     apr_pool_t *scratch_pool)
+{
+  const char *parent_abspath;
+  const char *name;
+  svn_wc__db_pdh_t *pdh;
+  const char *local_relpath;
+  svn_sqlite__stmt_t *stmt;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
+  svn_dirent_split(local_abspath, &parent_abspath, &name, scratch_pool);
+
+  SVN_ERR(parse_local_abspath(&pdh, &local_relpath, db, local_abspath,
+                              svn_sqlite__mode_readwrite,
+                              scratch_pool, scratch_pool));
+  VERIFY_USABLE_PDH(pdh);
+  
+  SVN_ERR_ASSERT(*local_relpath == '\0');
+
+  /* Delete the NAME row from BASE_NODE.  */
+  SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+                                    STMT_DELETE_BASE_NODE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, name));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=933471&r1=933470&r2=933471&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Tue Apr 13 03:06:33 2010
@@ -2170,6 +2170,13 @@ svn_wc__db_temp_set_base_checksum(svn_wc
                                   apr_pool_t *scratch_pool);
 
 
+/* Remove a stray "subdir" record in the BASE_NODE table.  */
+svn_error_t *
+svn_wc__db_temp_remove_subdir_record(svn_wc__db_t *db,
+                                     const char *local_abspath,
+                                     apr_pool_t *scratch_pool);
+
+
 /* Set *PRISTINE_MD5_CHECKSUM to the MD-5 checksum of a pristine text
    identified by its SHA-1 checksum PRISTINE_SHA1_CHECKSUM. Return an error
    if the pristine text does not exist or its MD5 checksum is not found. */