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 2012/06/29 20:08:17 UTC

svn commit: r1355490 - in /subversion/trunk/subversion/libsvn_wc: wc.h wc_db.c wc_db.h workqueue.c

Author: rhuijben
Date: Fri Jun 29 18:08:15 2012
New Revision: 1355490

URL: http://svn.apache.org/viewvc?rev=1355490&view=rev
Log:
Use the conflict skel to implement svn_wc__db_op_mark_conflict, which can
replace two temp_ops that were specifically designed to fill the old conflict
data.

As we currently install conflict data via the workqueue, some of this code
will have to remain when we bump to a format with conflict skels to
allow executing the workqueue items.

* subversion/libsvn_wc/wc.h
  (SVN_WC__VERSION): Add some documentation for format 30.
  (SVN_WC__USES_CONFLICT_SKELS): New define, to help documenting new code.

* subversion/libsvn_wc/wc_db.c
  (includes): Add conflicts.h.
  (temp_op_set_text_conflict_marker_files,
   temp_op_set_prop_conflict_marker_file): Add prototypes to avoid moving code.
  (mark_conflict): New function.
  (svn_wc__db_op_mark_conflict): Add conflict skel argument. Parse path and
    call mark_conflict().

  (svn_wc__db_temp_op_set_text_conflict_marker_files,
   svn_wc__db_temp_op_set_prop_conflict_marker_file):
     Make static. Remove public suffix and accept a wcroot, local_relpath
     instead of db, local_abspath.

* subversion/libsvn_wc/wc_db.h
  (svn_wc__db_op_mark_conflict): Add argument and documentation.

  (svn_wc__db_temp_op_set_text_conflict_marker_files,
   svn_wc__db_temp_op_set_property_conflict_marker_file): Remove functions.

* subversion/libsvn_wc/workqueue.c
  (includes): Add conflicts.h.
  (run_set_text_conflict_markers,
   run_set_property_conflict_marker): Create conflict skel and install that
     instead of calling a temp_db_op.

Modified:
    subversion/trunk/subversion/libsvn_wc/wc.h
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/libsvn_wc/wc_db.h
    subversion/trunk/subversion/libsvn_wc/workqueue.c

