You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2011/08/24 16:45:55 UTC

svn commit: r1161134 [1/2] - in /subversion/branches/fs-py: ./ notes/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/include/ subversion/include/private/ subversion/libsvn_client/ subversion/l...

Author: hwright
Date: Wed Aug 24 14:45:54 2011
New Revision: 1161134

URL: http://svn.apache.org/viewvc?rev=1161134&view=rev
Log:
On the fs-py branch:
Bring up-to-date with trunk, in order to pick up an improve fs-pack test.

Added:
    subversion/branches/fs-py/notes/diff-data-flows.txt
      - copied unchanged from r1161132, subversion/trunk/notes/diff-data-flows.txt
    subversion/branches/fs-py/subversion/tests/cmdline/upgrade_tests_data/upgrade_locked.tar.bz2
      - copied unchanged from r1161132, subversion/trunk/subversion/tests/cmdline/upgrade_tests_data/upgrade_locked.tar.bz2
Modified:
    subversion/branches/fs-py/   (props changed)
    subversion/branches/fs-py/CHANGES
    subversion/branches/fs-py/subversion/bindings/javahl/native/CreateJ.cpp
    subversion/branches/fs-py/subversion/bindings/javahl/src/org/apache/subversion/javahl/CommitInfo.java
    subversion/branches/fs-py/subversion/include/private/svn_sqlite.h
    subversion/branches/fs-py/subversion/include/svn_wc.h
    subversion/branches/fs-py/subversion/libsvn_client/diff.c
    subversion/branches/fs-py/subversion/libsvn_client/merge.c
    subversion/branches/fs-py/subversion/libsvn_client/repos_diff.c
    subversion/branches/fs-py/subversion/libsvn_client/status.c
    subversion/branches/fs-py/subversion/libsvn_ra_svn/cyrus_auth.c
    subversion/branches/fs-py/subversion/libsvn_subr/cmdline.c
    subversion/branches/fs-py/subversion/libsvn_subr/magic.c
    subversion/branches/fs-py/subversion/libsvn_subr/svn_cache_config.c
    subversion/branches/fs-py/subversion/libsvn_subr/utf.c
    subversion/branches/fs-py/subversion/libsvn_wc/diff_local.c
    subversion/branches/fs-py/subversion/libsvn_wc/update_editor.c
    subversion/branches/fs-py/subversion/libsvn_wc/upgrade.c
    subversion/branches/fs-py/subversion/libsvn_wc/wc-queries.sql
    subversion/branches/fs-py/subversion/libsvn_wc/wc_db.c
    subversion/branches/fs-py/subversion/libsvn_wc/wc_db.h
    subversion/branches/fs-py/subversion/tests/cmdline/merge_authz_tests.py
    subversion/branches/fs-py/subversion/tests/cmdline/merge_reintegrate_tests.py
    subversion/branches/fs-py/subversion/tests/cmdline/merge_tests.py
    subversion/branches/fs-py/subversion/tests/cmdline/tree_conflict_tests.py
    subversion/branches/fs-py/subversion/tests/cmdline/upgrade_tests.py
    subversion/branches/fs-py/subversion/tests/libsvn_fs_fs/fs-pack-test.c
    subversion/branches/fs-py/tools/client-side/svnmucc/svnmucc.c

Propchange: subversion/branches/fs-py/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Aug 24 14:45:54 2011
@@ -32,6 +32,7 @@
 /subversion/branches/issue-3242-dev:879653-896436
 /subversion/branches/issue-3334-dirs:875156-875867
 /subversion/branches/issue-3668-3669:1031000-1035744
+/subversion/branches/issue-3975:1152931-1160746
 /subversion/branches/kwallet:870785-871314
 /subversion/branches/log-g-performance:870941-871032
 /subversion/branches/merge-skips-obstructions:874525-874615
@@ -54,4 +55,4 @@
 /subversion/branches/tree-conflicts:868291-873154
 /subversion/branches/tree-conflicts-notify:873926-874008
 /subversion/branches/uris-as-urls:1060426-1064427
-/subversion/trunk:1154223-1160298
+/subversion/trunk:1154223-1161132

Modified: subversion/branches/fs-py/CHANGES
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/CHANGES?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/CHANGES (original)
+++ subversion/branches/fs-py/CHANGES Wed Aug 24 14:45:54 2011
@@ -3,7 +3,6 @@ Version 1.8.0
 http://svn.apache.org/repos/asf/subversion/tags/1.8.0
 
  User-visible changes:
-    * don't leave unversioned files when reverting copies (issue #3101)
 
  Developer-visible changes:
   - API changes:
