You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ph...@apache.org on 2011/04/06 21:20:30 UTC

svn commit: r1089593 - in /subversion/trunk/subversion: include/ include/private/ libsvn_wc/ tests/cmdline/

Author: philip
Date: Wed Apr  6 19:20:30 2011
New Revision: 1089593

URL: http://svn.apache.org/viewvc?rev=1089593&view=rev
Log:
Bump working copy format to 27.  There are no schema changes, conflict
files are now stored as relpaths in actual_node rather than as names.
Old WCNG working copies auto-upgrade if there are no conflicts.

* subversion/libsvn_wc/wc.h
  (SVN_WC__VERSION): Bump.

* subversion/include/svn_wc.h
  (struct svn_wc_conflict_description2_t): Rename members, they are now
   abspaths.

* subversion/include/private/svn_wc_private.h
  (svn_wc__cd_to_cd2): Remove.

* subversion/libsvn_wc/props.c
  (svn_wc__get_prejfile_abspath): Get abspath from conflict struct.
  (maybe_generate_propconflict): Store abspaths in conflict struct.
  (svn_wc__merge_props): Pass abspath.

* subversion/libsvn_wc/util.c
  (svn_wc__conflict_description2_dup): Adjust for renamed members.
  (svn_wc__cd2_to_cd): Convert abspaths to names.
  (svn_wc__cd_to_cd2): Remove.
 
* subversion/libsvn_wc/adm_ops.c
  (remove_conflict_file): Rename parameter, it's now an abspath, now
   works for directory property rejects.

* subversion/libsvn_wc/conflicts.c
  (attempt_deletion): Combine name and dir parameters into a single abspath.
  (resolve_conflict_on_node):  Pass abspaths to attempt_deletion, remove code
   that fixed-up non-abspaths.

* subversion/libsvn_wc/questions.c
  (svn_wc__internal_conflicted_p): Use abspaths from conflict struct.

* subversion/libsvn_wc/merge.c
  (setup_text_conflict_desc): Adjust for renamed members.
  (merge_text_file, merge_binary_file): Pass abspaths.

* subversion/libsvn_wc/entries.c
  (read_one_entry): Convert abspaths to names.
  (write_entry): Convert names to relpaths.

* subversion/libsvn_wc/wc_db.c
  (cross_db_copy): Adjust conflict relpaths.
  (revert_list_read, svn_wc__db_read_conflicts): Convert relpaths to abspaths.
  (svn_wc__db_temp_op_set_text_conflict_marker_files): Rename parameters,
   convert abspaths to relpaths.
  (svn_wc__db_temp_op_set_property_conflict_marker_file): Rename parameter,
   convert abspath to relpath.

* subversion/libsvn_wc/wc_db.h
  (svn_wc__db_temp_op_set_text_conflict_marker_files,
   svn_wc__db_temp_op_set_property_conflict_marker_file): Rename parameters.

* subversion/libsvn_wc/node.c
  (svn_wc__node_get_info_bits): Convert abspaths to names.

* subversion/libsvn_wc/workqueue.c
  (maybe_remove_conflict): Combine name and dir parameters into a single
   abspath.
  (run_set_text_conflict_markers,
   run_set_property_conflict_marker): Adjust for renamed members.
  (svn_wc__wq_tmp_build_set_text_conflict_markers,
   svn_wc__wq_tmp_build_set_property_conflict_marker): Rename parameters.

* subversion/libsvn_wc/workqueue.h
  (svn_wc__wq_tmp_build_set_text_conflict_markers,
   svn_wc__wq_tmp_build_set_property_conflict_marker): Rename parameters.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_HAS_ACTUAL_NODES_CONFLICTS): New.

* subversion/libsvn_wc/wc-metadata.sql
  (STMT_UPGRADE_TO_27): New.

* subversion/libsvn_wc/upgrade.c
  (bump_to_27): New.
  (svn_wc__upgrade_sdb): Handle 26-to-27.

* subversion/tests/cmdline/prop_tests.py
  (file_matching_dir_prop_reject): Remove XFAIL, extend to verify conflict
   files are removed by revert.

Modified:
    subversion/trunk/subversion/include/private/svn_wc_private.h
    subversion/trunk/subversion/include/svn_wc.h
    subversion/trunk/subversion/libsvn_wc/adm_ops.c
    subversion/trunk/subversion/libsvn_wc/conflicts.c
    subversion/trunk/subversion/libsvn_wc/entries.c
    subversion/trunk/subversion/libsvn_wc/merge.c
    subversion/trunk/subversion/libsvn_wc/node.c
    subversion/trunk/subversion/libsvn_wc/props.c
    subversion/trunk/subversion/libsvn_wc/questions.c
    subversion/trunk/subversion/libsvn_wc/upgrade.c
    subversion/trunk/subversion/libsvn_wc/util.c
    subversion/trunk/subversion/libsvn_wc/wc-metadata.sql
    subversion/trunk/subversion/libsvn_wc/wc-queries.sql
    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
    subversion/trunk/subversion/libsvn_wc/workqueue.h
    subversion/trunk/subversion/tests/cmdline/prop_tests.py