Modified: subversion/trunk/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc.h?rev=1355490&r1=1355489&r2=1355490&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc.h Fri Jun 29 18:08:15 2012
@@ -151,6 +151,9 @@ extern "C" {
  *
  * == 1.7.x shipped with format 29
  *
+ * The bump to 30 switched the conflict storage to a skel inside conflict_data.
+ * Also clears some known invalid state.
+ *
  * Please document any further format changes here.
  */
 
@@ -182,6 +185,9 @@ extern "C" {
 /* A version < this has no work queue (see workqueue.h).  */
 #define SVN_WC__HAS_WORK_QUEUE 13
 
+/* The first version that uses conflict skels for all conflicts */
+#define SVN_WC__USES_CONFLICT_SKELS 30
+
 /* Return true iff error E indicates an "is not a working copy" type
    of error, either because something wasn't a working copy at all, or
    because it's a working copy from a previous version (in need of

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1355490&r1=1355489&r2=1355490&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Fri Jun 29 18:08:15 2012
@@ -42,6 +42,7 @@
 #include "wc-queries.h"
 #include "entries.h"
 #include "lock.h"
+#include "conflicts.h"
 #include "tree_conflicts.h"
 #include "wc_db_private.h"
 #include "workqueue.h"
@@ -306,6 +307,20 @@ set_actual_props(apr_int64_t wc_id,
                  apr_pool_t *scratch_pool);
 
 static svn_error_t *
+temp_op_set_text_conflict_marker_files(svn_wc__db_wcroot_t *wcroot,
+                                       const char *local_relpath,
+                                       const char *old_abspath,
+                                       const char *new_abspath,
+                                       const char *wrk_abspath,
+                                       apr_pool_t *scratch_pool);
+
+static svn_error_t *
+temp_op_set_prop_conflict_marker_file(svn_wc__db_wcroot_t *wcroot,
+                                       const char *local_relpath,
+                                       const char *prej_abspath,
+                                       apr_pool_t *scratch_pool);
+
+static svn_error_t *
 insert_incomplete_children(svn_sqlite__db_t *sdb,
                            apr_int64_t wc_id,
                            const char *local_relpath,
@@ -5169,15 +5184,94 @@ svn_wc__db_op_set_changelist(svn_wc__db_
                                            scratch_pool));
 }
 
+/* Implementation of svn_wc__db_op_mark_conflict() */
+static svn_error_t *
+mark_conflict(svn_wc__db_wcroot_t *wcroot,
+              const char *local_relpath,
+              const svn_skel_t *conflict_skel,
+              apr_pool_t *scratch_pool)
+{
+  svn_boolean_t is_complete;
+
+  SVN_ERR(svn_wc__conflict_skel_is_complete(&is_complete, conflict_skel));
+
+  SVN_ERR_ASSERT(is_complete);
+
+#if SVN_WC__VERSION < SVN_WC__USES_CONFLICT_SKELS
+  if (conflict_skel)
+    {
+      /* Store conflict data in the old locations */
+      svn_error_t *err;
+      const char *mine_abspath;
+      const char *their_old_abspath;
+      const char *their_abspath;
+      svn_wc__db_t *db;
+      const char *local_abspath;
+
+      /* Ugly but temporary hack: obtain a DB for transforming paths.
+         ### Can't use this for a write tranaction or we get a deadlock! */
+
+      SVN_ERR(svn_wc__db_open(&db, NULL, FALSE, FALSE,
+                              scratch_pool, scratch_pool));
+
+      local_abspath = svn_dirent_join(wcroot->abspath, local_relpath,
+                                      scratch_pool);
+    
+      err = svn_wc__conflict_read_text_conflict(&mine_abspath,
+                                                &their_old_abspath,
+                                                &their_abspath,
+                                                db, local_abspath,
+                                                conflict_skel,
+                                                scratch_pool, scratch_pool);
+
+      if (err)
+        svn_error_clear(err);
+      else
+        SVN_ERR(temp_op_set_text_conflict_marker_files(wcroot, local_relpath,
+                                                       their_old_abspath,
+                                                       their_abspath,
+                                                       mine_abspath,
+                                                       scratch_pool));
+
+      err = svn_wc__conflict_read_prop_conflict(&mine_abspath, NULL, NULL,
+                                                NULL, NULL,
+                                                db, local_abspath,
+                                                conflict_skel,
+                                                scratch_pool, scratch_pool);
+
+      if (err)
+        svn_error_clear(err);
+      else
+        SVN_ERR(temp_op_set_prop_conflict_marker_file(wcroot, local_relpath,
+                                                      mine_abspath,
+                                                      scratch_pool));
+
+      SVN_ERR(svn_wc__db_close(db));
+    }
+#else
+  /* And in the new location */
+#endif
+
+  return SVN_NO_ERROR;
+}
 
 svn_error_t *
 svn_wc__db_op_mark_conflict(svn_wc__db_t *db,
                             const char *local_abspath,
+                            const svn_skel_t *conflict_skel,
                             apr_pool_t *scratch_pool)
 {
+  svn_wc__db_wcroot_t *wcroot;
+  const char *local_relpath;
+
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
-  NOT_IMPLEMENTED();
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
+                              local_abspath, scratch_pool, scratch_pool));
+  VERIFY_USABLE_WCROOT(wcroot);
+
+  return svn_error_trace(mark_conflict(wcroot, local_relpath, conflict_skel,
+                                       scratch_pool));
 }
 
 /* Baton for db_op_mark_resolved */
@@ -12562,30 +12656,18 @@ svn_wc__db_temp_op_make_copy(svn_wc__db_
   return SVN_NO_ERROR;
 }
 