@@ -29,7 +28,6 @@ the 1.6 release:  http://subversion.apac
 
   - Minor new features and improvements:
     * Better handling of HTTP redirects (issue #2779)
-    * make Serf the default DAV access method, if available (r875974)
     * Improved and much more consistent path handling (issue #2028, and others)
     * 'svnadmin load' rewrites changed revnums in mergeinfo (issue #3020)
     * Error message and help text improvements
@@ -54,6 +52,7 @@ the 1.6 release:  http://subversion.apac
     * make server-side network data compression rate configurable (r1072288)
     * added support for auto-detecting mime-types with libmagic (r1131120)
     * 'svn rm url1 url2 url3' uses single txn per repo (issue #1199)
+    * don't leave unversioned files when reverting copies (issue #3101)
 
   - Client-side bugfixes:
     * 'svn cp A B; svn mv B C' is equivalent to 'svn cp A C' (issue #756)

Modified: subversion/branches/fs-py/subversion/bindings/javahl/native/CreateJ.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/bindings/javahl/native/CreateJ.cpp?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/bindings/javahl/native/CreateJ.cpp (original)
+++ subversion/branches/fs-py/subversion/bindings/javahl/native/CreateJ.cpp Wed Aug 24 14:45:54 2011
@@ -871,7 +871,8 @@ CreateJ::CommitInfo(const svn_commit_inf
   if (midCT == 0)
     {
       midCT = env->GetMethodID(clazz, "<init>",
-                               "(JLjava/lang/String;Ljava/lang/String;)V");
+                               "(JLjava/lang/String;Ljava/lang/String;"
+                               "Ljava/lang/String;Ljava/lang/String;)V");
       if (JNIUtil::isJavaExceptionThrown() || midCT == 0)
         POP_AND_RETURN_NULL;
     }
@@ -886,8 +887,18 @@ CreateJ::CommitInfo(const svn_commit_inf
 
   jlong jRevision = commit_info->revision;
 
+  jstring jPostCommitError = JNIUtil::makeJString(
+                                            commit_info->post_commit_err);
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+
+  jstring jReposRoot = JNIUtil::makeJString(commit_info->repos_root);
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+
   // call the Java method
-  jobject jInfo = env->NewObject(clazz, midCT, jRevision, jDate, jAuthor);
+  jobject jInfo = env->NewObject(clazz, midCT, jRevision, jDate, jAuthor,
+                                 jPostCommitError, jReposRoot);
   if (JNIUtil::isJavaExceptionThrown())
     POP_AND_RETURN_NULL;
 

Modified: subversion/branches/fs-py/subversion/bindings/javahl/src/org/apache/subversion/javahl/CommitInfo.java
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/bindings/javahl/src/org/apache/subversion/javahl/CommitInfo.java?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/bindings/javahl/src/org/apache/subversion/javahl/CommitInfo.java (original)
+++ subversion/branches/fs-py/subversion/bindings/javahl/src/org/apache/subversion/javahl/CommitInfo.java Wed Aug 24 14:45:54 2011
@@ -50,13 +50,21 @@ public class CommitInfo implements java.
     /** the author of the revision */
     String author;
 
+    /** post commit error (or NULL) */
+    String postCommitError;
+
+    /** repos root (or NULL) */
+    String reposRoot;
+
     /** This constructor will be only called from the jni code.  */
-    public CommitInfo(long rev, String d, String a)
+    public CommitInfo(long rev, String d, String a, String pce, String rr)
             throws java.text.ParseException
     {
         revision = rev;
         date = (new LogDate(d)).getDate();
         author = a;
+        postCommitError = pce;
+        reposRoot = rr;
     }
 
     /**
@@ -82,4 +90,20 @@ public class CommitInfo implements java.
     {
         return author;
     }
+
+    /**
+     * return any post commit error for the commit
+     */
+    public String getPostCommitError()
+    {
+        return postCommitError;
+    }
+
+    /**
+     * return the repos root
+     */
+    public String getReposRoot()
+    {
+        return reposRoot;
+    }
 }

Modified: subversion/branches/fs-py/subversion/include/private/svn_sqlite.h
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/include/private/svn_sqlite.h?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/include/private/svn_sqlite.h (original)
+++ subversion/branches/fs-py/subversion/include/private/svn_sqlite.h Wed Aug 24 14:45:54 2011
@@ -373,13 +373,12 @@ svn_sqlite__with_immediate_transaction(s
 
 /* Helper function to handle several SQLite operations inside a shared lock.
    This callback is similar to svn_sqlite__with_transaction(), but can be
-   nested (even with a transaction) and changes in the callback are always
-   committed when this function returns.
+   nested (even with a transaction).
 
-   For SQLite 3.6.8 and later using this function as a wrapper around a group
-   of operations can give a *huge* performance boost as the shared-read lock
-   will be shared over multiple statements, instead of being reobtained
-   everytime, which requires disk and/or network io.
+   Using this function as a wrapper around a group of operations can give a
+   *huge* performance boost as the shared-read lock will be shared over
+   multiple statements, instead of being reobtained every time, which may
+   require disk and/or network io, depending on SQLite's locking strategy.
 
    SCRATCH_POOL will be passed to the callback (NULL is valid).
 

Modified: subversion/branches/fs-py/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/include/svn_wc.h?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/include/svn_wc.h (original)
+++ subversion/branches/fs-py/subversion/include/svn_wc.h Wed Aug 24 14:45:54 2011
@@ -2060,7 +2060,7 @@ svn_wc_create_conflict_result(svn_wc_con
  *
  * The values #svn_wc_conflict_choose_mine_conflict and
  * #svn_wc_conflict_choose_theirs_conflict are not legal for conflicts
- * in binary files or properties.
+ * in binary files or binary properties.
  *
  * Implementations of this callback are free to present the conflict
  * using any user interface.  This may include simple contextual

Modified: subversion/branches/fs-py/subversion/libsvn_client/diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/diff.c?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_client/diff.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_client/diff.c Wed Aug 24 14:45:54 2011
@@ -820,10 +820,9 @@ diff_props_changed(svn_wc_notify_state_t
                    svn_boolean_t dir_was_added,
                    const apr_array_header_t *propchanges,
                    apr_hash_t *original_props,
-                   void *diff_baton,
+                   struct diff_cmd_baton *diff_cmd_baton,
                    apr_pool_t *scratch_pool)
 {
-  struct diff_cmd_baton *diff_cmd_baton = diff_baton;
   apr_array_header_t *props;
   svn_boolean_t show_diff_header;
 
@@ -891,7 +890,7 @@ diff_dir_props_changed(svn_wc_notify_sta
                                             dir_was_added,
                                             propchanges,
                                             original_props,
-                                            diff_baton,
+                                            diff_cmd_baton,
                                             scratch_pool));
 }
 
@@ -911,9 +910,8 @@ diff_content_changed(const char *path,
                      svn_diff_operation_kind_t operation,
                      const char *copyfrom_path,
                      svn_revnum_t copyfrom_rev,
-                     void *diff_baton)
+                     struct diff_cmd_baton *diff_cmd_baton)
 {
-  struct diff_cmd_baton *diff_cmd_baton = diff_baton;
   int exitcode;
   apr_pool_t *subpool = svn_pool_create(diff_cmd_baton->pool);
   svn_stream_t *os;
@@ -1105,6 +1103,7 @@ diff_file_changed(svn_wc_notify_state_t 
                   apr_pool_t *scratch_pool)
 {
   struct diff_cmd_baton *diff_cmd_baton = diff_baton;
+
   if (diff_cmd_baton->anchor)
     path = svn_dirent_join(diff_cmd_baton->anchor, path, scratch_pool);
   if (tmpfile1)
@@ -1112,11 +1111,11 @@ diff_file_changed(svn_wc_notify_state_t 
                                  tmpfile1, tmpfile2, rev1, rev2,
                                  mimetype1, mimetype2,
                                  svn_diff_op_modified, NULL,
-                                 SVN_INVALID_REVNUM, diff_baton));
+                                 SVN_INVALID_REVNUM, diff_cmd_baton));
   if (prop_changes->nelts > 0)
     SVN_ERR(diff_props_changed(prop_state, tree_conflicted,
                                path, FALSE, prop_changes,
-                               original_props, diff_baton, scratch_pool));
+                               original_props, diff_cmd_baton, scratch_pool));
   if (content_state)
     *content_state = svn_wc_notify_state_unknown;
   if (prop_state)
@@ -1166,17 +1165,17 @@ diff_file_added(svn_wc_notify_state_t *c
                                  tmpfile1, tmpfile2, rev1, rev2,
                                  mimetype1, mimetype2,
                                  svn_diff_op_copied, copyfrom_path,
-                                 copyfrom_revision, diff_baton));
+                                 copyfrom_revision, diff_cmd_baton));
   else if (tmpfile1)
     SVN_ERR(diff_content_changed(path,
                                  tmpfile1, tmpfile2, rev1, rev2,
                                  mimetype1, mimetype2,
                                  svn_diff_op_added, NULL, SVN_INVALID_REVNUM,
-                                 diff_baton));
+                                 diff_cmd_baton));
   if (prop_changes->nelts > 0)
     SVN_ERR(diff_props_changed(prop_state, tree_conflicted,
                                path, FALSE, prop_changes,
-                               original_props, diff_baton, scratch_pool));
+                               original_props, diff_cmd_baton, scratch_pool));
   if (content_state)
     *content_state = svn_wc_notify_state_unknown;
   if (prop_state)
@@ -1224,7 +1223,7 @@ diff_file_deleted(svn_wc_notify_state_t 
                                      diff_cmd_baton->revnum2,
                                      mimetype1, mimetype2,
                                      svn_diff_op_deleted, NULL,
-                                     SVN_INVALID_REVNUM, diff_baton));
+                                     SVN_INVALID_REVNUM, diff_cmd_baton));
     }
 
   /* We don't list all the deleted properties. */

Modified: subversion/branches/fs-py/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/merge.c?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_client/merge.c Wed Aug 24 14:45:54 2011
@@ -1346,6 +1346,67 @@ merge_file_opened(svn_boolean_t *tree_co
   return SVN_NO_ERROR;
 }
 
+
+/* Indicate in *MOVED_AWAY whether the node at LOCAL_ABSPATH was
+ * moved away locally. Do not raise an error if the node at LOCAL_ABSPATH
+ * does not exist. */
+static svn_error_t *
+check_moved_away(svn_boolean_t *moved_away,
+                 svn_wc_context_t *wc_ctx,
+                 const char *local_abspath,
+                 apr_pool_t *scratch_pool)
+{
+  const char *moved_to_abspath;
+  svn_error_t *err;
+  
+  *moved_away = FALSE;
+
+  err = svn_wc__node_was_moved_away(&moved_to_abspath, NULL,
+                                    wc_ctx, local_abspath,
+                                    scratch_pool, scratch_pool);
+  if (err)
+    {
+      if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+        svn_error_clear(err);
+      else
+        return svn_error_trace(err);
+    }
+  else if (moved_to_abspath)
+    *moved_away = TRUE;
+
+  return SVN_NO_ERROR;
+}
+
+/* Indicate in *MOVED_HERE whether the node at LOCAL_ABSPATH was
+ * moved here locally. Do not raise an error if the node at LOCAL_ABSPATH
+ * does not exist. */
+static svn_error_t *
+check_moved_here(svn_boolean_t *moved_here,
+                 svn_wc_context_t *wc_ctx,
+                 const char *local_abspath,
+                 apr_pool_t *scratch_pool)
+{
+  const char *moved_from_abspath;
+  svn_error_t *err;
+  
+  *moved_here = FALSE;
+
+  err = svn_wc__node_was_moved_here(&moved_from_abspath, NULL,
+                                    wc_ctx, local_abspath,
+                                    scratch_pool, scratch_pool);
+  if (err)
+    {
+      if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+        svn_error_clear(err);
+      else
+        return svn_error_trace(err);
+    }
+  else if (moved_from_abspath)
+    *moved_here = TRUE;
+
+  return SVN_NO_ERROR;
+}
+
 /* An svn_wc_diff_callbacks4_t function. */
 static svn_error_t *
 merge_file_changed(svn_wc_notify_state_t *content_state,
@@ -1399,6 +1460,9 @@ merge_file_changed(svn_wc_notify_state_t
      way svn_wc_merge4() can do the merge. */
   if (wc_kind != svn_node_file || is_deleted)
     {
+      svn_boolean_t moved_away;
+      svn_wc_conflict_reason_t reason;
+
       /* Maybe the node is excluded via depth filtering? */
 
       if (wc_kind == svn_node_none)
@@ -1427,9 +1491,16 @@ merge_file_changed(svn_wc_notify_state_t
       /* This is use case 4 described in the paper attached to issue
        * #2282.  See also notes/tree-conflicts/detection.txt
        */
+      SVN_ERR(check_moved_away(&moved_away, merge_b->ctx->wc_ctx,
+                               mine_abspath, scratch_pool));
+      if (moved_away)
+        reason = svn_wc_conflict_reason_moved_away;
+      else if (is_deleted)
+        reason = svn_wc_conflict_reason_deleted;
+      else
+        reason = svn_wc_conflict_reason_missing;
       SVN_ERR(tree_conflict(merge_b, mine_abspath, svn_node_file,
-                            svn_wc_conflict_action_edit,
-                            svn_wc_conflict_reason_missing));
+                            svn_wc_conflict_action_edit, reason));
       if (tree_conflicted)
         *tree_conflicted = TRUE;
       if (content_state)
@@ -1696,14 +1767,21 @@ merge_file_added(svn_wc_notify_state_t *
                                               merge_b->pool));
             if (existing_conflict)
               {
+                svn_boolean_t moved_here;
+                svn_wc_conflict_reason_t reason;
+
                 /* Possibly collapse the existing conflict into a 'replace'
                  * tree conflict. The conflict reason is 'added' because
                  * the now-deleted tree conflict victim must have been
                  * added in the history of the merge target. */
+                SVN_ERR(check_moved_here(&moved_here, merge_b->ctx->wc_ctx,
+                                         mine_abspath, scratch_pool));
+                reason = moved_here ? svn_wc_conflict_reason_moved_here
+                                    : svn_wc_conflict_reason_added;
                 SVN_ERR(tree_conflict_on_add(merge_b, mine_abspath,
                                              svn_node_file,
                                              svn_wc_conflict_action_add,
-                                             svn_wc_conflict_reason_added));
+                                             reason));
                 if (tree_conflicted)
                   *tree_conflicted = TRUE;
               }
@@ -1769,14 +1847,20 @@ merge_file_added(svn_wc_notify_state_t *
               }
             else
               {
+                svn_boolean_t moved_here;
+                svn_wc_conflict_reason_t reason;
+
                 /* The file add the merge wants to carry out is obstructed by
                  * a versioned file. This file must have been added in the
                  * history of the merge target, hence we flag a tree conflict
                  * with reason 'added'. */
+                SVN_ERR(check_moved_here(&moved_here, merge_b->ctx->wc_ctx,
+                                         mine_abspath, scratch_pool));
+                reason = moved_here ? svn_wc_conflict_reason_moved_here
+                                    : svn_wc_conflict_reason_added;
                 SVN_ERR(tree_conflict_on_add(
                           merge_b, mine_abspath, svn_node_file,
-                          svn_wc_conflict_action_add,
-                          svn_wc_conflict_reason_added));
+                          svn_wc_conflict_action_add, reason));
 
                 if (tree_conflicted)
                   *tree_conflicted = TRUE;
@@ -1883,6 +1967,8 @@ merge_file_deleted(svn_wc_notify_state_t
 {
   merge_cmd_baton_t *merge_b = baton;
   svn_node_kind_t kind;
+  svn_boolean_t moved_away;
+  svn_wc_conflict_reason_t reason;
 
   if (merge_b->dry_run)
     {
@@ -1975,9 +2061,12 @@ merge_file_deleted(svn_wc_notify_state_t
        * This is use case 6 described in the paper attached to issue
        * #2282.  See also notes/tree-conflicts/detection.txt
        */
+      SVN_ERR(check_moved_away(&moved_away, merge_b->ctx->wc_ctx,
+                               mine_abspath, scratch_pool));
+      reason = moved_away ? svn_wc_conflict_reason_moved_away
+                          : svn_wc_conflict_reason_deleted;
       SVN_ERR(tree_conflict(merge_b, mine_abspath, svn_node_file,
-                            svn_wc_conflict_action_delete,
-                            svn_wc_conflict_reason_deleted));
+                            svn_wc_conflict_action_delete, reason));
       if (tree_conflicted)
         *tree_conflicted = TRUE;
       if (state)
@@ -2142,11 +2231,18 @@ merge_dir_added(svn_wc_notify_state_t *s
             }
           else
             {
+              svn_boolean_t moved_here;
+              svn_wc_conflict_reason_t reason;
+
               /* This is a tree conflict. */
+              SVN_ERR(check_moved_here(&moved_here, merge_b->ctx->wc_ctx,
+                                       local_abspath, scratch_pool));
+              reason = moved_here ? svn_wc_conflict_reason_moved_here
+                                  : svn_wc_conflict_reason_added;
               SVN_ERR(tree_conflict_on_add(merge_b, local_abspath,
                                            svn_node_dir,
                                            svn_wc_conflict_action_add,
-                                           svn_wc_conflict_reason_added));
+                                           reason));
               if (tree_conflicted)
                 *tree_conflicted = TRUE;
               if (state)
@@ -2202,6 +2298,9 @@ merge_dir_deleted(svn_wc_notify_state_t 
   svn_error_t *err;
   svn_boolean_t is_versioned;
   svn_boolean_t is_deleted;
+  svn_boolean_t moved_away;
+  svn_wc_conflict_reason_t reason;
+
 
   /* Easy out: We are only applying mergeinfo differences. */
   if (merge_b->record_only)
@@ -2286,9 +2385,12 @@ merge_dir_deleted(svn_wc_notify_state_t 
           {
             /* Dir is already not under version control at this path. */
             /* Raise a tree conflict. */
+            SVN_ERR(check_moved_away(&moved_away, merge_b->ctx->wc_ctx,
+                                     local_abspath, scratch_pool));
+            reason = moved_away ? svn_wc_conflict_reason_moved_away
+                                : svn_wc_conflict_reason_deleted;
             SVN_ERR(tree_conflict(merge_b, local_abspath, svn_node_dir,
-                                  svn_wc_conflict_action_delete,
-                                  svn_wc_conflict_reason_deleted));
+                                  svn_wc_conflict_action_delete, reason));
             if (tree_conflicted)
               *tree_conflicted = TRUE;
           }
@@ -2302,9 +2404,12 @@ merge_dir_deleted(svn_wc_notify_state_t 
       /* Dir is already non-existent. This is use case 6 as described in
        * notes/tree-conflicts/detection.txt.
        * This case was formerly treated as no-op. */
+      SVN_ERR(check_moved_away(&moved_away, merge_b->ctx->wc_ctx,
+                               local_abspath, scratch_pool));
+      reason = moved_away ? svn_wc_conflict_reason_moved_away
+                          : svn_wc_conflict_reason_deleted;
       SVN_ERR(tree_conflict(merge_b, local_abspath, svn_node_dir,
-                            svn_wc_conflict_action_delete,
-                            svn_wc_conflict_reason_deleted));
+                            svn_wc_conflict_action_delete, reason));
       if (tree_conflicted)
         *tree_conflicted = TRUE;
       if (state)
@@ -2399,9 +2504,15 @@ merge_dir_opened(svn_boolean_t *tree_con
        * forcing the user to sanity-check the merge result. */
       else if (is_deleted || wc_kind == svn_node_none)
         {
+          svn_boolean_t moved_away;
+          svn_wc_conflict_reason_t reason;
+
+          SVN_ERR(check_moved_away(&moved_away, merge_b->ctx->wc_ctx,
+                                   local_abspath, scratch_pool));
+          reason = moved_away ? svn_wc_conflict_reason_moved_away
+                              : svn_wc_conflict_reason_deleted;
           SVN_ERR(tree_conflict(merge_b, local_abspath, svn_node_dir,
-                                svn_wc_conflict_action_edit,
-                                svn_wc_conflict_reason_deleted));
+                                svn_wc_conflict_action_edit, reason));
           if (tree_conflicted)
             *tree_conflicted = TRUE;
         }
@@ -4480,7 +4591,8 @@ populate_remaining_ranges(apr_array_head
 /* Helper for record_mergeinfo_for_dir_merge().
 
    Adjust, in place, the inheritability of the ranges in RANGELIST to
-   describe a merge of RANGELIST into WC_WCPATH at depth DEPTH.
+   describe a merge of RANGELIST into WC_WCPATH at depth DEPTH.  Set
+   *RANGELIST_INHERITANCE to the inheritability set.
 
    WC_PATH_IS_MERGE_TARGET is true if WC_PATH is the target of the merge,
    otherwise WC_PATH is a subtree.
@@ -4492,6 +4604,7 @@ populate_remaining_ranges(apr_array_head
    Perform any temporary allocations in SCRATCH_POOL. */
 static svn_error_t *
 calculate_merge_inheritance(apr_array_header_t *rangelist,
+                            svn_boolean_t *rangelist_inheritance,
                             const char *local_abspath,
                             svn_boolean_t wc_path_is_merge_target,
                             svn_boolean_t wc_path_has_missing_child,
@@ -4503,6 +4616,10 @@ calculate_merge_inheritance(apr_array_he
 
   SVN_ERR(svn_wc_read_kind(&path_kind, wc_ctx, local_abspath, FALSE,
                            scratch_pool));
+
+  /* Starting assumption. */
+  *rangelist_inheritance = TRUE;
+
   if (path_kind == svn_node_file)
     {
       /* Files *never* have non-inheritable mergeinfo. */
@@ -4515,17 +4632,27 @@ calculate_merge_inheritance(apr_array_he
           if (wc_path_has_missing_child
               || depth == svn_depth_files
               || depth == svn_depth_empty)
-            svn_rangelist__set_inheritance(rangelist, FALSE);
+            {
+              svn_rangelist__set_inheritance(rangelist, FALSE);
+              *rangelist_inheritance = FALSE;
+            }
           else /* depth == svn_depth_files || depth == svn_depth_empty */
-            svn_rangelist__set_inheritance(rangelist, TRUE);
+            {
+              svn_rangelist__set_inheritance(rangelist, TRUE);
+            }
         }
       else /* WC_PATH is a directory subtree of the target. */
         {
           if (wc_path_has_missing_child
               || depth == svn_depth_immediates)
-            svn_rangelist__set_inheritance(rangelist, FALSE);
+            {
+              svn_rangelist__set_inheritance(rangelist, FALSE);
+              *rangelist_inheritance = FALSE;
+            }
           else /* depth == infinity */
-            svn_rangelist__set_inheritance(rangelist, TRUE);
+            {
+              svn_rangelist__set_inheritance(rangelist, TRUE);
+            }
         }
     }
   return SVN_NO_ERROR;
@@ -7600,6 +7727,7 @@ record_mergeinfo_for_dir_merge(svn_merge
       else /* Record mergeinfo on CHILD. */
         {
           svn_boolean_t child_is_deleted;
+          svn_boolean_t rangelist_inheritance;
 
           /* If CHILD is deleted we don't need to set mergeinfo on it. */
           SVN_ERR(svn_wc__node_is_status_deleted(&child_is_deleted,
@@ -7662,6 +7790,7 @@ record_mergeinfo_for_dir_merge(svn_merge
             continue;
 
           SVN_ERR(calculate_merge_inheritance(child_merge_rangelist,
+                                              &rangelist_inheritance,
                                               child->abspath,
                                               i == 0,
                                               child->missing_child,
@@ -7695,6 +7824,66 @@ record_mergeinfo_for_dir_merge(svn_merge
             }
 
           child_merges = apr_hash_make(iterpool);
+
+          /* If CHILD is the merge target we then know that the mergeinfo
+             described by MERGE_SOURCE_PATH:MERGED_RANGE->START-
+             MERGED_RANGE->END describes existent path-revs in the repository,
+             see normalize_merge_sources() and the global comment
+             'MERGEINFO MERGE SOURCE NORMALIZATION'.
+
+             If CHILD is a subtree of the merge target however, then no such
+             guarantee holds.  The mergeinfo described by
+             (MERGE_SOURCE_PATH + CHILD_REPOS_PATH):MERGED_RANGE->START-
+             MERGED_RANGE->END might contain merge sources which don't
+             exist or refer to unrelated lines of history. */
+          if (i > 0
+              && (!merge_b->record_only || merge_b->reintegrate_merge)
+              && (!is_rollback))
+            {
+              svn_opt_revision_t peg_revision;
+              svn_mergeinfo_t subtree_history_as_mergeinfo;
+              apr_array_header_t *child_merge_src_rangelist;
+              const char *old_session_url;
+              const char *subtree_mergeinfo_url =
+                svn_path_url_add_component2(merge_b->repos_root_url,
+                                            child_merge_src_canon_path + 1,
+                                            iterpool);
+
+              /* Confirm that the naive mergeinfo we want to set on
+                 CHILD->ABSPATH both exists and is part of
+                 (MERGE_SOURCE_PATH+CHILD_REPOS_PATH)@MERGED_RANGE->END's
+                 history. */
+              peg_revision.kind = svn_opt_revision_number;
+
+              /* We know MERGED_RANGE->END is younger than MERGE_RANGE->START
+                 because we only do this for forward merges. */
+              peg_revision.value.number = merged_range->end;
+              SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url,
+                                                        merge_b->ra_session2,
+                                                        subtree_mergeinfo_url,
+                                                        iterpool));
+              SVN_ERR(svn_client__get_history_as_mergeinfo(
+                &subtree_history_as_mergeinfo, NULL,
+                subtree_mergeinfo_url, &peg_revision,
+                MAX(merged_range->start, merged_range->end),
+                MIN(merged_range->start, merged_range->end),
+                merge_b->ra_session2, merge_b->ctx, iterpool));
+
+              if (old_session_url)
+                SVN_ERR(svn_ra_reparent(merge_b->ra_session2,
+                                        old_session_url, iterpool));
+              child_merge_src_rangelist = apr_hash_get(
+                subtree_history_as_mergeinfo,
+                child_merge_src_canon_path,
+                APR_HASH_KEY_STRING);
+              SVN_ERR(svn_rangelist_intersect(&child_merge_rangelist,
+                                              child_merge_rangelist,
+                                              child_merge_src_rangelist,
+                                              FALSE, iterpool));
+              if (!rangelist_inheritance)
+                svn_rangelist__set_inheritance(child_merge_rangelist, FALSE);
+            }
+
           apr_hash_set(child_merges, child->abspath, APR_HASH_KEY_STRING,
                        child_merge_rangelist);
           SVN_ERR(update_wc_mergeinfo(result_catalog,
@@ -7750,8 +7939,9 @@ record_mergeinfo_for_dir_merge(svn_merge
 
    Record mergeinfo describing a merge of
    MERGED_RANGE->START:MERGED_RANGE->END from the repository relative path
-   MERGEINFO_PATH to each path in NOTIFY_B->ADDED_ABSPATHS which is the
-   immediate child of a parent with explicit non-inheritable mergeinfo.
+   MERGEINFO_PATH to each path in NOTIFY_B->ADDED_ABSPATHS which has explicit
+   mergeinfo or is the immediate child of a parent with explicit
+   non-inheritable mergeinfo.
 
    DEPTH, NOTIFY_B, MERGE_B, and SQUELCH_MERGEINFO_NOTIFICATIONS, are
    cascaded from do_directory_merge's arguments of the same names.
@@ -7785,34 +7975,48 @@ record_mergeinfo_for_added_subtrees(
       const char *added_abspath = svn__apr_hash_index_key(hi);
       const char *dir_abspath;
       svn_mergeinfo_t parent_mergeinfo;
+      svn_mergeinfo_t added_path_mergeinfo;
       svn_boolean_t inherited; /* used multiple times, but ignored */
 
       apr_pool_clear(iterpool);
       dir_abspath = svn_dirent_dirname(added_abspath, iterpool);
 
-      /* Does ADDED_ABSPATH's immediate parent have non-inheritable
-         mergeinfo? */
-      SVN_ERR(svn_client__get_wc_mergeinfo(&parent_mergeinfo, &inherited,
+      /* Grab the added path's explicit mergeinfo. */
+      SVN_ERR(svn_client__get_wc_mergeinfo(&added_path_mergeinfo, &inherited,
                                            svn_mergeinfo_explicit,
-                                           dir_abspath, NULL, NULL, FALSE,
-                                           merge_b->ctx,
-                                           iterpool, iterpool));
-      if (svn_mergeinfo__is_noninheritable(parent_mergeinfo, iterpool))
+                                           added_abspath, NULL, NULL, FALSE,
+                                           merge_b->ctx, iterpool, iterpool));
+
+      /* If the added path doesn't have explicit mergeinfo, does its immediate
+         parent have non-inheritable mergeinfo? */
+      if (!added_path_mergeinfo)
+        SVN_ERR(svn_client__get_wc_mergeinfo(&parent_mergeinfo, &inherited,
+                                             svn_mergeinfo_explicit,
+                                             dir_abspath, NULL, NULL, FALSE,
+                                             merge_b->ctx,
+                                             iterpool, iterpool));
+
+      if (added_path_mergeinfo
+          || svn_mergeinfo__is_noninheritable(parent_mergeinfo, iterpool))
         {
           svn_client__merge_path_t *target_merge_path =
             APR_ARRAY_IDX(notify_b->children_with_mergeinfo, 0,
                           svn_client__merge_path_t *);
           svn_merge_range_t *rng;
           svn_node_kind_t added_path_kind;
-          svn_mergeinfo_t merge_mergeinfo, added_path_mergeinfo;
+          svn_mergeinfo_t merge_mergeinfo;
+          svn_mergeinfo_t adds_history_as_mergeinfo;
           apr_array_header_t *rangelist;
           const char *rel_added_path;
           const char *added_path_mergeinfo_path;
+          const char *old_session_url;
+          const char *added_path_mergeinfo_url;
+          svn_opt_revision_t peg_revision;
 
           SVN_ERR(svn_wc_read_kind(&added_path_kind, merge_b->ctx->wc_ctx,
                                    added_abspath, FALSE, iterpool));
 
-          /* Calculate the mergeinfo resulting from this merge. */
+          /* Calculate the naive mergeinfo describing the merge. */
           merge_mergeinfo = apr_hash_make(iterpool);
           rangelist = apr_array_make(iterpool, 1, sizeof(svn_merge_range_t *));
           rng = svn_merge_range_dup(merged_range, iterpool);
@@ -7839,14 +8043,46 @@ record_mergeinfo_for_added_subtrees(
           apr_hash_set(merge_mergeinfo, added_path_mergeinfo_path,
                        APR_HASH_KEY_STRING, rangelist);
 
-          /* Get any explicit mergeinfo the added path has. */
-          SVN_ERR(svn_client__get_wc_mergeinfo(
-            &added_path_mergeinfo, &inherited,
-            svn_mergeinfo_explicit, added_abspath,
-            NULL, NULL, FALSE, merge_b->ctx, iterpool, iterpool));
+          /* Don't add new mergeinfo to describe the merge if that mergeinfo
+             contains non-existent merge sources.
+
+             We know that MERGEINFO_PATH/rel_added_path's history does not
+             span MERGED_RANGE->START:MERGED_RANGE->END but rather that it
+             was added at some revions greater than MERGED_RANGE->START
+             (assuming this is a forward merge).  It may have been added,
+             deleted, and re-added many times.  The point is that we cannot
+             blindly apply the naive mergeinfo calculated above because it
+             will describe non-existent merge sources. To avoid this we get
+             take the intersection of the naive mergeinfo with
+             MERGEINFO_PATH/rel_added_path's history. */
+          added_path_mergeinfo_url =
+            svn_path_url_add_component2(merge_b->repos_root_url,
+                                        added_path_mergeinfo_path + 1,
+                                        iterpool);
+          peg_revision.kind = svn_opt_revision_number;
+          peg_revision.value.number = MAX(merged_range->start,
+                                          merged_range->end);
+          SVN_ERR(svn_client__ensure_ra_session_url(
+            &old_session_url, merge_b->ra_session2,
+            added_path_mergeinfo_url, iterpool));
+          SVN_ERR(svn_client__get_history_as_mergeinfo(
+            &adds_history_as_mergeinfo, NULL,
+            added_path_mergeinfo_url, &peg_revision,
+            MAX(merged_range->start, merged_range->end),
+            MIN(merged_range->start, merged_range->end),
+            merge_b->ra_session2, merge_b->ctx, iterpool));
+
+          if (old_session_url)
+            SVN_ERR(svn_ra_reparent(merge_b->ra_session2,
+                                    old_session_url, iterpool));
+
+          SVN_ERR(svn_mergeinfo_intersect2(&merge_mergeinfo,
+                                           merge_mergeinfo,
+                                           adds_history_as_mergeinfo,
+                                           FALSE, iterpool, iterpool));
 
           /* Combine the explict mergeinfo on the added path (if any)
-             with the mergeinfo for this merge. */
+             with the mergeinfo describing this merge. */
           if (added_path_mergeinfo)
             SVN_ERR(svn_mergeinfo_merge(merge_mergeinfo, added_path_mergeinfo,
                                         iterpool));

Modified: subversion/branches/fs-py/subversion/libsvn_client/repos_diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/repos_diff.c?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_client/repos_diff.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_client/repos_diff.c Wed Aug 24 14:45:54 2011
@@ -486,9 +486,6 @@ open_root(void *edit_baton,
   struct edit_baton *eb = edit_baton;
   struct dir_baton *b = make_dir_baton("", NULL, eb, FALSE, pool);
 
-  /* Override the wcpath in our baton. */
-  b->wcpath = apr_pstrdup(pool, eb->target);
-
   SVN_ERR(get_dirprops_from_ra(b, base_revision));
 
   *root_baton = b;

Modified: subversion/branches/fs-py/subversion/libsvn_client/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/status.c?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_client/status.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_client/status.c Wed Aug 24 14:45:54 2011
@@ -85,6 +85,7 @@ tweak_status(void *baton,
   /* If the status item has an entry, but doesn't belong to one of the
      changelists our caller is interested in, we filter out this status
      transmission.  */
+  /* ### duplicated in ../libsvn_wc/diff_local.c */
   if (sb->changelist_hash)
     {
       if (status->changelist)

Modified: subversion/branches/fs-py/subversion/libsvn_ra_svn/cyrus_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_svn/cyrus_auth.c?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_svn/cyrus_auth.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_svn/cyrus_auth.c Wed Aug 24 14:45:54 2011
@@ -28,7 +28,6 @@
 #include <apr_want.h>
 #include <apr_general.h>
 #include <apr_strings.h>
-#include <apr_atomic.h>
 #include <apr_thread_mutex.h>
 #include <apr_version.h>
 

Modified: subversion/branches/fs-py/subversion/libsvn_subr/cmdline.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/cmdline.c?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/cmdline.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/cmdline.c Wed Aug 24 14:45:54 2011
@@ -37,7 +37,6 @@
 
 #include <apr_errno.h>          /* for apr_strerror */
 #include <apr_general.h>        /* for apr_initialize/apr_terminate */
-#include <apr_atomic.h>         /* for apr_atomic_init */
 #include <apr_strings.h>        /* for apr_snprintf */
 #include <apr_pools.h>
 

Modified: subversion/branches/fs-py/subversion/libsvn_subr/magic.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/magic.c?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/magic.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/magic.c Wed Aug 24 14:45:54 2011
@@ -45,8 +45,9 @@
 struct svn_magic__cookie_t {
 #ifdef SVN_HAVE_LIBMAGIC
   magic_t magic;
-#endif
+#else
   char dummy;
+#endif
 };
 
 #ifdef SVN_HAVE_LIBMAGIC

Modified: subversion/branches/fs-py/subversion/libsvn_subr/svn_cache_config.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/svn_cache_config.c?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/svn_cache_config.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/svn_cache_config.c Wed Aug 24 14:45:54 2011
@@ -147,6 +147,9 @@ svn_cache__get_global_membuffer_cache(vo
       /* Handle race condition: if we are the first to create a
        * cache object, make it our global singleton. Otherwise,
        * discard the new cache and keep the existing one.
+       *
+       * Cast is necessary because of APR bug:
+       * https://issues.apache.org/bugzilla/show_bug.cgi?id=50731
        */
       old_cache = apr_atomic_casptr((volatile void **)&cache, new_cache, NULL);
       if (old_cache != NULL)

Modified: subversion/branches/fs-py/subversion/libsvn_subr/utf.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/utf.c?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_subr/utf.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_subr/utf.c Wed Aug 24 14:45:54 2011
@@ -90,8 +90,8 @@ static apr_hash_t *xlate_handle_hash = N
  * using atomic xchange ops, i.e. without further thread synchronization.
  * If the respective item is NULL, fallback to hash lookup.
  */
-static volatile void *xlat_ntou_static_handle = NULL;
-static volatile void *xlat_uton_static_handle = NULL;
+static void * volatile xlat_ntou_static_handle = NULL;
+static void * volatile xlat_uton_static_handle = NULL;
 
 /* Clean up the xlate handle cache. */
 static apr_status_t
@@ -182,11 +182,13 @@ get_xlate_key(const char *topage,
  * the caller.
  */
 static APR_INLINE void*
-atomic_swap(volatile void **mem, void *new_value)
+atomic_swap(void * volatile * mem, void *new_value)
 {
 #if APR_HAS_THREADS
 #if APR_VERSION_AT_LEAST(1,3,0)
-   return apr_atomic_xchgptr(mem, new_value);
+  /* Cast is necessary because of APR bug:
+     https://issues.apache.org/bugzilla/show_bug.cgi?id=50731 */
+   return apr_atomic_xchgptr((volatile void **)mem, new_value);
 #else
    /* old APRs don't support atomic swaps. Simply return the
     * input to the caller for further proccessing. */

Modified: subversion/branches/fs-py/subversion/libsvn_wc/diff_local.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_wc/diff_local.c?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_wc/diff_local.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_wc/diff_local.c Wed Aug 24 14:45:54 2011
@@ -445,11 +445,25 @@ diff_status_callback(void *baton,
         break; /* Go check other conditions */
     }
 
-  if (eb->changelist_hash != NULL
-      && (!status->changelist
-          || ! apr_hash_get(eb->changelist_hash, status->changelist,
-                            APR_HASH_KEY_STRING)))
-    return SVN_NO_ERROR; /* Filtered via changelist */
+  /* Filter items by changelist. */
+  /* ### duplicated in ../libsvn_client/status.c */
+  if (eb->changelist_hash)
+    {
+      if (status->changelist)
+        {
+          /* Skip unless the caller requested this changelist. */
+          if (! apr_hash_get(eb->changelist_hash, status->changelist,
+                             APR_HASH_KEY_STRING))
+            return SVN_NO_ERROR;
+        }
+      else
+        {
+          /* Skip unless the caller requested changelist-lacking items. */
+          if (! apr_hash_get(eb->changelist_hash, "",
+                             APR_HASH_KEY_STRING))
+            return SVN_NO_ERROR;
+        }
+    }
 
   /* ### The following checks should probably be reversed as it should decide
          when *not* to show a diff, because generally all changed nodes should

Modified: subversion/branches/fs-py/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_wc/update_editor.c?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_wc/update_editor.c Wed Aug 24 14:45:54 2011
@@ -699,6 +699,10 @@ struct file_baton
   /* Absolute path to this file */
   const char *local_abspath;
 
+  /* Absolute path to the new location of the file if it was moved away.
+   * If the file was not moved away, this is NULL. */
+  const char *moved_to_abspath;
+
   /* The repository relative path this file will correspond to. */
   const char *new_relpath;
 
@@ -775,7 +779,6 @@ make_file_baton(struct file_baton **f_p,
 {
   struct edit_baton *eb = pb->edit_baton;
   apr_pool_t *file_pool = svn_pool_create(pb->pool);
-
   struct file_baton *f = apr_pcalloc(file_pool, sizeof(*f));
 
   SVN_ERR_ASSERT(path);
@@ -1454,6 +1457,7 @@ check_tree_conflict(svn_wc_conflict_desc
                     svn_wc_conflict_action_t action,
                     svn_node_kind_t their_node_kind,
                     const char *their_relpath,
+                    const char *moved_to_abspath,
                     apr_pool_t *result_pool,
                     apr_pool_t *scratch_pool)
 {
@@ -1521,20 +1525,8 @@ check_tree_conflict(svn_wc_conflict_desc
 
 
       case svn_wc__db_status_deleted:
-        {
-          const char *moved_to_abspath;
-
-          /* The node is locally deleted. Check if it was moved away.
-           * ### should scan_deletion return status_moved_away, like
-           * ### scan_addition returns status_moved_here? */
-          SVN_ERR(svn_wc__db_scan_deletion(NULL, &moved_to_abspath, NULL,
-                                           NULL, eb->db, local_abspath,
-                                           scratch_pool, scratch_pool));
-          if (moved_to_abspath)
-            reason = svn_wc_conflict_reason_moved_away;
-          else
-            reason = svn_wc_conflict_reason_deleted;
-        }
+        if (!moved_to_abspath)
+          reason = svn_wc_conflict_reason_deleted;
         break;
 
       case svn_wc__db_status_incomplete:
@@ -1825,7 +1817,7 @@ delete_entry(const char *path,
       SVN_ERR(check_tree_conflict(&tree_conflict, eb, local_abspath,
                                   status, kind, TRUE,
                                   svn_wc_conflict_action_delete, svn_node_none,
-                                  repos_relpath, pb->pool, scratch_pool));
+                                  repos_relpath, NULL, pb->pool, scratch_pool));
     }
 
   if (tree_conflict != NULL)
@@ -2183,7 +2175,7 @@ add_directory(const char *path,
                                       status, wc_kind, FALSE,
                                       svn_wc_conflict_action_add,
                                       svn_node_dir, db->new_relpath,
-                                      pool, pool));
+                                      NULL, pool, pool));
         }
 
       if (tree_conflict == NULL)
@@ -2375,7 +2367,7 @@ open_directory(const char *path,
     SVN_ERR(check_tree_conflict(&tree_conflict, eb, db->local_abspath,
                                 status, wc_kind, TRUE,
                                 svn_wc_conflict_action_edit, svn_node_dir,
-                                db->new_relpath, db->pool, pool));
+                                db->new_relpath, NULL, db->pool, pool));
 
   /* Remember the roots of any locally deleted trees. */
   if (tree_conflict != NULL)
@@ -3209,7 +3201,7 @@ add_file(const char *path,
                                       fb->local_abspath,
                                       status, wc_kind, FALSE,
                                       svn_wc_conflict_action_add,
-                                      svn_node_file, fb->new_relpath,
+                                      svn_node_file, fb->new_relpath, NULL,
                                       scratch_pool, scratch_pool));
         }
 
@@ -3342,6 +3334,12 @@ open_file(const char *path,
                                      eb->db, fb->local_abspath,
                                      fb->pool, scratch_pool));
 
+  /* If the file has moved locally look up its new location. */
+  if (status == svn_wc__db_status_deleted)
+    SVN_ERR(svn_wc__db_scan_deletion(NULL, &fb->moved_to_abspath, NULL, NULL,
+                                     eb->db, fb->local_abspath,
+                                     fb->pool, scratch_pool));
+
   /* Is this path a conflict victim? */
   if (conflicted)
     SVN_ERR(node_already_conflicted(&conflicted, eb->db,
@@ -3369,7 +3367,8 @@ open_file(const char *path,
     SVN_ERR(check_tree_conflict(&tree_conflict, eb, fb->local_abspath,
                                 status, wc_kind, TRUE,
                                 svn_wc_conflict_action_edit, svn_node_file,
-                                fb->new_relpath, fb->pool, scratch_pool));
+                                fb->new_relpath, fb->moved_to_abspath,
+                                fb->pool, scratch_pool));
 
   /* Is this path the victim of a newly-discovered tree conflict? */
   if (tree_conflict != NULL)
@@ -3714,6 +3713,8 @@ merge_file(svn_skel_t **work_items,
   svn_boolean_t is_locally_modified;
   enum svn_wc_merge_outcome_t merge_outcome = svn_wc_merge_unchanged;
   svn_skel_t *work_item;
+  const char *working_abspath = fb->moved_to_abspath ? fb->moved_to_abspath
+                                                     : fb->local_abspath;
 
   SVN_ERR_ASSERT(! fb->shadowed && !fb->obstruction_found);
 
@@ -3758,7 +3759,7 @@ merge_file(svn_skel_t **work_items,
          files that do not exist and for directories. */
 
       SVN_ERR(svn_wc__internal_file_modified_p(&is_locally_modified,
-                                               eb->db, fb->local_abspath,
+                                               eb->db, working_abspath,
                                                FALSE /* exact_comparison */,
                                                scratch_pool));
     }
@@ -3802,7 +3803,7 @@ merge_file(svn_skel_t **work_items,
       SVN_ERR(svn_wc__perform_file_merge(work_items,
                                          &merge_outcome,
                                          eb->db,
-                                         fb->local_abspath,
+                                         working_abspath,
                                          pb->local_abspath,
                                          fb->new_text_base_sha1_checksum,
                                          fb->add_existed
@@ -3834,7 +3835,7 @@ merge_file(svn_skel_t **work_items,
       SVN_ERR(svn_wc__get_translate_info(NULL, NULL,
                                          &keywords,
                                          NULL,
-                                         eb->db, fb->local_abspath,
+                                         eb->db, working_abspath,
                                          actual_props, TRUE,
                                          scratch_pool, scratch_pool));
       if (magic_props_changed || keywords)
@@ -3854,7 +3855,7 @@ merge_file(svn_skel_t **work_items,
               /* Copy and DEtranslate the working file to a temp text-base.
                  Note that detranslation is done according to the old props. */
               SVN_ERR(svn_wc__internal_translated_file(
-                        &tmptext, fb->local_abspath, eb->db, fb->local_abspath,
+                        &tmptext, working_abspath, eb->db, working_abspath,
                         SVN_WC_TRANSLATE_TO_NF
                           | SVN_WC_TRANSLATE_NO_OUTPUT_CLEANUP,
                         eb->cancel_func, eb->cancel_baton,
@@ -3896,7 +3897,7 @@ merge_file(svn_skel_t **work_items,
         }
 
       SVN_ERR(svn_wc__wq_build_record_fileinfo(&work_item,
-                                               eb->db, fb->local_abspath,
+                                               eb->db, working_abspath,
                                                set_date,
                                                result_pool, scratch_pool));
       *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
@@ -3951,6 +3952,9 @@ close_file(void *file_baton,
   svn_skel_t *work_item;
   apr_pool_t *scratch_pool = fb->pool; /* Destroyed at function exit */
   svn_boolean_t keep_recorded_info = FALSE;
+  const svn_checksum_t *new_checksum;
+  const char *working_abspath = fb->moved_to_abspath ? fb->moved_to_abspath
+                                                     : fb->local_abspath;
 
   if (fb->skip_this)
     {
@@ -4041,7 +4045,7 @@ close_file(void *file_baton,
   if ((!fb->adding_file || fb->add_existed)
       && !fb->shadowed)
     SVN_ERR(svn_wc__get_actual_props(&local_actual_props,
-                                     eb->db, fb->local_abspath,
+                                     eb->db, working_abspath,
                                      scratch_pool, scratch_pool));
   if (local_actual_props == NULL)
     local_actual_props = apr_hash_make(scratch_pool);
@@ -4119,7 +4123,7 @@ close_file(void *file_baton,
                                       svn_wc__db_status_added,
                                       svn_wc__db_kind_file, TRUE,
                                       svn_wc_conflict_action_add,
-                                      svn_node_file, fb->new_relpath,
+                                      svn_node_file, fb->new_relpath, NULL,
                                       scratch_pool, scratch_pool));
           SVN_ERR_ASSERT(tree_conflict != NULL);
           SVN_ERR(svn_wc__db_op_set_tree_conflict(eb->db,
@@ -4149,7 +4153,7 @@ close_file(void *file_baton,
                                   &new_base_props,
                                   &new_actual_props,
                                   eb->db,
-                                  fb->local_abspath,
+                                  working_abspath,
                                   svn_wc__db_kind_file,
                                   NULL /* left_version */,
                                   NULL /* right_version */,
@@ -4181,7 +4185,7 @@ close_file(void *file_baton,
               if (eb->notify_func)
                 {
                   svn_wc_notify_t *notify =svn_wc_create_notify(
-                                fb->local_abspath,
+                                working_abspath,
                                 svn_wc_notify_update_skip_access_denied,
                                 scratch_pool);
 
@@ -4228,7 +4232,7 @@ close_file(void *file_baton,
 
           SVN_ERR(svn_wc__wq_build_file_install(&work_item,
                                                 eb->db,
-                                                fb->local_abspath,
+                                                working_abspath,
                                                 install_from,
                                                 eb->use_commit_times,
                                                 record_fileinfo,
@@ -4244,7 +4248,7 @@ close_file(void *file_baton,
 
              Note: this will also update the executable flag, but ... meh.  */
           SVN_ERR(svn_wc__wq_build_sync_file_flags(&work_item, eb->db,
-                                                   fb->local_abspath,
+                                                   working_abspath,
                                                    scratch_pool, scratch_pool));
           all_work_items = svn_wc__wq_merge(all_work_items, work_item,
                                             scratch_pool);
@@ -4262,7 +4266,7 @@ close_file(void *file_baton,
       /* Remove the INSTALL_FROM file, as long as it doesn't refer to the
          working file.  */
       if (install_from != NULL
-          && strcmp(install_from, fb->local_abspath) != 0)
+          && strcmp(install_from, working_abspath) != 0)
         {
           SVN_ERR(svn_wc__wq_build_file_remove(&work_item, eb->db,
                                                install_from,
@@ -4313,43 +4317,62 @@ close_file(void *file_baton,
     }
 
   /* Insert/replace the BASE node with all of the new metadata.  */
-  {
-      /* Set the 'checksum' column of the file's BASE_NODE row to
-       * NEW_TEXT_BASE_SHA1_CHECKSUM.  The pristine text identified by that
-       * checksum is already in the pristine store. */
-    const svn_checksum_t *new_checksum = fb->new_text_base_sha1_checksum;
-
-    /* If we don't have a NEW checksum, then the base must not have changed.
-       Just carry over the old checksum.  */
-    if (new_checksum == NULL)
-      new_checksum = fb->original_checksum;
-
-    SVN_ERR(svn_wc__db_base_add_file(eb->db, fb->local_abspath,
-                                     eb->wcroot_abspath,
-                                     fb->new_relpath,
-                                     eb->repos_root, eb->repos_uuid,
-                                     *eb->target_revision,
-                                     new_base_props,
-                                     fb->changed_rev,
-                                     fb->changed_date,
-                                     fb->changed_author,
-                                     new_checksum,
-                                     (dav_prop_changes->nelts > 0)
-                                       ? svn_prop_array_to_hash(
-                                                        dav_prop_changes,
-                                                        scratch_pool)
-                                       : NULL,
-                                     NULL /* conflict */,
-                                     (! fb->shadowed) && new_base_props,
-                                     new_actual_props,
-                                     keep_recorded_info,
-                                     (fb->shadowed && fb->obstruction_found),
-                                     all_work_items,
-                                     scratch_pool));
-  }
+
+  /* Set the 'checksum' column of the file's BASE_NODE row to
+   * NEW_TEXT_BASE_SHA1_CHECKSUM.  The pristine text identified by that
+   * checksum is already in the pristine store. */
+  new_checksum = fb->new_text_base_sha1_checksum;
+
+  /* If we don't have a NEW checksum, then the base must not have changed.
+     Just carry over the old checksum.  */
+  if (new_checksum == NULL)
+    new_checksum = fb->original_checksum;
+
+  SVN_ERR(svn_wc__db_base_add_file(eb->db, fb->local_abspath,
+                                   eb->wcroot_abspath,
+                                   fb->new_relpath,
+                                   eb->repos_root, eb->repos_uuid,
+                                   *eb->target_revision,
+                                   new_base_props,
+                                   fb->changed_rev,
+                                   fb->changed_date,
+                                   fb->changed_author,
+                                   new_checksum,
+                                   (dav_prop_changes->nelts > 0)
+                                     ? svn_prop_array_to_hash(
+                                                      dav_prop_changes,
+                                                      scratch_pool)
+                                     : NULL,
+                                   NULL /* conflict */,
+                                   (! fb->shadowed) && new_base_props,
+                                   new_actual_props,
+                                   keep_recorded_info,
+                                   (fb->shadowed && fb->obstruction_found),
+                                   all_work_items,
+                                   scratch_pool));
 
   /* Deal with the WORKING tree, based on updates to the BASE tree.  */
 
+  if (fb->moved_to_abspath)
+    {
+      /* Perform another in-DB move of the file to sync meta-data
+       * of the moved-away node with the new BASE node. */
+      SVN_ERR(svn_wc__db_op_copy_file(eb->db, fb->moved_to_abspath,
+                                      new_actual_props,
+                                      fb->changed_rev,
+                                      fb->changed_date,
+                                      fb->changed_author,
+                                      fb->new_relpath,
+                                      eb->repos_root,
+                                      eb->repos_uuid,
+                                      *eb->target_revision,
+                                      new_checksum,
+                                      TRUE /* is_move */,
+                                      NULL /* conflict */,
+                                      NULL, /* no work, just modify DB */
+                                      scratch_pool));
+    }
+
   /* If this file was locally-added and is now being added by the update, we
      can toss the local-add, turning this into a local-edit.
      If the local file is replaced, we don't want to touch ACTUAL. */
@@ -4383,7 +4406,10 @@ close_file(void *file_baton,
           action = svn_wc_notify_update_add;
         }
 
-      notify = svn_wc_create_notify(fb->local_abspath, action, scratch_pool);
+      /* If the file was moved-away, notify for the moved-away node.
+       * The original location only had its BASE info changed and
+       * we don't usually notify about such changes. */ 
+      notify = svn_wc_create_notify(working_abspath, action, scratch_pool);
       notify->kind = svn_node_file;
       notify->content_state = content_state;
       notify->prop_state = prop_state;
@@ -5459,6 +5485,7 @@ svn_wc_add_repos_file4(svn_wc_context_t 
                                   original_uuid,
                                   copyfrom_rev,
                                   new_text_base_sha1_checksum,
+                                  FALSE /* is_move */,
                                   NULL /* conflict */,
                                   NULL /* work_items */,
                                   pool));

Modified: subversion/branches/fs-py/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_wc/upgrade.c?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_wc/upgrade.c Wed Aug 24 14:45:54 2011
@@ -1914,12 +1914,12 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx,
                              scratch_pool));
   SVN_ERR(svn_wc__ensure_directory(root_adm_abspath, scratch_pool));
 
-  /* Create an empty sqlite database for this directory. */
+  /* Create an empty sqlite database for this directory and store it in DB. */
   SVN_ERR(svn_wc__db_upgrade_begin(&data.sdb,
                                    &data.repos_id, &data.wc_id,
-                                   data.root_abspath,
+                                   db, data.root_abspath,
                                    this_dir->repos, this_dir->uuid,
-                                   scratch_pool, scratch_pool));
+                                   scratch_pool));
 
   /* Migrate the entries over to the new database.
    ### We need to think about atomicity here.
@@ -1964,7 +1964,6 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx,
   SVN_ERR(svn_wc__db_wq_add(db, data.root_abspath, work_items, scratch_pool));
 
   SVN_ERR(svn_wc__db_wclock_release(db, data.root_abspath, scratch_pool));
-  SVN_ERR(svn_sqlite__close(data.sdb));
   SVN_ERR(svn_wc__db_close(db));
 
   /* Renaming the db file is what makes the pre-wcng into a wcng */

Modified: subversion/branches/fs-py/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_wc/wc-queries.sql?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/fs-py/subversion/libsvn_wc/wc-queries.sql Wed Aug 24 14:45:54 2011
@@ -166,9 +166,9 @@ INSERT OR REPLACE INTO nodes (
   wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
   revision, presence, depth, kind, changed_revision, changed_date,
   changed_author, checksum, properties, translated_size, last_mod_time,
-  dav_cache, symlink_target, file_external, moved_to)
+  dav_cache, symlink_target, file_external, moved_to, moved_here)
 VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14,
-        ?15, ?16, ?17, ?18, ?19, ?20, ?21)
+        ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22)
 
 -- STMT_SELECT_OP_DEPTH_CHILDREN
 SELECT local_relpath FROM nodes

Modified: subversion/branches/fs-py/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_wc/wc_db.c?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_wc/wc_db.c Wed Aug 24 14:45:54 2011
@@ -1018,7 +1018,7 @@ insert_working_node(void *baton,
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_INSERT_NODE));
   SVN_ERR(svn_sqlite__bindf(stmt, "isisnnntstrisn"
                 "nnnn" /* properties translated_size last_mod_time dav_cache */
-                "s",
+                "snni", /* symlink_target, file_external, moved_to, moved_here */
                 wcroot->wc_id, local_relpath,
                 piwb->op_depth,
                 parent_relpath,
@@ -1031,7 +1031,8 @@ insert_working_node(void *baton,
                 piwb->changed_author,
                 /* Note: incomplete nodes may have a NULL target.  */
                 (piwb->kind == svn_wc__db_kind_symlink)
-                            ? piwb->target : NULL));
+                            ? piwb->target : NULL,
+                (apr_int64_t)piwb->moved_here));
 
   if (piwb->kind == svn_wc__db_kind_file)
     {
@@ -4250,6 +4251,7 @@ svn_wc__db_op_copy_file(svn_wc__db_t *db
                         const char *original_uuid,
                         svn_revnum_t original_revision,
                         const svn_checksum_t *checksum,
+                        svn_boolean_t is_move,
                         const svn_skel_t *conflict,
                         const svn_skel_t *work_items,
                         apr_pool_t *scratch_pool)
@@ -4282,7 +4284,7 @@ svn_wc__db_op_copy_file(svn_wc__db_t *db
   iwb.changed_rev = changed_rev;
   iwb.changed_date = changed_date;
   iwb.changed_author = changed_author;
-  iwb.moved_here = FALSE;
+  iwb.moved_here = is_move;
 
   if (original_root_url != NULL)
     {
@@ -5303,7 +5305,6 @@ op_revert_txn(void *baton,
                                         STMT_CLEAR_MOVED_TO_RELPATH));
       SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
       SVN_ERR(svn_sqlite__step_done(stmt));
-      SVN_ERR(svn_sqlite__reset(stmt));
     }
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
@@ -5414,13 +5415,20 @@ op_revert_recursive_txn(void *baton,
   while (have_row)
     {
       const char *moved_here_child_relpath;
+      svn_error_t *err;
 
       svn_pool_clear(iterpool);
 
       moved_here_child_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
-      SVN_ERR(clear_moved_to(moved_here_child_relpath, wcroot, iterpool));
+      err = clear_moved_to(moved_here_child_relpath, wcroot, iterpool);
+      if (err)
+        return svn_error_trace(svn_error_compose_create(
+                                        err,
+                                        svn_sqlite__reset(stmt)));
+
       SVN_ERR(svn_sqlite__step(&have_row, stmt));
     }
+  SVN_ERR(svn_sqlite__reset(stmt));
   svn_pool_destroy(iterpool);
 
   /* Clear potential moved-to pointing at the target node itself. */
@@ -5433,7 +5441,6 @@ op_revert_recursive_txn(void *baton,
                                     STMT_CLEAR_MOVED_TO_RELPATH_RECURSIVE));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
   SVN_ERR(svn_sqlite__step_done(stmt));
-  SVN_ERR(svn_sqlite__reset(stmt));
 
   return SVN_NO_ERROR;
 }
@@ -6191,6 +6198,27 @@ info_below_working(svn_boolean_t *have_b
   return SVN_NO_ERROR;
 }
 
+/* Helper function for op_delete_txn */
+static svn_error_t *
+delete_update_movedto(svn_wc__db_wcroot_t *wcroot,
+                      const char *child_moved_from_relpath,
+                      const char *new_moved_to_relpath,
+                      apr_pool_t *scratch_pool)
+{
+  svn_sqlite__stmt_t *stmt;
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_UPDATE_MOVED_TO_RELPATH));
+
+  SVN_ERR(svn_sqlite__bindf(stmt, "iss",
+                            wcroot->wc_id,
+                            child_moved_from_relpath,
+                            new_moved_to_relpath));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+
+  return SVN_NO_ERROR;
+}
+
 
 struct op_delete_baton_t {
   apr_int64_t delete_depth;  /* op-depth for root of delete */
@@ -6267,7 +6295,6 @@ op_delete_txn(void *baton,
           SVN_ERR(svn_sqlite__bindf(stmt, "iss", wcroot->wc_id,
                                     moved_from_relpath, b->moved_to_relpath));
           SVN_ERR(svn_sqlite__step_done(stmt));
-          SVN_ERR(svn_sqlite__reset(stmt));
         }
 
       /* If a subtree is being moved-away, we need to update moved-to
@@ -6332,7 +6359,6 @@ op_delete_txn(void *baton,
                 {
                   const char *child_subtree_relpath;
                   const char *new_moved_to_relpath;
-                  svn_sqlite__stmt_t *moved_to_stmt;
 
                   /* Compute the new moved-to path for this child... */
                   child_subtree_relpath =
@@ -6344,15 +6370,14 @@ op_delete_txn(void *baton,
                     svn_relpath_join(b->moved_to_relpath,
                                      child_subtree_relpath, iterpool);
                   /* ... and update the BASE moved-to record. */
-                  SVN_ERR(svn_sqlite__get_statement(
-                            &moved_to_stmt, wcroot->sdb,
-                            STMT_UPDATE_MOVED_TO_RELPATH));
-                  SVN_ERR(svn_sqlite__bindf(moved_to_stmt, "iss",
-                                            wcroot->wc_id,
-                                            child_moved_from_relpath,
-                                            new_moved_to_relpath));
-                  SVN_ERR(svn_sqlite__step(&have_row, moved_to_stmt));
-                  SVN_ERR(svn_sqlite__reset(moved_to_stmt));
+                  err = delete_update_movedto(wcroot, child_moved_from_relpath,
+                                              new_moved_to_relpath,
+                                              scratch_pool);
+
+                  if (err)
+                    return svn_error_trace(svn_error_compose_create(
+                                                    err,
+                                                    svn_sqlite__reset(stmt)));
                 }
 
               SVN_ERR(svn_sqlite__step(&have_row, stmt));
@@ -10128,16 +10153,30 @@ svn_error_t *
 svn_wc__db_upgrade_begin(svn_sqlite__db_t **sdb,
                          apr_int64_t *repos_id,
                          apr_int64_t *wc_id,
+                         svn_wc__db_t *wc_db,
                          const char *dir_abspath,
                          const char *repos_root_url,
                          const char *repos_uuid,
-                         apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool)
 {
-  return svn_error_trace(create_db(sdb, repos_id, wc_id, dir_abspath,
-                                   repos_root_url, repos_uuid,
-                                   SDB_FILE,
-                                   result_pool, scratch_pool));
+  svn_wc__db_wcroot_t *wcroot;
+  SVN_ERR(create_db(sdb, repos_id, wc_id, dir_abspath,
+                    repos_root_url, repos_uuid,
+                    SDB_FILE,
+                    wc_db->state_pool, scratch_pool));
+
+  SVN_ERR(svn_wc__db_pdh_create_wcroot(&wcroot,
+                                       apr_pstrdup(wc_db->state_pool,
+                                                   dir_abspath),
+                                       *sdb, *wc_id, FORMAT_FROM_SDB,
+                                       FALSE /* auto-upgrade */,
+                                       FALSE /* enforce_empty_wq */,
+                                       wc_db->state_pool, scratch_pool));
+
+  /* The WCROOT is complete. Stash it into DB.  */
+  apr_hash_set(wc_db->dir_data, wcroot->abspath, APR_HASH_KEY_STRING, wcroot);
+
+  return SVN_NO_ERROR;
 }
 
 

Modified: subversion/branches/fs-py/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_wc/wc_db.h?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/fs-py/subversion/libsvn_wc/wc_db.h Wed Aug 24 14:45:54 2011
@@ -1281,6 +1281,7 @@ svn_wc__db_op_copy_file(svn_wc__db_t *db
                         const char *original_uuid,
                         svn_revnum_t original_revision,
                         const svn_checksum_t *checksum,
+                        svn_boolean_t is_move,
                         const svn_skel_t *conflict,
                         const svn_skel_t *work_items,
                         apr_pool_t *scratch_pool);
@@ -2605,14 +2606,20 @@ svn_wc__db_scan_deletion(const char **ba
    @{
 */
 
+/* Create a new wc.db file for LOCAL_DIR_ABSPATH, which is going to be a
+   working copy for the repository REPOS_ROOT_URL with uuid REPOS_UUID.
+   Return the raw sqlite handle, repository id and working copy id
+   and store the database in WC_DB.
+
+   Perform temporary allocations in SCRATCH_POOL. */
 svn_error_t *
 svn_wc__db_upgrade_begin(svn_sqlite__db_t **sdb,
                          apr_int64_t *repos_id,
                          apr_int64_t *wc_id,
+                         svn_wc__db_t *wc_db,
                          const char *local_dir_abspath,
                          const char *repos_root_url,
                          const char *repos_uuid,
-                         apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool);
 
 

Modified: subversion/branches/fs-py/subversion/tests/cmdline/merge_authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/cmdline/merge_authz_tests.py?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/cmdline/merge_authz_tests.py (original)
+++ subversion/branches/fs-py/subversion/tests/cmdline/merge_authz_tests.py Wed Aug 24 14:45:54 2011
@@ -420,7 +420,7 @@ def mergeinfo_and_skipped_paths(sbox):
                    props={SVN_PROP_MERGEINFO : '/A/D/H/omega:8-9'}),
     'chi'   : Item("This is the file 'chi'.\n"),
     'zeta'  : Item("This is the file 'zeta'.\n",
-                   props={SVN_PROP_MERGEINFO : '/A/D/H/zeta:8-9'}),
+                   props={SVN_PROP_MERGEINFO : '/A/D/H/zeta:9'}),
     })
   expected_skip = wc.State(A_COPY_2_H_path, {})
   svntest.actions.run_and_verify_merge(A_COPY_2_H_path, '7', '9',

Modified: subversion/branches/fs-py/subversion/tests/cmdline/merge_reintegrate_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/cmdline/merge_reintegrate_tests.py?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/cmdline/merge_reintegrate_tests.py (original)
+++ subversion/branches/fs-py/subversion/tests/cmdline/merge_reintegrate_tests.py Wed Aug 24 14:45:54 2011
@@ -486,22 +486,9 @@ def reintegrate_with_rename(sbox):
     ""             : Item(status=' M', wc_rev=9),
   })
   k_expected_disk.tweak('', props={SVN_PROP_MERGEINFO : '/A_COPY:2-9'})
-
-  # Why do we expect mergeinfo of '/A_COPY/D/G/tauprime:2-9' on
-  # A/D/G/tauprime?  Because this --reintegrate merge is effectively a
-  # two URL merge of %URL%/A@9 %URL%/A_COPY@9 to 'A'.  Since %URL%/A@9 and
-  # %URL%/A_COPY@9 have a common ancestor in %URL%/A@1 we expect this 2-URL
-  # merge to record mergeinfo and a component of that mergeinfo describes
-  # the merge of %URL%/A_COPY@2 to %URL%/A_COPY@9.  We see that above on
-  # A.  But we also get it on A's subtrees with explicit mergeinfo, namely
-  # A/D/G/tauprime.  Now I know what you are thinking, "'A_COPY/D/G/tauprime'
-  # doesn't even exist until r9!", and you are quite right.  But this
-  # inheritance of bogus mergeinfo is a known problem, see
-  # http://subversion.tigris.org/issues/show_bug.cgi?id=3157#desc8,
-  # and is not what this test is about, so we won't fail because of it.
   k_expected_disk.add({
     'D/G/tauprime' : Item(props={SVN_PROP_MERGEINFO :
-                                 '/A/D/G/tau:2-7\n/A_COPY/D/G/tauprime:2-9'},
+                                 '/A/D/G/tau:2-7\n/A_COPY/D/G/tauprime:9'},
                           contents="This is the file 'tau'.\n")
     })
   expected_skip = wc.State(A_path, {})
@@ -1269,7 +1256,8 @@ def reintegrate_with_subtree_mergeinfo(s
                            'A    ' + gamma_moved_COPY_path + '\n',
                            'D    ' + gamma_COPY_path + '\n',
                            ' U   ' + A_COPY_path     + '\n',
-                           ' U   ' + D_COPY_path     + '\n',]),
+                           ' U   ' + D_COPY_path     + '\n',
+                           ' U   ' + gamma_moved_COPY_path + '\n']),
     [], 'merge', sbox.repo_url + '/A',  A_COPY_path)
   expected_output = wc.State(
     wc_dir,
@@ -1339,7 +1327,7 @@ def reintegrate_with_subtree_mergeinfo(s
     ''              : Item(status=' U'),
     'mu'            : Item(status=' G'),
     'D'             : Item(status=' U'),
-    'D/gamma_moved' : Item(status=' G'),
+    'D/gamma_moved' : Item(status=' U'),
     })
   expected_elision_output = wc.State(A_path, {
     })
@@ -1385,8 +1373,7 @@ def reintegrate_with_subtree_mergeinfo(s
     'D/G/tau'       : Item("This is the file 'tau'.\n"),
     'D/gamma_moved' : Item(
       "Even newer content", props={SVN_PROP_MERGEINFO :
-                                   '/A/D/gamma_moved:2-15\n'
-                                   '/A_COPY/D/gamma_moved:2-19\n'
+                                   '/A_COPY/D/gamma_moved:17-19\n'
                                    '/A_COPY_3/D/gamma:9'}),
     'D/H'           : Item(),
     'D/H/chi'       : Item("This is the file 'chi'.\n"),
@@ -2024,7 +2011,7 @@ def added_subtrees_with_mergeinfo_break_
     'C'         : Item(),
     'C/nu'      : Item("Trunk work on nu.\n",
                        props={SVN_PROP_MERGEINFO :
-                              '/A_COPY/C/nu:16-18\n'
+                              '/A_COPY/C/nu:13,16-18\n'
                               '/A_COPY_2/C/nu:10'}), # <-- From cyclic
                                                      # merge in r11
     'D'         : Item(),

Modified: subversion/branches/fs-py/subversion/tests/cmdline/merge_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/cmdline/merge_tests.py?rev=1161134&r1=1161133&r2=1161134&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/tests/cmdline/merge_tests.py (original)
+++ subversion/branches/fs-py/subversion/tests/cmdline/merge_tests.py Wed Aug 24 14:45:54 2011
@@ -7681,7 +7681,7 @@ def merge_away_subtrees_noninheritable_r
   expected_output = svntest.verify.UnorderedOutput(
       [A_COPY_path  + ' - /A:2-13*\n',
        mu_COPY_path + ' - /A/mu:2-13\n',
-       nu_COPY_path + ' - /A/nu:2-13\n',])
+       nu_COPY_path + ' - /A/nu:10-13\n',])
   svntest.actions.run_and_verify_svn(None,
                                      expected_output,
                                      [], 'pg', SVN_PROP_MERGEINFO,
@@ -11582,24 +11582,7 @@ def dont_explicitly_record_implicit_merg
   svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
   wc_status.tweak(wc_rev=10)
 
-  # Now do a cherry harvest merge to 'A_copy'.  We should pick up the
-  # change to 'A_copy/D/H/nu' from r10, the mergeinfo on 'A_copy' should
-  # reflect the entire eligible revision range from 'A', r2-10.
-  # 'A_copy/D/H/nu' should have get the equivalent mergeinfo to 'A_copy'
-  # which should elide to the latter, leaving no explicit mergeinfo...
-  #
-  # ...or should it?  For the mergeinfo on ' A_copy/D/H/nu' to elide, it
-  # needs mergeinfo '/A/D/H/nu:2-10', but 'A/D/H/nu' doesn't exist prior to
-  # r6...Anyhow, regardless of what the mergeinfo on ' A_copy/D/H/nu' should
-  # be prior to elision, if we have the following conditions:
-  #
-  #   1) A uniform working revision merge target.
-  #
-  #   2) Explicit mergeinfo on the target/subtrees from the same
-  #      source ('A' in this case).
-  #
-  # Then a cherry harvest from the same source should leave explicit
-  # mergeinfo *only* on the merge target no?
+  # Now do a cherry harvest merge to 'A_copy'.
   expected_output = wc.State(A_copy_path, {
     'D/H/nu' : Item(status='U '),
     })
@@ -11608,7 +11591,6 @@ def dont_explicitly_record_implicit_merg
     'D/H/nu' : Item(status=' U'),
     })
   expected_elision_output = wc.State(A_copy_path, {
-    'D/H/nu' : Item(status=' U'),
     })
   expected_A_copy_status = wc.State(A_copy_path, {
     ''          : Item(status=' M', wc_rev=10),
@@ -11652,7 +11634,8 @@ def dont_explicitly_record_implicit_merg
     'D/H/chi'   : Item("This is the file 'chi'.\n"),
     'D/H/psi'   : Item("This is the file 'psi'.\n"),
     'D/H/omega' : Item("This is the file 'omega'.\n"),
-    'D/H/nu'    : Item("Even nuer content"),
+    'D/H/nu'    : Item("Even nuer content",
+                       props={SVN_PROP_MERGEINFO : '/A/D/H/nu:6-10'}),
     })
   expected_A_copy_skip = wc.State(A_copy_path, {})
   svntest.actions.run_and_verify_merge(A_copy_path, None, None,
@@ -13957,7 +13940,7 @@ def no_self_referential_filtering_on_add
     'B/E/beta'  : Item("New content"),
     'B/lambda'  : Item("This is the file 'lambda'.\n"),
     'B/F'       : Item(),
-    'C_MOVED'   : Item(props={SVN_PROP_MERGEINFO : '/A/C_MOVED:3-10\n' +
+    'C_MOVED'   : Item(props={SVN_PROP_MERGEINFO : '/A/C_MOVED:10\n' +
                               '/A_COPY/C:8\n' +
                               '/A_COPY/C_MOVED:8',
                               'propname' : 'propval'}),
@@ -16711,7 +16694,6 @@ def foreign_repos_prop_conflict(sbox):
 #----------------------------------------------------------------------
 # Test for issue #3975 'adds with explicit mergeinfo don't get mergeinfo
 # describing merge which added them'
-@XFail()
 @Issue(3975)
 @SkipUnless(server_has_mergeinfo)
 def merge_adds_subtree_with_mergeinfo(sbox):
@@ -16767,7 +16749,8 @@ def merge_adds_subtree_with_mergeinfo(sb
     ''          : Item(status=' U'),
     })
   expected_mergeinfo_output = wc.State(A_COPY2_path, {
-    ''   : Item(status=' G'),
+    ''     : Item(status=' G'),
+    'C/nu' : Item(status=' U'),
     })
   expected_elision_output = wc.State(A_COPY2_path, {
     })
@@ -16805,15 +16788,11 @@ def merge_adds_subtree_with_mergeinfo(sb
     'B/lambda'  : Item("This is the file 'lambda'.\n"),
     'B/F'       : Item(),
     'C'         : Item(),
-    # Currently this test fails because A_COPY_2/C/nu gets no
-    # mergeinfo set on it to describe the merge, it only has
-    # the explicit mergeinfo from its copy source (i.e. /A_COPY/C/nu:10
-    # from ^/A/C/nu@11.
     'C/nu'      : Item("This is the file 'nu'.\n" \
                        "More work on the A_COPY branch.\n" \
                        "A faux conflict resolution.\n",
                        props={SVN_PROP_MERGEINFO :
-                              '\/A/C/nu:9-11n/A_COPY/C/nu:10'}),
+                              '/A/C/nu:9-11\n/A_COPY/C/nu:10'}),
     'D'         : Item(),
     'D/G'       : Item(),
     'D/G/pi'    : Item("This is the file 'pi'.\n"),