Modified: subversion/trunk/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_wc_private.h?rev=1089593&r1=1089592&r2=1089593&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_wc_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_wc_private.h Wed Apr  6 19:20:30 2011
@@ -158,14 +158,6 @@ svn_wc__cd2_to_cd(const svn_wc_conflict_
 
 
 /*
- * Convert from svn_wc_conflict_description_t to svn_wc_conflict_description2_t.
- * Allocate the result in RESULT_POOL.
- */
-svn_wc_conflict_description2_t *
-svn_wc__cd_to_cd2(const svn_wc_conflict_description_t *conflict,
-                  apr_pool_t *result_pool);
-
-/*
  * Convert from svn_wc_status3_t to svn_wc_status2_t.
  * Allocate the result in RESULT_POOL.
  */

Modified: subversion/trunk/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_wc.h?rev=1089593&r1=1089592&r2=1089593&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_wc.h (original)
+++ subversion/trunk/subversion/include/svn_wc.h Wed Apr  6 19:20:30 2011
@@ -1666,7 +1666,9 @@ typedef struct svn_wc_conflict_descripti
    * four fulltext files that can be used to interactively resolve the
    * conflict.
    *
-   * ### Are these paths relative to some directory, or absolute?
+   * BASE_ABSPATH, THEIR_ABSPATH and MY_ABSPATH are absolute paths.
+   *
+   * ### Is MERGED_FILE relative to some directory, or absolute?
    *
    * All four files will be in repository-normal form -- LF
    * line endings and contracted keywords.  (If any of these files are
@@ -1680,15 +1682,15 @@ typedef struct svn_wc_conflict_descripti
    * property values are technically binary values, and thus can't
    * always be merged.)
    */
-  const char *base_file;     /* common ancestor of the two files being merged */
+  const char *base_abspath;  /* common ancestor of the two files being merged */
 
   /** their version of the file */
   /* ### BH: For properties this field contains the reference to
              the property rejection (.prej) file */
-  const char *their_file;
+  const char *their_abspath;
 
   /** my locally-edited version of the file */
-  const char *my_file;
+  const char *my_abspath;
 
   /** merged version; may contain conflict markers */
   const char *merged_file;

Modified: subversion/trunk/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_ops.c?rev=1089593&r1=1089592&r2=1089593&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_ops.c Wed Apr  6 19:20:30 2011
@@ -1263,23 +1263,16 @@ svn_wc__register_file_external(svn_wc_co
 */
 
 
-/* Remove conflict file NAME, which may not exist, associated with
- * *LOCAL_ABSPATH and set NOTIFY_REQUIRED to TRUE if the file was
- * present and removed. */
+/* Remove conflict file CONFLICT_ABSPATH, which may not exist, and set
+ * *NOTIFY_REQUIRED to TRUE if the file was present and removed. */
 static svn_error_t *
 remove_conflict_file(svn_boolean_t *notify_required,
-                     const char *name,
+                     const char *conflict_abspath,
                      const char *local_abspath,
                      apr_pool_t *scratch_pool)
 {
-  if (name)
+  if (conflict_abspath)
     {
-      /* ### Doesn't work for dir prop rejects.  Perhaps have relpaths
-             in the database? */
-      const char *conflict_abspath
-        = svn_dirent_join(svn_dirent_dirname(local_abspath, scratch_pool),
-                          name, scratch_pool);
-
       svn_error_t *err = svn_io_remove_file2(conflict_abspath, FALSE,
                                              scratch_pool);
       if (err)

Modified: subversion/trunk/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/conflicts.c?rev=1089593&r1=1089592&r2=1089593&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/trunk/subversion/libsvn_wc/conflicts.c Wed Apr  6 19:20:30 2011
@@ -116,23 +116,20 @@ svn_wc__conflict_skel_add_prop_conflict(
 /*** Resolving a conflict automatically ***/
 
 
-/* Helper for resolve_conflict_on_entry.  Delete the file BASE_NAME in
-   PARENT_DIR if it exists.  Set WAS_PRESENT to TRUE if the file existed,
-   and leave it UNTOUCHED otherwise. */
+/* Helper for resolve_conflict_on_entry.  Delete the file FILE_ABSPATH
+   in if it exists.  Set WAS_PRESENT to TRUE if the file existed, and
+   leave it UNTOUCHED otherwise. */
 static svn_error_t *
-attempt_deletion(const char *parent_dir,
-                 const char *base_name,
+attempt_deletion(const char *file_abspath,
                  svn_boolean_t *was_present,
                  apr_pool_t *scratch_pool)
 {
-  const char *full_path;
   svn_error_t *err;
 
-  if (base_name == NULL)
+  if (file_abspath == NULL)
     return SVN_NO_ERROR;
 
-  full_path = svn_dirent_join(parent_dir, base_name, scratch_pool);
-  err = svn_io_remove_file2(full_path, FALSE, scratch_pool);
+  err = svn_io_remove_file2(file_abspath, FALSE, scratch_pool);
 
   if (err == NULL || !APR_STATUS_IS_ENOENT(err->apr_err))
     {
@@ -203,12 +200,12 @@ resolve_conflict_on_node(svn_wc__db_t *d
 
       if (desc->kind == svn_wc_conflict_kind_text)
         {
-          conflict_old = desc->base_file;
-          conflict_new = desc->their_file;
-          conflict_working = desc->my_file;
+          conflict_old = desc->base_abspath;
+          conflict_new = desc->their_abspath;
+          conflict_working = desc->my_abspath;
         }
       else if (desc->kind == svn_wc_conflict_kind_property)
-        prop_reject_file = desc->their_file;
+        prop_reject_file = desc->their_abspath;
     }
 
   if (kind == svn_wc__db_kind_dir)
@@ -258,23 +255,6 @@ resolve_conflict_on_node(svn_wc__db_t *d
                                                svn_io_file_del_on_close,
                                                pool, pool));
 
-                /* ### If any of these paths isn't absolute, treat it
-                 * ### as relative to CONFLICT_DIR_ABSPATH.
-                 * ### Else we end up erroring out here, e.g. if the file
-                 * ### is just a basename, and does not live in the current
-                 * ### working directory.
-                 * ### The API docs are unclear about whether these paths
-                 * ### must be absolute or not. */
-                if (! svn_dirent_is_absolute(conflict_old))
-                  conflict_old = svn_dirent_join(conflict_dir_abspath,
-                                                 conflict_old, pool);
-                if (! svn_dirent_is_absolute(conflict_working))
-                  conflict_working = svn_dirent_join(conflict_dir_abspath,
-                                                     conflict_working, pool);
-                if (! svn_dirent_is_absolute(conflict_new))
-                  conflict_new = svn_dirent_join(conflict_dir_abspath,
-                                                 conflict_new, pool);
-
                 SVN_ERR(svn_diff_file_diff3_2(&diff,
                                               conflict_old,
                                               conflict_working,
@@ -313,19 +293,15 @@ resolve_conflict_on_node(svn_wc__db_t *d
 
   if (resolve_text)
     {
-      SVN_ERR(attempt_deletion(conflict_dir_abspath, conflict_old,
-                               &found_file, pool));
-      SVN_ERR(attempt_deletion(conflict_dir_abspath, conflict_new,
-                               &found_file, pool));
-      SVN_ERR(attempt_deletion(conflict_dir_abspath, conflict_working,
-                               &found_file, pool));
+      SVN_ERR(attempt_deletion(conflict_old, &found_file, pool));
+      SVN_ERR(attempt_deletion(conflict_new, &found_file, pool));
+      SVN_ERR(attempt_deletion(conflict_working, &found_file, pool));
       resolve_text = conflict_old || conflict_new || conflict_working;
     }
   if (resolve_props)
     {
       if (prop_reject_file != NULL)
-        SVN_ERR(attempt_deletion(conflict_dir_abspath, prop_reject_file,
-                                 &found_file, pool));
+        SVN_ERR(attempt_deletion(prop_reject_file, &found_file, pool));
       else
         resolve_props = FALSE;
     }

Modified: subversion/trunk/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/entries.c?rev=1089593&r1=1089592&r2=1089593&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/entries.c (original)
+++ subversion/trunk/subversion/libsvn_wc/entries.c Wed Apr  6 19:20:30 2011
@@ -900,16 +900,16 @@ read_one_entry(const svn_wc_entry_t **ne
           switch (cd->kind)
             {
             case svn_wc_conflict_kind_text:
-              entry->conflict_old = apr_pstrdup(result_pool,
-                                                cd->base_file);
-              entry->conflict_new = apr_pstrdup(result_pool,
-                                                cd->their_file);
-              entry->conflict_wrk = apr_pstrdup(result_pool,
-                                                cd->my_file);
+              entry->conflict_old = svn_dirent_basename(cd->base_abspath,
+                                                        result_pool);
+              entry->conflict_new = svn_dirent_basename(cd->their_abspath,
+                                                        result_pool);
+              entry->conflict_wrk = svn_dirent_basename(cd->my_abspath,
+                                                        result_pool);
               break;
             case svn_wc_conflict_kind_property:
-              entry->prejfile = apr_pstrdup(result_pool,
-                                            cd->their_file);
+              entry->prejfile = svn_dirent_basename(cd->their_abspath,
+                                                    result_pool);
               break;
             case svn_wc_conflict_kind_tree:
               break;
@@ -1803,15 +1803,34 @@ write_entry(struct write_baton **entry_n
   if (entry->conflict_old)
     {
       actual_node = MAYBE_ALLOC(actual_node, scratch_pool);
-      actual_node->conflict_old = entry->conflict_old;
-      actual_node->conflict_new = entry->conflict_new;
-      actual_node->conflict_working = entry->conflict_wrk;
+      if (parent_relpath && entry->conflict_old)
+        actual_node->conflict_old = svn_relpath_join(parent_relpath,
+                                                     entry->conflict_old,
+                                                     scratch_pool);
+      else
+        actual_node->conflict_old = entry->conflict_old;
+      if (parent_relpath && entry->conflict_new)
+        actual_node->conflict_new = svn_relpath_join(parent_relpath,
+                                                     entry->conflict_new,
+                                                     scratch_pool);
+      else
+        actual_node->conflict_new = entry->conflict_new;
+      if (parent_relpath && entry->conflict_wrk)
+        actual_node->conflict_working = svn_relpath_join(parent_relpath,
+                                                         entry->conflict_wrk,
+                                                         scratch_pool);
+      else
+        actual_node->conflict_working = entry->conflict_wrk;
     }
 
   if (entry->prejfile)
     {
       actual_node = MAYBE_ALLOC(actual_node, scratch_pool);
-      actual_node->prop_reject = entry->prejfile;
+      actual_node->prop_reject = svn_relpath_join((entry->kind == svn_node_dir
+                                                   ? local_relpath
+                                                   : parent_relpath),
+                                                  entry->prejfile,
+                                                  scratch_pool);
     }
 
   if (entry->changelist)

Modified: subversion/trunk/subversion/libsvn_wc/merge.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/merge.c?rev=1089593&r1=1089592&r2=1089593&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/merge.c (original)
+++ subversion/trunk/subversion/libsvn_wc/merge.c Wed Apr  6 19:20:30 2011
@@ -790,9 +790,9 @@ setup_text_conflict_desc(const char *lef
   cdesc->is_binary = FALSE;
   cdesc->mime_type = (mimeprop && mimeprop->value)
                      ? mimeprop->value->data : NULL,
-  cdesc->base_file = left_abspath;
-  cdesc->their_file = right_abspath;
-  cdesc->my_file = detranslated_target;
+  cdesc->base_abspath = left_abspath;
+  cdesc->their_abspath = right_abspath;
+  cdesc->my_abspath = detranslated_target;
   cdesc->merged_file = result_target;
 
   cdesc->src_left_version = left_version;
@@ -1031,9 +1031,7 @@ merge_text_file(svn_skel_t **work_items,
            * svn_wc__wq_tmp_build_set_text_conflict_markers()'s doc string. */
           SVN_ERR(svn_wc__wq_tmp_build_set_text_conflict_markers(
                             &work_item, db, target_abspath,
-                            svn_dirent_basename(left_copy, NULL),
-                            svn_dirent_basename(right_copy, NULL),
-                            svn_dirent_basename(target_copy, NULL),
+                            left_copy, right_copy, target_copy,
                             result_pool, scratch_pool));
           *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
         }
@@ -1108,7 +1106,6 @@ merge_binary_file(svn_skel_t **work_item
   /* ### when making the binary-file backups, should we be honoring
      keywords and eol stuff?   */
   const char *left_copy, *right_copy;
-  const char *left_base, *right_base;
   const char *merge_dirpath, *merge_filename;
   const char *conflict_wrk;
   svn_skel_t *work_item;
@@ -1260,10 +1257,8 @@ merge_binary_file(svn_skel_t **work_item
   if (strcmp(target_abspath, detranslated_target_abspath) != 0)
     {
       /* Create a .mine file too */
-      const char *mine_copy;
-
       SVN_ERR(svn_io_open_uniquely_named(NULL,
-                                         &mine_copy,
+                                         &conflict_wrk,
                                          merge_dirpath,
                                          merge_filename,
                                          target_label,
@@ -1271,28 +1266,20 @@ merge_binary_file(svn_skel_t **work_item
                                          pool, pool));
       SVN_ERR(svn_wc__wq_build_file_move(work_items, db,
                                          detranslated_target_abspath,
-                                         mine_copy,
+                                         conflict_wrk,
                                          pool, result_pool));
-
-      mine_copy = svn_dirent_is_child(merge_dirpath,
-                                      mine_copy, pool);
-      conflict_wrk = mine_copy;
     }
   else
     {
       conflict_wrk = NULL;
     }
 
-  /* Derive the basenames of the backup files. */
-  left_base = svn_dirent_basename(left_copy, pool);
-  right_base = svn_dirent_basename(right_copy, pool);
-
   /* Mark target_abspath's entry as "Conflicted", and start tracking
      the backup files in the entry as well. */
   SVN_ERR(svn_wc__wq_tmp_build_set_text_conflict_markers(&work_item,
                                                          db, target_abspath,
-                                                         left_base,
-                                                         right_base,
+                                                         left_copy,
+                                                         right_copy,
                                                          conflict_wrk,
                                                          result_pool,
                                                          scratch_pool));

Modified: subversion/trunk/subversion/libsvn_wc/node.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/node.c?rev=1089593&r1=1089592&r2=1089593&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/node.c (original)
+++ subversion/trunk/subversion/libsvn_wc/node.c Wed Apr  6 19:20:30 2011
@@ -1469,18 +1469,22 @@ svn_wc__node_get_info_bits(apr_time_t *t
             {
             case svn_wc_conflict_kind_text:
               if (conflict_old)
-                *conflict_old = apr_pstrdup(result_pool, cd->base_file);
+                *conflict_old = svn_dirent_basename(cd->base_abspath,
+                                                    result_pool);
 
               if (conflict_new)
-                *conflict_new = apr_pstrdup(result_pool, cd->their_file);
+                *conflict_new = svn_dirent_basename(cd->their_abspath,
+                                                    result_pool);
 
               if (conflict_wrk)
-                *conflict_wrk = apr_pstrdup(result_pool, cd->my_file);
+                *conflict_wrk = svn_dirent_basename(cd->my_abspath,
+                                                    result_pool);
               break;
 
             case svn_wc_conflict_kind_property:
               if (prejfile)
-                *prejfile = apr_pstrdup(result_pool, cd->their_file);
+                *prejfile = svn_dirent_basename(cd->their_abspath,
+                                                result_pool);
               break;
             case svn_wc_conflict_kind_tree:
               break;

Modified: subversion/trunk/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/props.c?rev=1089593&r1=1089592&r2=1089593&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/props.c (original)
+++ subversion/trunk/subversion/libsvn_wc/props.c Wed Apr  6 19:20:30 2011
@@ -93,8 +93,9 @@ append_prop_conflict(svn_stream_t *strea
 }
 
 
-/* Get the reject file for LOCAL_ABSPATH in DB.  Set *REJECT_FILE to the
-   name of that file, or to NULL if no such file exists. */
+/* Get the property reject file for LOCAL_ABSPATH in DB.  Set
+   *PREJFILE_ABSPATH to the name of that file, or to NULL if no such
+   file is named.  The file may, or may not, exist on disk. */
 svn_error_t *
 svn_wc__get_prejfile_abspath(const char **prejfile_abspath,
                              svn_wc__db_t *db,
@@ -115,18 +116,7 @@ svn_wc__get_prejfile_abspath(const char 
 
       if (cd->kind == svn_wc_conflict_kind_property)
         {
-          if (strcmp(cd->their_file,
-                     SVN_WC__THIS_DIR_PREJ SVN_WC__PROP_REJ_EXT) == 0)
-            *prejfile_abspath = svn_dirent_join(
-                                  local_abspath,
-                                  SVN_WC__THIS_DIR_PREJ SVN_WC__PROP_REJ_EXT,
-                                  result_pool);
-          else
-            *prejfile_abspath = svn_dirent_join(
-                                  svn_dirent_dirname(local_abspath,
-                                                     scratch_pool),
-                                  cd->their_file,
-                                  result_pool);
+          *prejfile_abspath = apr_pstrdup(result_pool, cd->their_abspath);
           return SVN_NO_ERROR;
         }
     }
@@ -753,14 +743,24 @@ maybe_generate_propconflict(svn_boolean_
 
   /* Create a tmpfile for each of the string_t's we've got.  */
   if (working_val)
-    SVN_ERR(svn_io_write_unique(&cdesc->my_file, dirpath, working_val->data,
-                                working_val->len,
-                                svn_io_file_del_on_pool_cleanup, filepool));
+    {
+      const char *file_name;
+
+      SVN_ERR(svn_io_write_unique(&file_name, dirpath, working_val->data,
+                                  working_val->len,
+                                  svn_io_file_del_on_pool_cleanup, filepool));
+      cdesc->my_abspath = svn_dirent_join(dirpath, file_name, filepool);
+    }
 
   if (new_val)
-    SVN_ERR(svn_io_write_unique(&cdesc->their_file, dirpath, new_val->data,
-                                new_val->len, svn_io_file_del_on_pool_cleanup,
-                                filepool));
+    {
+      const char *file_name;
+
+      SVN_ERR(svn_io_write_unique(&file_name, dirpath, new_val->data,
+                                  new_val->len, svn_io_file_del_on_pool_cleanup,
+                                  filepool));
+      cdesc->their_abspath = svn_dirent_join(dirpath, file_name, filepool);
+    }
 
   if (!base_val && !old_val)
     {
@@ -780,15 +780,18 @@ maybe_generate_propconflict(svn_boolean_
          conflict-callback can still attempt a 3-way merge. */
 
       const svn_string_t *the_val = base_val ? base_val : old_val;
+      const char *file_name;
 
-      SVN_ERR(svn_io_write_unique(&cdesc->base_file, dirpath, the_val->data,
+      SVN_ERR(svn_io_write_unique(&file_name, dirpath, the_val->data,
                                   the_val->len, svn_io_file_del_on_pool_cleanup,
                                   filepool));
+      cdesc->base_abspath = svn_dirent_join(dirpath, file_name, filepool);
     }
 
   else  /* base and old are both non-NULL */
     {
       const svn_string_t *the_val;
+      const char *file_name;
 
       if (! svn_string_compare(base_val, old_val))
         {
@@ -816,9 +819,10 @@ maybe_generate_propconflict(svn_boolean_
           the_val = base_val;
         }
 
-      SVN_ERR(svn_io_write_unique(&cdesc->base_file, dirpath, the_val->data,
+      SVN_ERR(svn_io_write_unique(&file_name, dirpath, the_val->data,
                                   the_val->len, svn_io_file_del_on_pool_cleanup,
                                   filepool));
+      cdesc->base_abspath = svn_dirent_join(dirpath, file_name, filepool);
 
       if (working_val && new_val)
         {
@@ -1576,9 +1580,7 @@ svn_wc__merge_props(svn_wc_notify_state_
 
         SVN_ERR(svn_wc__wq_tmp_build_set_property_conflict_marker(
                                           &work_item,
-                                          db, local_abspath,
-                                          svn_dirent_basename(reject_path,
-                                                              NULL),
+                                          db, local_abspath, reject_path,
                                           scratch_pool, scratch_pool));
 
         SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, scratch_pool));

Modified: subversion/trunk/subversion/libsvn_wc/questions.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/questions.c?rev=1089593&r1=1089592&r2=1089593&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/questions.c (original)
+++ subversion/trunk/subversion/libsvn_wc/questions.c Wed Apr  6 19:20:30 2011
@@ -427,7 +427,6 @@ svn_wc__internal_conflicted_p(svn_boolea
   svn_wc__db_kind_t node_kind;
   const apr_array_header_t *conflicts;
   int i;
-  const char* dir_path;
   svn_boolean_t conflicted;
 
   SVN_ERR(svn_wc__db_read_info(NULL, &node_kind, NULL, NULL, NULL, NULL,
@@ -438,11 +437,6 @@ svn_wc__internal_conflicted_p(svn_boolea
                                db, local_abspath, scratch_pool,
                                scratch_pool));
 
-  if (node_kind == svn_wc__db_kind_dir)
-    dir_path = local_abspath;
-  else
-    dir_path = svn_dirent_dirname(local_abspath, scratch_pool);
-
   if (text_conflicted_p)
     *text_conflicted_p = FALSE;
   if (prop_conflicted_p)
@@ -453,6 +447,7 @@ svn_wc__internal_conflicted_p(svn_boolea
   if (!conflicted)
     return SVN_NO_ERROR;
 
+
   SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, local_abspath,
                                     scratch_pool, scratch_pool));
 
@@ -474,12 +469,10 @@ svn_wc__internal_conflicted_p(svn_boolea
             if (!text_conflicted_p || *text_conflicted_p)
               break;
 
-            if (cd->base_file)
+            if (cd->base_abspath)
               {
-                const char *path = svn_dirent_join(dir_path, cd->base_file,
-                                                   scratch_pool);
-
-                SVN_ERR(svn_io_check_path(path, &kind, scratch_pool));
+                SVN_ERR(svn_io_check_path(cd->base_abspath, &kind,
+                                          scratch_pool));
 
                 *text_conflicted_p = (kind == svn_node_file);
 
@@ -487,12 +480,10 @@ svn_wc__internal_conflicted_p(svn_boolea
                   break;
               }
 
-            if (cd->their_file)
+            if (cd->their_abspath)
               {
-                const char *path = svn_dirent_join(dir_path, cd->their_file,
-                                                   scratch_pool);
-
-                SVN_ERR(svn_io_check_path(path, &kind, scratch_pool));
+                SVN_ERR(svn_io_check_path(cd->their_abspath, &kind,
+                                          scratch_pool));
 
                 *text_conflicted_p = (kind == svn_node_file);
 
@@ -500,12 +491,10 @@ svn_wc__internal_conflicted_p(svn_boolea
                   break;
               }
 
-            if (cd->my_file)
+            if (cd->my_abspath)
               {
-                const char *path = svn_dirent_join(dir_path, cd->my_file,
-                                                   scratch_pool);
-
-                SVN_ERR(svn_io_check_path(path, &kind, scratch_pool));
+                SVN_ERR(svn_io_check_path(cd->my_abspath, &kind,
+                                          scratch_pool));
 
                 *text_conflicted_p = (kind == svn_node_file);
               }
@@ -515,12 +504,10 @@ svn_wc__internal_conflicted_p(svn_boolea
             if (!prop_conflicted_p || *prop_conflicted_p)
               break;
 
-            if (cd->their_file)
+            if (cd->their_abspath)
               {
-                const char *path = svn_dirent_join(dir_path, cd->their_file,
-                                                   scratch_pool);
-
-                SVN_ERR(svn_io_check_path(path, &kind, scratch_pool));
+                SVN_ERR(svn_io_check_path(cd->their_abspath, &kind,
+                                          scratch_pool));
 
                 *prop_conflicted_p = (kind == svn_node_file);
               }

Modified: subversion/trunk/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/upgrade.c?rev=1089593&r1=1089592&r2=1089593&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/trunk/subversion/libsvn_wc/upgrade.c Wed Apr  6 19:20:30 2011
@@ -1152,6 +1152,27 @@ bump_to_26(void *baton, svn_sqlite__db_t
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+bump_to_27(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
+{
+  const char *wcroot_abspath = ((struct bump_baton *)baton)->wcroot_abspath;
+  svn_sqlite__stmt_t *stmt;
+  svn_boolean_t have_row;
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                    STMT_HAS_ACTUAL_NODES_CONFLICTS));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+  SVN_ERR(svn_sqlite__reset(stmt));
+  if (have_row)
+    return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                             _("The working copy at '%s' is format 26 with "
+                               "conflicts; use a format 26 client to resolve "
+                               "before using this client"),
+                             wcroot_abspath);
+  SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_27));
+  return SVN_NO_ERROR;
+}
+
 
 struct upgrade_data_t {
   svn_sqlite__db_t *sdb;
@@ -1426,6 +1447,12 @@ svn_wc__upgrade_sdb(int *result_format,
         *result_format = 26;
         /* FALLTHROUGH  */
 
+      case 26:
+        SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_27, &bb,
+                                             scratch_pool));
+        *result_format = 27;
+        /* FALLTHROUGH  */
+
       /* ### future bumps go here.  */
 #if 0
       case XXX-1:

Modified: subversion/trunk/subversion/libsvn_wc/util.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/util.c?rev=1089593&r1=1089592&r2=1089593&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/util.c (original)
+++ subversion/trunk/subversion/libsvn_wc/util.c Wed Apr  6 19:20:30 2011
@@ -326,12 +326,12 @@ svn_wc__conflict_description2_dup(const 
     new_conflict->property_name = apr_pstrdup(pool, conflict->property_name);
   if (conflict->mime_type)
     new_conflict->mime_type = apr_pstrdup(pool, conflict->mime_type);
-  if (conflict->base_file)
-    new_conflict->base_file = apr_pstrdup(pool, conflict->base_file);
-  if (conflict->their_file)
-    new_conflict->their_file = apr_pstrdup(pool, conflict->their_file);
-  if (conflict->my_file)
-    new_conflict->my_file = apr_pstrdup(pool, conflict->my_file);
+  if (conflict->base_abspath)
+    new_conflict->base_abspath = apr_pstrdup(pool, conflict->base_abspath);
+  if (conflict->their_abspath)
+    new_conflict->their_abspath = apr_pstrdup(pool, conflict->their_abspath);
+  if (conflict->my_abspath)
+    new_conflict->my_abspath = apr_pstrdup(pool, conflict->my_abspath);
   if (conflict->merged_file)
     new_conflict->merged_file = apr_pstrdup(pool, conflict->merged_file);
   if (conflict->src_left_version)
@@ -429,12 +429,12 @@ svn_wc__cd2_to_cd(const svn_wc_conflict_
         new_conflict->mime_type = conflict->mime_type
                               ? apr_pstrdup(result_pool, conflict->mime_type)
                               : NULL;
-        new_conflict->base_file = apr_pstrdup(result_pool,
-                                              conflict->base_file);
-        new_conflict->their_file = apr_pstrdup(result_pool,
-                                               conflict->their_file);
-        new_conflict->my_file = apr_pstrdup(result_pool,
-                                            conflict->my_file);
+        new_conflict->base_file = svn_dirent_basename(conflict->base_abspath,
+                                                      result_pool);
+        new_conflict->their_file = svn_dirent_basename(conflict->their_abspath,
+                                                       result_pool);
+        new_conflict->my_file = svn_dirent_basename(conflict->my_abspath,
+                                                    result_pool);
         new_conflict->merged_file = conflict->merged_file
                                     ? apr_pstrdup(result_pool,
                                                   conflict->merged_file)
@@ -453,63 +453,6 @@ svn_wc__cd2_to_cd(const svn_wc_conflict_
 }
 
 
-svn_wc_conflict_description2_t *
-svn_wc__cd_to_cd2(const svn_wc_conflict_description_t *conflict,
-                  apr_pool_t *result_pool)
-{
-  svn_wc_conflict_description2_t *new_conflict;
-
-  if (conflict == NULL)
-    return NULL;
-
-  new_conflict = apr_pcalloc(result_pool, sizeof(*new_conflict));
-
-  svn_error_clear(
-    svn_dirent_get_absolute(&new_conflict->local_abspath, conflict->path,
-                            result_pool));
-  new_conflict->node_kind = conflict->node_kind;
-  new_conflict->kind = conflict->kind;
-  new_conflict->action = conflict->action;
-  new_conflict->reason = conflict->reason;
-  if (conflict->src_left_version)
-    new_conflict->src_left_version =
-          svn_wc_conflict_version_dup(conflict->src_left_version, result_pool);
-  if (conflict->src_right_version)
-    new_conflict->src_right_version =
-          svn_wc_conflict_version_dup(conflict->src_right_version, result_pool);
-
-  switch (conflict->kind)
-    {
-      case svn_wc_conflict_kind_property:
-        new_conflict->property_name = apr_pstrdup(result_pool,
-                                                  conflict->property_name);
-        /* Falling through. */
-
-      case svn_wc_conflict_kind_text:
-        new_conflict->is_binary = conflict->is_binary;
-        new_conflict->mime_type = conflict->mime_type
-                              ? apr_pstrdup(result_pool, conflict->mime_type)
-                              : NULL;
-        new_conflict->base_file = apr_pstrdup(result_pool,
-                                              conflict->base_file);
-        new_conflict->their_file = apr_pstrdup(result_pool,
-                                               conflict->their_file);
-        new_conflict->my_file = apr_pstrdup(result_pool,
-                                            conflict->my_file);
-        new_conflict->merged_file = conflict->merged_file
-                                    ? apr_pstrdup(result_pool,
-                                                  conflict->merged_file)
-                                    : NULL;
-        break;
-
-      case svn_wc_conflict_kind_tree:
-        new_conflict->operation = conflict->operation;
-        break;
-    }
-
-  return new_conflict;
-}
-
 svn_error_t *
 svn_wc__status2_from_3(svn_wc_status2_t **status,
                        const svn_wc_status3_t *old_status,

Modified: subversion/trunk/subversion/libsvn_wc/wc-metadata.sql
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-metadata.sql?rev=1089593&r1=1089592&r2=1089593&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-metadata.sql Wed Apr  6 19:20:30 2011
@@ -642,6 +642,15 @@ PRAGMA user_version = 26;
 
 /* ------------------------------------------------------------------------- */
 
+/* Format 27 involves no schema changes, it introduces stores
+   conflict files as relpaths rather than names in ACTUAL_NODE. */
+
+-- STMT_UPGRADE_TO_27
+PRAGMA user_version = 27;
+
+
+/* ------------------------------------------------------------------------- */
+
 /* Format YYY introduces new handling for conflict information.  */
 -- format: YYY
 

Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1089593&r1=1089592&r2=1089593&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Wed Apr  6 19:20:30 2011
@@ -913,6 +913,12 @@ WHERE wc_id = ?1 AND local_relpath = ?2 
 -- STMT_HAS_WORKING_NODES
 SELECT 1 FROM nodes WHERE op_depth > 0
 
+-- STMT_HAS_ACTUAL_NODES_CONFLICTS
+SELECT 1 FROM actual_node
+WHERE NOT ((prop_reject IS NULL) AND (conflict_old IS NULL)
+           AND (conflict_new IS NULL) AND (conflict_working IS NULL)
+           AND (tree_conflict_data IS NULL))
+
 -- STMT_UPDATE_CHECKSUM
 UPDATE nodes SET checksum = ?4
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3

Modified: subversion/trunk/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc.h?rev=1089593&r1=1089592&r2=1089593&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc.h Wed Apr  6 19:20:30 2011
@@ -140,12 +140,15 @@ extern "C" {
  *
  * The change from 25 to 26 introduced a NODES_BASE view.
  *
+ * The change from 26 to 27 stored conflict files as relpaths rather
+ * than basenames.
+ *
  * == 1.7.x shipped with format ???
  *
  * Please document any further format changes here.
  */
 
-#define SVN_WC__VERSION 26
+#define SVN_WC__VERSION 27
 
 
 /* Formats <= this have no concept of "revert text-base/props".  */

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1089593&r1=1089592&r2=1089593&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Wed Apr  6 19:20:30 2011
@@ -2264,23 +2264,46 @@ cross_db_copy(svn_wc__db_wcroot_t *src_w
       const char *changelist = svn_sqlite__column_text(stmt, 1, scratch_pool);
       const char *conflict_old = svn_sqlite__column_text(stmt, 2, scratch_pool);
       const char *conflict_new = svn_sqlite__column_text(stmt, 3, scratch_pool);
-      const char *conflict_working = svn_sqlite__column_text(stmt, 4,
-                                                             scratch_pool);
+      const char *conflict_wrk = svn_sqlite__column_text(stmt, 4, scratch_pool);
       const char *tree_conflict_data = svn_sqlite__column_text(stmt, 5,
                                                                scratch_pool);
       apr_size_t props_size;
-
       /* No need to parse the properties when simply copying. */
       const char *properties = svn_sqlite__column_blob(stmt, 6, &props_size,
                                                        scratch_pool);
+
       SVN_ERR(svn_sqlite__reset(stmt));
+
+      if (prop_reject)
+        prop_reject = svn_relpath_join(dst_relpath,
+                                       svn_relpath_skip_ancestor(src_relpath,
+                                                                 prop_reject),
+                                       scratch_pool);
+      if (conflict_old)
+        conflict_old = svn_relpath_join(dst_relpath,
+                                        svn_relpath_skip_ancestor(src_relpath,
+                                                                  conflict_old),
+                                        scratch_pool);
+      if (conflict_new)
+        conflict_new = svn_relpath_join(dst_relpath,
+                                        svn_relpath_skip_ancestor(src_relpath,
+                                                                  conflict_new),
+                                        scratch_pool);
+      if (conflict_wrk)
+        conflict_wrk = svn_relpath_join(dst_relpath,
+                                        svn_relpath_skip_ancestor(src_relpath,
+                                                                  conflict_wrk),
+                                        scratch_pool);
+
+      /* ### Do we need to adjust relpaths in tree conflict data? */
+
       SVN_ERR(svn_sqlite__get_statement(&stmt, dst_wcroot->sdb,
                                         STMT_INSERT_ACTUAL_NODE));
       SVN_ERR(svn_sqlite__bindf(stmt, "issbssssss",
                                 dst_wcroot->wc_id, dst_relpath,
                                 svn_relpath_dirname(dst_relpath, scratch_pool),
                                 properties, props_size,
-                                conflict_old, conflict_new, conflict_working,
+                                conflict_old, conflict_new, conflict_wrk,
                                 prop_reject, changelist, tree_conflict_data));
       SVN_ERR(svn_sqlite__step(&have_row, stmt));
     }
@@ -3991,10 +4014,35 @@ revert_list_read(void *baton,
   if (have_row)
     {
       *(b->reverted) = !svn_sqlite__column_is_null(stmt, 4);
-      *(b->conflict_new) = svn_sqlite__column_text(stmt, 0, b->result_pool);
-      *(b->conflict_old) = svn_sqlite__column_text(stmt, 1, b->result_pool);
-      *(b->conflict_working) = svn_sqlite__column_text(stmt, 2, b->result_pool);
-      *(b->prop_reject) = svn_sqlite__column_text(stmt, 3, b->result_pool);
+      if (svn_sqlite__column_is_null(stmt, 0))
+        *(b->conflict_new) = NULL;
+      else
+        *(b->conflict_new) = svn_dirent_join(wcroot->abspath,
+                                             svn_sqlite__column_text(stmt, 0,
+                                                                     NULL),
+                                             b->result_pool);
+      if (svn_sqlite__column_is_null(stmt, 1))
+        *(b->conflict_old) = NULL;
+      else
+        *(b->conflict_old) = svn_dirent_join(wcroot->abspath,
+                                             svn_sqlite__column_text(stmt, 1,
+                                                                     NULL),
+                                             b->result_pool);
+      if (svn_sqlite__column_is_null(stmt, 2))
+        *(b->conflict_working) = NULL;
+      else
+        *(b->conflict_working) = svn_dirent_join(wcroot->abspath,
+                                                 svn_sqlite__column_text(stmt,
+                                                                         2,
+                                                                         NULL),
+                                                 b->result_pool);
+      if (svn_sqlite__column_is_null(stmt, 3))
+        *(b->prop_reject) = NULL;
+      else
+        *(b->prop_reject) = svn_dirent_join(wcroot->abspath,
+                                            svn_sqlite__column_text(stmt, 3,
+                                                                    NULL),
+                                            b->result_pool);
     }
   else
     {
@@ -8670,7 +8718,7 @@ svn_wc__db_read_conflicts(const apr_arra
       const char *conflict_data;
 
       /* ### Store in description! */
-      prop_reject = svn_sqlite__column_text(stmt, 0, result_pool);
+      prop_reject = svn_sqlite__column_text(stmt, 0, NULL);
       if (prop_reject)
         {
           svn_wc_conflict_description2_t *desc;
@@ -8680,14 +8728,15 @@ svn_wc__db_read_conflicts(const apr_arra
                                                            "",
                                                            result_pool);
 
-          desc->their_file = prop_reject;
+          desc->their_abspath = svn_dirent_join(wcroot->abspath, prop_reject,
+                                                result_pool);
 
           APR_ARRAY_PUSH(cflcts, svn_wc_conflict_description2_t*) = desc;
         }
 
-      conflict_old = svn_sqlite__column_text(stmt, 1, result_pool);
-      conflict_new = svn_sqlite__column_text(stmt, 2, result_pool);
-      conflict_working = svn_sqlite__column_text(stmt, 3, result_pool);
+      conflict_old = svn_sqlite__column_text(stmt, 1, NULL);
+      conflict_new = svn_sqlite__column_text(stmt, 2, NULL);
+      conflict_working = svn_sqlite__column_text(stmt, 3, NULL);
 
       if (conflict_old || conflict_new || conflict_working)
         {
@@ -8695,9 +8744,15 @@ svn_wc__db_read_conflicts(const apr_arra
               = svn_wc_conflict_description_create_text2(local_abspath,
                                                          result_pool);
 
-          desc->base_file = conflict_old;
-          desc->their_file = conflict_new;
-          desc->my_file = conflict_working;
+          if (conflict_old)
+            desc->base_abspath = svn_dirent_join(wcroot->abspath, conflict_old,
+                                                 result_pool);
+          if (conflict_new)
+            desc->their_abspath = svn_dirent_join(wcroot->abspath, conflict_new,
+                                                  result_pool);
+          if (conflict_working)
+            desc->my_abspath = svn_dirent_join(wcroot->abspath,
+                                               conflict_working, result_pool);
           desc->merged_file = svn_dirent_basename(local_abspath, result_pool);
 
           APR_ARRAY_PUSH(cflcts, svn_wc_conflict_description2_t*) = desc;
@@ -9765,17 +9820,21 @@ svn_wc__db_temp_op_set_file_external(svn
 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_basename,
-                                                  const char *new_basename,
-                                                  const char *wrk_basename,
+                                                  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;
+  const char *local_relpath, *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,
@@ -9797,9 +9856,9 @@ svn_wc__db_temp_op_set_text_conflict_mar
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                         STMT_UPDATE_ACTUAL_TEXT_CONFLICTS));
     }
-  else if (old_basename == NULL
-           && new_basename == NULL
-           && wrk_basename == NULL)
+  else if (old_abspath == NULL
+           && new_abspath == NULL
+           && wrk_abspath == NULL)
     {
       return SVN_NO_ERROR; /* We don't have to add anything */
     }
@@ -9813,11 +9872,40 @@ svn_wc__db_temp_op_set_text_conflict_mar
                                                         scratch_pool)));
     }
 
+  old_relpath = svn_dirent_skip_ancestor(wcroot->abspath, old_abspath);
+  if (old_relpath == old_abspath)
+    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,
+                                                    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,
+                                                    scratch_pool));
+
+  if (wrk_abspath)
+    {
+      wrk_relpath = svn_dirent_skip_ancestor(wcroot->abspath, wrk_abspath);
+      if (wrk_relpath == wrk_abspath)
+        return svn_error_createf(SVN_ERR_BAD_FILENAME, svn_sqlite__reset(stmt),
+                                 _("Invalid conflict file '%s' for '%s'"),
+                                 svn_dirent_local_style(wrk_abspath,
+                                                        scratch_pool),
+                                 svn_dirent_local_style(local_abspath,
+                                                        scratch_pool));
+    }
+  else
+    wrk_relpath = NULL;
+
   SVN_ERR(svn_sqlite__bindf(stmt, "issss", wcroot->wc_id,
                                            local_relpath,
-                                           old_basename,
-                                           new_basename,
-                                           wrk_basename));
+                                           old_relpath,
+                                           new_relpath,
+                                           wrk_relpath));
 
   return svn_error_return(svn_sqlite__step_done(stmt));
 }
@@ -9828,11 +9916,11 @@ svn_wc__db_temp_op_set_text_conflict_mar
 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_basename,
+                                                     const char *prej_abspath,
                                                      apr_pool_t *scratch_pool)
 {
   svn_wc__db_wcroot_t *wcroot;
-  const char *local_relpath;
+  const char *local_relpath, *prej_relpath;
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t got_row;
 
@@ -9858,7 +9946,7 @@ svn_wc__db_temp_op_set_property_conflict
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                         STMT_UPDATE_ACTUAL_PROPERTY_CONFLICTS));
     }
-  else if (!prej_basename)
+  else if (!prej_abspath)
     return SVN_NO_ERROR;
   else
     {
@@ -9871,9 +9959,17 @@ svn_wc__db_temp_op_set_property_conflict
                                                           scratch_pool)));
     }
 
+  prej_relpath = svn_dirent_skip_ancestor(wcroot->abspath, prej_abspath);
+  if (prej_relpath == prej_abspath)
+    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,
+                                                    scratch_pool));
+
   SVN_ERR(svn_sqlite__bindf(stmt, "iss", wcroot->wc_id,
                                          local_relpath,
-                                         prej_basename));
+                                         prej_relpath));
 
   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=1089593&r1=1089592&r2=1089593&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Wed Apr  6 19:20:30 2011
@@ -2562,9 +2562,9 @@ svn_wc__db_temp_op_set_file_external(svn
 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_basename,
-                                                  const char *new_basename,
-                                                  const char *wrk_basename,
+                                                  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
@@ -2572,7 +2572,7 @@ svn_wc__db_temp_op_set_text_conflict_mar
 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_basename,
+                                                     const char *prej_abspath,
                                                      apr_pool_t *scratch_pool);
 
 /* Tweak a locally added existing directory LOCAL_ABSPATH to have a base

Modified: subversion/trunk/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.c?rev=1089593&r1=1089592&r2=1089593&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.c Wed Apr  6 19:20:30 2011
@@ -140,21 +140,16 @@ get_and_record_fileinfo(svn_wc__db_t *db
 /* OP_REVERT  */
 
 
-/* Remove the file at join(PARENT_ABSPATH, BASE_NAME) if it is not the
-   working file defined by LOCAL_ABSPATH. If BASE_NAME is NULL, then
-   nothing is done. All temp allocations are made within SCRATCH_POOL.  */
+/* Remove the file CONFLICT_ABSPATH if it is not the working file
+   defined by LOCAL_ABSPATH. If CONFLICT_ABSPATH is NULL, then nothing
+   is done. All temp allocations are made within SCRATCH_POOL.  */
 static svn_error_t *
-maybe_remove_conflict(const char *parent_abspath,
-                      const char *base_name,
+maybe_remove_conflict(const char *conflict_abspath,
                       const char *local_abspath,
                       apr_pool_t *scratch_pool)
 {
-  if (base_name != NULL)
+  if (conflict_abspath != NULL)
     {
-      const char *conflict_abspath = svn_dirent_join(parent_abspath,
-                                                     base_name,
-                                                     scratch_pool);
-
       if (strcmp(conflict_abspath, local_abspath) != 0)
         SVN_ERR(svn_io_remove_file2(conflict_abspath, TRUE,
                                     scratch_pool));
@@ -231,14 +226,17 @@ run_revert(svn_wc__db_t *db,
           cd = APR_ARRAY_IDX(conflicts, i,
                              const svn_wc_conflict_description2_t *);
 
-          SVN_ERR(maybe_remove_conflict(parent_abspath, cd->base_file,
-                                        local_abspath, scratch_pool));
-          SVN_ERR(maybe_remove_conflict(parent_abspath, cd->their_file,
+          SVN_ERR(maybe_remove_conflict(cd->base_abspath,
                                         local_abspath, scratch_pool));
-          SVN_ERR(maybe_remove_conflict(parent_abspath, cd->my_file,
+          SVN_ERR(maybe_remove_conflict(cd->their_abspath,
                                         local_abspath, scratch_pool));
-          SVN_ERR(maybe_remove_conflict(parent_abspath, cd->merged_file,
+          SVN_ERR(maybe_remove_conflict(cd->my_abspath,
                                         local_abspath, scratch_pool));
+          if (cd->merged_file)
+            SVN_ERR(maybe_remove_conflict(svn_dirent_join(parent_abspath,
+                                                          cd->merged_file,
+                                                          scratch_pool),
+                                          local_abspath, scratch_pool));
         }
     }
 
@@ -1940,30 +1938,30 @@ run_set_text_conflict_markers(svn_wc__db
 {
   const svn_skel_t *arg = work_item->children->next;
   const char *local_abspath;
-  const char *old_basename;
-  const char *new_basename;
-  const char *wrk_basename;
+  const char *old_abspath;
+  const char *new_abspath;
+  const char *wrk_abspath;
 
   local_abspath = apr_pstrmemdup(scratch_pool, arg->data, arg->len);
 
   arg = arg->next;
-  old_basename = arg->len ? apr_pstrmemdup(scratch_pool, arg->data, arg->len)
-                          : NULL;
+  old_abspath = arg->len ? apr_pstrmemdup(scratch_pool, arg->data, arg->len)
+                         : NULL;
 
   arg = arg->next;
-  new_basename = arg->len ? apr_pstrmemdup(scratch_pool, arg->data, arg->len)
-                          : NULL;
+  new_abspath = arg->len ? apr_pstrmemdup(scratch_pool, arg->data, arg->len)
+                         : NULL;
 
   arg = arg->next;
-  wrk_basename = arg->len ? apr_pstrmemdup(scratch_pool, arg->data, arg->len)
-                          : NULL;
+  wrk_abspath = arg->len ? apr_pstrmemdup(scratch_pool, arg->data, arg->len)
+                         : NULL;
 
   return svn_error_return(
           svn_wc__db_temp_op_set_text_conflict_marker_files(db,
                                                             local_abspath,
-                                                            old_basename,
-                                                            new_basename,
-                                                            wrk_basename,
+                                                            old_abspath,
+                                                            new_abspath,
+                                                            wrk_abspath,
                                                             scratch_pool));
 }
 
@@ -1972,9 +1970,9 @@ svn_error_t *
 svn_wc__wq_tmp_build_set_text_conflict_markers(svn_skel_t **work_item,
                                                svn_wc__db_t *db,
                                                const char *local_abspath,
-                                               const char *old_basename,
-                                               const char *new_basename,
-                                               const char *wrk_basename,
+                                               const char *old_abspath,
+                                               const char *new_abspath,
+                                               const char *wrk_abspath,
                                                apr_pool_t *result_pool,
                                                apr_pool_t *scratch_pool)
 {
@@ -1982,14 +1980,16 @@ svn_wc__wq_tmp_build_set_text_conflict_m
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
-  svn_skel__prepend_str(wrk_basename ? apr_pstrdup(result_pool, wrk_basename)
-                                     : "", *work_item, result_pool);
+  /* Abspaths in the workqueue won't work if the WC is moved. */
 
-  svn_skel__prepend_str(new_basename ? apr_pstrdup(result_pool, new_basename)
-                                     : "", *work_item, result_pool);
+  svn_skel__prepend_str(wrk_abspath ? apr_pstrdup(result_pool, wrk_abspath)
+                                    : "", *work_item, result_pool);
 
-  svn_skel__prepend_str(old_basename ? apr_pstrdup(result_pool, old_basename)
-                                     : "", *work_item, result_pool);
+  svn_skel__prepend_str(new_abspath ? apr_pstrdup(result_pool, new_abspath)
+                                    : "", *work_item, result_pool);
+
+  svn_skel__prepend_str(old_abspath ? apr_pstrdup(result_pool, old_abspath)
+                                    : "", *work_item, result_pool);
 
   svn_skel__prepend_str(apr_pstrdup(result_pool, local_abspath),
                         *work_item, result_pool);
@@ -2013,18 +2013,18 @@ run_set_property_conflict_marker(svn_wc_
 {
   const svn_skel_t *arg = work_item->children->next;
   const char *local_abspath;
-  const char *prej_basename;
+  const char *prej_abspath;
 
   local_abspath = apr_pstrmemdup(scratch_pool, arg->data, arg->len);
 
   arg = arg->next;
-  prej_basename = arg->len ? apr_pstrmemdup(scratch_pool, arg->data, arg->len)
-                           : NULL;
+  prej_abspath = arg->len ? apr_pstrmemdup(scratch_pool, arg->data, arg->len)
+                          : NULL;
 
   return svn_error_return(
           svn_wc__db_temp_op_set_property_conflict_marker_file(db,
                                                                 local_abspath,
-                                                                prej_basename,
+                                                                prej_abspath,
                                                                 scratch_pool));
 }
 
@@ -2032,7 +2032,7 @@ svn_error_t *
 svn_wc__wq_tmp_build_set_property_conflict_marker(svn_skel_t **work_item,
                                                   svn_wc__db_t *db,
                                                   const char *local_abspath,
-                                                  const char *prej_basename,
+                                                  const char *prej_abspath,
                                                   apr_pool_t *result_pool,
                                                   apr_pool_t *scratch_pool)
 {
@@ -2040,8 +2040,8 @@ svn_wc__wq_tmp_build_set_property_confli
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
-  svn_skel__prepend_str(prej_basename ? apr_pstrdup(result_pool, prej_basename)
-                                      : "", *work_item, result_pool);
+  svn_skel__prepend_str(prej_abspath ? apr_pstrdup(result_pool, prej_abspath)
+                                     : "", *work_item, result_pool);
 
   svn_skel__prepend_str(apr_pstrdup(result_pool, local_abspath),
                         *work_item, result_pool);

Modified: subversion/trunk/subversion/libsvn_wc/workqueue.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.h?rev=1089593&r1=1089592&r2=1089593&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.h (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.h Wed Apr  6 19:20:30 2011
@@ -239,9 +239,9 @@ svn_error_t *
 svn_wc__wq_tmp_build_set_text_conflict_markers(svn_skel_t **work_item,
                                                svn_wc__db_t *db,
                                                const char *local_abspath,
-                                               const char *old_basename,
-                                               const char *new_basename,
-                                               const char *wrk_basename,
+                                               const char *old_abspath,
+                                               const char *new_abspath,
+                                               const char *wrk_abspath,
                                                apr_pool_t *result_pool,
                                                apr_pool_t *scratch_pool);
 
@@ -260,7 +260,7 @@ svn_error_t *
 svn_wc__wq_tmp_build_set_property_conflict_marker(svn_skel_t **work_item,
                                                   svn_wc__db_t *db,
                                                   const char *local_abspath,
-                                                  const char *prej_basename,
+                                                  const char *prej_abspath,
                                                   apr_pool_t *result_pool,
                                                   apr_pool_t *scratch_pool);
 

Modified: subversion/trunk/subversion/tests/cmdline/prop_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/prop_tests.py?rev=1089593&r1=1089592&r2=1089593&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/prop_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/prop_tests.py Wed Apr  6 19:20:30 2011
@@ -2359,7 +2359,6 @@ def propget_redirection(sbox):
   if ((len(expected_output) * 3) - 6) != len(pg_stdout_redir):
     raise svntest.Failure("Redirected pg -vR has unexpected duplicates")
 
-@XFail()
 @Issue(3852)
 def file_matching_dir_prop_reject(sbox):
   "prop conflict for file matching dir prop reject"
@@ -2400,7 +2399,7 @@ def file_matching_dir_prop_reject(sbox):
   sbox.simple_propset('prop', 'val3', 'A/dir_conflicts')
   sbox.simple_propset('prop', 'val3', 'A')
 
-  # Update to trigger property conflict
+  # Update to trigger property conflicts
   expected_disk = svntest.main.greek_state.copy()
   expected_disk.add({
     'A/dir_conflicts' : Item('some content\n', props = {'prop' : 'val3'}),
@@ -2413,8 +2412,7 @@ def file_matching_dir_prop_reject(sbox):
   expected_status.tweak(wc_rev=2)
   expected_status.tweak('A', 'A/dir_conflicts', status=' C')
 
-  # I'm not sure what conflict files are expected
-  extra_files = ['dir_conflicts.*\.prej', 'dir_conflicts.*\.prej']
+  extra_files = ['dir_conflicts.prej', 'dir_conflicts.2.prej']
   svntest.actions.run_and_verify_update(wc_dir,
                                         expected_output,
                                         expected_disk,
@@ -2422,12 +2420,27 @@ def file_matching_dir_prop_reject(sbox):
                                         None,
                                         svntest.tree.detect_conflict_files,
                                         extra_files,
-                                        None, None, 2, '-r', '2', wc_dir)
-
+                                        None, None, True, '-r', '2', wc_dir)
   if len(extra_files) != 0:
     print("didn't get expected conflict files")
     raise svntest.verify.SVNUnexpectedOutput
 
+  # Revert and update to check that conflict files are removed
+  svntest.actions.run_and_verify_svn(None, None, [], 'revert', '-R', wc_dir)
+  expected_status.tweak('A', 'A/dir_conflicts', status='  ')
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
+  expected_output = svntest.wc.State(wc_dir, {
+    'A'               : Item(status=' U'),
+    'A/dir_conflicts' : Item(status=' U'),
+    })
+  expected_disk.tweak('A', 'A/dir_conflicts', props={'prop' : 'val2'})
+  expected_status.tweak(wc_rev=3)
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output,
+                                        expected_disk,
+                                        expected_status,
+                                        None, None, None, None, None, True)
 
 ########################################################################
 # Run the tests