-svn_error_t *
-svn_wc__db_temp_op_set_text_conflict_marker_files(svn_wc__db_t *db,
-                                                  const char *local_abspath,
-                                                  const char *old_abspath,
-                                                  const char *new_abspath,
-                                                  const char *wrk_abspath,
-                                                  apr_pool_t *scratch_pool)
+static svn_error_t *
+temp_op_set_text_conflict_marker_files(svn_wc__db_wcroot_t *wcroot,
+                                       const char *local_relpath,
+                                       const char *old_abspath,
+                                       const char *new_abspath,
+                                       const char *wrk_abspath,
+                                       apr_pool_t *scratch_pool)
 {
-  svn_wc__db_wcroot_t *wcroot;
-  const char *local_relpath, *old_relpath, *new_relpath, *wrk_relpath;
+  const char *old_relpath, *new_relpath, *wrk_relpath;
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t got_row;
 
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(old_abspath));
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(new_abspath));
-  /* Binary files usually send NULL */
-  SVN_ERR_ASSERT(!wrk_abspath || svn_dirent_is_absolute(wrk_abspath));
-
-  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
-                                             local_abspath,
-                                             scratch_pool, scratch_pool));
-  VERIFY_USABLE_WCROOT(wcroot);
-
   /* This should be handled in a transaction, but we can assume a db lock
      and this code won't survive until 1.7 */
 
@@ -12622,14 +12704,14 @@ svn_wc__db_temp_op_set_text_conflict_mar
     return svn_error_createf(SVN_ERR_BAD_FILENAME, svn_sqlite__reset(stmt),
                              _("Invalid conflict file '%s' for '%s'"),
                              svn_dirent_local_style(old_abspath, scratch_pool),
-                             svn_dirent_local_style(local_abspath,
+                             path_for_error_message(wcroot, local_relpath,
                                                     scratch_pool));
   new_relpath = svn_dirent_skip_ancestor(wcroot->abspath, new_abspath);
   if (new_relpath == new_abspath)
     return svn_error_createf(SVN_ERR_BAD_FILENAME, svn_sqlite__reset(stmt),
                              _("Invalid conflict file '%s' for '%s'"),
                              svn_dirent_local_style(new_abspath, scratch_pool),
-                             svn_dirent_local_style(local_abspath,
+                             path_for_error_message(wcroot, local_relpath,
                                                     scratch_pool));
 
   if (wrk_abspath)
@@ -12640,7 +12722,7 @@ svn_wc__db_temp_op_set_text_conflict_mar
                                  _("Invalid conflict file '%s' for '%s'"),
                                  svn_dirent_local_style(wrk_abspath,
                                                         scratch_pool),
-                                 svn_dirent_local_style(local_abspath,
+                                 path_for_error_message(wcroot, local_relpath,
                                                         scratch_pool));
     }
   else
@@ -12655,27 +12737,16 @@ svn_wc__db_temp_op_set_text_conflict_mar
   return svn_error_trace(svn_sqlite__step_done(stmt));
 }
 
-
-/* Set the conflict marker information on LOCAL_ABSPATH to the specified
-   values */
-svn_error_t *
-svn_wc__db_temp_op_set_property_conflict_marker_file(svn_wc__db_t *db,
-                                                     const char *local_abspath,
-                                                     const char *prej_abspath,
-                                                     apr_pool_t *scratch_pool)
+static svn_error_t *
+temp_op_set_prop_conflict_marker_file(svn_wc__db_wcroot_t *wcroot,
+                                       const char *local_relpath,
+                                       const char *prej_abspath,
+                                       apr_pool_t *scratch_pool)
 {
-  svn_wc__db_wcroot_t *wcroot;
-  const char *local_relpath, *prej_relpath;
+  const char *prej_relpath;
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t got_row;
 
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
-  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
-                                             local_abspath,
-                                             scratch_pool, scratch_pool));
-  VERIFY_USABLE_WCROOT(wcroot);
-
   /* This should be handled in a transaction, but we can assume a db locl\
      and this code won't survive until 1.7 */
 
@@ -12709,7 +12780,7 @@ svn_wc__db_temp_op_set_property_conflict
     return svn_error_createf(SVN_ERR_BAD_FILENAME, svn_sqlite__reset(stmt),
                              _("Invalid property reject file '%s' for '%s'"),
                              svn_dirent_local_style(prej_abspath, scratch_pool),
-                             svn_dirent_local_style(local_abspath,
+                             path_for_error_message(wcroot, local_relpath,
                                                     scratch_pool));
 
   SVN_ERR(svn_sqlite__bindf(stmt, "iss", wcroot->wc_id,

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1355490&r1=1355489&r2=1355490&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Fri Jun 29 18:08:15 2012
@@ -1499,12 +1499,17 @@ svn_wc__db_op_set_changelist(svn_wc__db_
                              void *cancel_baton,
                              apr_pool_t *scratch_pool);
 
+/* Record CONFLICT on LOCAL_ABSPATH, potentially replacing other conflicts
+   recorded on LOCAL_ABSPATH.
 
-/* ### caller maintains ACTUAL. we're just recording state. */
-/* ### we probably need to record details of the conflict. how? */
+   Users should in most cases pass CONFLICT to another WC_DB call instead of
+   calling svn_wc__db_op_mark_conflict() directly outside a transaction, to
+   allow recording atomically with the operation involved.
+ */
 svn_error_t *
 svn_wc__db_op_mark_conflict(svn_wc__db_t *db,
                             const char *local_abspath,
+                            const svn_skel_t *conflict,
                             apr_pool_t *scratch_pool);
 
 
@@ -2943,25 +2948,6 @@ svn_wc__db_temp_op_make_copy(svn_wc__db_
                              const char *local_abspath,
                              apr_pool_t *scratch_pool);
 
-
-/* Set the conflict marker information on LOCAL_ABSPATH to the specified
-   values */
-svn_error_t *
-svn_wc__db_temp_op_set_text_conflict_marker_files(svn_wc__db_t *db,
-                                                  const char *local_abspath,
-                                                  const char *old_abspath,
-                                                  const char *new_abspath,
-                                                  const char *wrk_abspath,
-                                                  apr_pool_t *scratch_pool);
-
-/* Set the conflict marker information on LOCAL_ABSPATH to the specified
-   values */
-svn_error_t *
-svn_wc__db_temp_op_set_property_conflict_marker_file(svn_wc__db_t *db,
-                                                     const char *local_abspath,
-                                                     const char *prej_abspath,
-                                                     apr_pool_t *scratch_pool);
-
 /* Add a new directory in BASE, whether WORKING nodes exist or not. Mark it
    as incomplete and with revision REVISION. If REPOS_RELPATH is not NULL,
    apply REPOS_RELPATH, REPOS_ROOT_URL and REPOS_UUID.

Modified: subversion/trunk/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.c?rev=1355490&r1=1355489&r2=1355490&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.c Fri Jun 29 18:08:15 2012
@@ -34,6 +34,7 @@
 #include "wc_db.h"
 #include "workqueue.h"
 #include "adm_files.h"
+#include "conflicts.h"
 #include "translate.h"
 
 #include "svn_private_config.h"
@@ -1322,15 +1323,66 @@ run_set_text_conflict_markers(svn_wc__db
                                       scratch_pool, scratch_pool));
     }
 
-  return svn_error_trace(
-          svn_wc__db_temp_op_set_text_conflict_marker_files(db,
-                                                            local_abspath,
-                                                            old_abspath,
-                                                            new_abspath,
-                                                            wrk_abspath,
-                                                            scratch_pool));
-}
+  /* Upgrade scenario: We have a workqueue item that describes how to install a
+     non skel conflict. Fetch all the information we can to create a new style
+     conflict. */
+  /* ### Before format 30 this is/was a common code path as we didn't install
+     ### the conflict directly in the db. It just calls the wc_db code
+     ### to set the right fields. */
+
+  {
+    /* Check if we also have a property conflict... */
+    const apr_array_header_t *conflicts;
+    svn_skel_t *conflict_skel;
+    int i;
+
+    conflict_skel = svn_wc__conflict_skel_create(scratch_pool);
 
+    SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, local_abspath,
+                                      scratch_pool, scratch_pool));
+
+    if (conflicts)
+      for (i = 0; i < conflicts->nelts; i++)
+        {
+          svn_wc_conflict_description2_t *desc =
+                APR_ARRAY_IDX(conflicts, i, svn_wc_conflict_description2_t *);
+          apr_hash_t *prop_names;
+
+          if (desc->kind != svn_wc_conflict_kind_property)
+            continue;
+
+          prop_names = apr_hash_make(scratch_pool);
+
+          /* Add the absolute minimal property conflict */
+          SVN_ERR(svn_wc__conflict_skel_add_prop_conflict(conflict_skel, db,
+                                                          local_abspath,
+                                                          desc->their_abspath,
+                                                          NULL, NULL, NULL,
+                                                          prop_names,
+                                                          scratch_pool,
+                                                          scratch_pool));
+
+          break;
+        }
+
+    SVN_ERR(svn_wc__conflict_skel_add_text_conflict(conflict_skel, db,
+                                                    local_abspath,
+                                                    wrk_abspath,
+                                                    old_abspath,
+                                                    new_abspath,
+                                                    scratch_pool,
+                                                    scratch_pool));
+
+    /* ### Set some 'none' operation? */
+    SVN_ERR(svn_wc__conflict_skel_set_op_update(conflict_skel, NULL,
+                                                scratch_pool,
+                                                scratch_pool));
+
+    SVN_ERR(svn_wc__db_op_mark_conflict(db, local_abspath, conflict_skel,
+                                        scratch_pool));
+  }
+  return SVN_NO_ERROR;
+}
 
 svn_error_t *
 svn_wc__wq_tmp_build_set_text_conflict_markers(svn_skel_t **work_item,
@@ -1409,11 +1461,58 @@ run_set_property_conflict_marker(svn_wc_
                                     local_relpath,
                                     scratch_pool, scratch_pool));
 
-  return svn_error_trace(
-          svn_wc__db_temp_op_set_property_conflict_marker_file(db,
-                                                               local_abspath,
-                                                               prej_abspath,
-                                                               scratch_pool));
+  {
+    /* Check if we also have a property conflict... */
+    const apr_array_header_t *conflicts;
+    svn_skel_t *conflict_skel;
+    int i;
+    apr_hash_t *prop_names;
+
+    conflict_skel = svn_wc__conflict_skel_create(scratch_pool);
+
+    SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, local_abspath,
+                                      scratch_pool, scratch_pool));
+
+    if (conflicts)
+      for (i = 0; i < conflicts->nelts; i++)
+        {
+          svn_wc_conflict_description2_t *desc =
+                APR_ARRAY_IDX(conflicts, i, svn_wc_conflict_description2_t *);
+
+          if (desc->kind != svn_wc_conflict_kind_text)
+            continue;
+
+          /* Add the existing text conflict */
+          SVN_ERR(svn_wc__conflict_skel_add_text_conflict(
+                                                conflict_skel, db,
+                                                local_abspath,
+                                                desc->my_abspath,
+                                                desc->base_abspath,
+                                                desc->their_abspath,
+                                                scratch_pool,
+                                                scratch_pool));
+
+          break;
+        }
+
+    prop_names = apr_hash_make(scratch_pool);
+    SVN_ERR(svn_wc__conflict_skel_add_prop_conflict(conflict_skel, db,
+                                                    local_abspath,
+                                                    prej_abspath,
+                                                    NULL, NULL, NULL,
+                                                    prop_names,
+                                                    scratch_pool,
+                                                    scratch_pool));
+
+    /* ### Set some 'none' operation? */
+    SVN_ERR(svn_wc__conflict_skel_set_op_update(conflict_skel, NULL,
+                                                scratch_pool,
+                                                scratch_pool));
+
+    SVN_ERR(svn_wc__db_op_mark_conflict(db, local_abspath, conflict_skel,
+                                        scratch_pool));
+  }
+  return SVN_NO_ERROR;
 }
 
 svn_error_t *