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 17:16:55 UTC

svn commit: r1161147 [3/9] - in /subversion/branches/revprop-packing: ./ build/ build/ac-macros/ notes/ subversion/bindings/ctypes-python/csvn/ subversion/bindings/ctypes-python/test/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/or...

Modified: subversion/branches/revprop-packing/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java (original)
+++ subversion/branches/revprop-packing/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java Wed Aug 24 15:16:50 2011
@@ -307,7 +307,9 @@ public class SVNClient implements ISVNCl
                                         boolean force)
             throws ClientException;
 
-    public native void propertySetRemote(String path, String name, byte[] value,
+    public native void propertySetRemote(String path, long baseRev,
+                                         String name, byte[] value,
+                                         CommitMessageCallback handler,
                                          boolean force,
                                          Map<String, String> revpropTable,
                                          CommitCallback callback)

Modified: subversion/branches/revprop-packing/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java (original)
+++ subversion/branches/revprop-packing/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java Wed Aug 24 15:16:50 2011
@@ -1878,8 +1878,12 @@ public class SVNClient implements SVNCli
         {
             if (Path.isURL(path))
             {
-                aSVNClient.propertySetRemote(path, name,
+                Info2[] infos = info2(path, Revision.HEAD, Revision.HEAD,
+                                      false);
+
+                aSVNClient.propertySetRemote(path, infos[0].getRev(), name,
                                        value == null ? null : value.getBytes(),
+                                       cachedHandler,
                                        force, revpropTable, null);
             }
             else

Modified: subversion/branches/revprop-packing/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java (original)
+++ subversion/branches/revprop-packing/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java Wed Aug 24 15:16:50 2011
@@ -130,6 +130,35 @@ public class BasicTests extends SVNTests
     }
 
     /**
+     * Test the JNIError class functionality
+     * @throws Throwable
+     */
+    public void testJNIError() throws Throwable
+    {
+        // build the test setup.
+        OneTest thisTest = new OneTest();
+
+        // Create a client, dispose it, then try to use it later
+        ISVNClient tempclient = new SVNClient();
+        tempclient.dispose();
+
+        // create Y and Y/Z directories in the repository
+        addExpectedCommitItem(null, thisTest.getUrl().toString(), "Y", NodeKind.none,
+                              CommitItemStateFlags.Add);
+        Set<String> urls = new HashSet<String>(1);
+        urls.add(thisTest.getUrl() + "/Y");
+        try 
+        {
+            tempclient.mkdir(urls, false, null, new ConstMsg("log_msg"), null);
+        } 
+        catch(JNIError e)
+        {
+	        return; // Test passes!
+        }
+        fail("A JNIError should have been thrown here.");
+    }
+
+    /**
      * Tests Mergeinfo and RevisionRange classes.
      * @since 1.5
      */
@@ -3081,6 +3110,53 @@ public class BasicTests extends SVNTests
     }
 
     /**
+     * Test the basic SVNClient.propertySetRemote functionality.
+     * @throws Throwable
+     */
+    public void testPropEdit() throws Throwable
+    {
+        final String PROP = "abc";
+        final byte[] VALUE = new String("def").getBytes();
+        final byte[] NEWVALUE = new String("newvalue").getBytes();
+        // create the test working copy
+        OneTest thisTest = new OneTest();
+
+        Set<String> pathSet = new HashSet<String>();
+        // set a property on A/D/G/rho file
+        pathSet.clear();
+        pathSet.add(thisTest.getWCPath()+"/A/D/G/rho");
+        client.propertySetLocal(pathSet, PROP, VALUE,
+                                Depth.infinity, null, false);
+        thisTest.getWc().setItemPropStatus("A/D/G/rho", Status.Kind.modified);
+
+        // test the status of the working copy
+        thisTest.checkStatus();
+
+        // commit the changes
+        checkCommitRevision(thisTest, "wrong revision number from commit", 2,
+                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
+                            false, false, null, null);
+
+        thisTest.getWc().setItemPropStatus("A/D/G/rho", Status.Kind.normal);
+
+        // check the status of the working copy
+        thisTest.checkStatus();
+        
+        // now edit the propval directly in the repository
+        long baseRev = 2L;
+        client.propertySetRemote(thisTest.getUrl()+"/A/D/G/rho", baseRev, PROP, NEWVALUE,
+                                 new ConstMsg("edit prop"), false, null, null);
+        
+        // update the WC and verify that the property was changed
+        client.update(thisTest.getWCPathSet(), Revision.HEAD, Depth.infinity, false, false,
+                      false, false);
+        byte[] propVal = client.propertyGet(thisTest.getWCPath()+"/A/D/G/rho", PROP, null, null);
+
+        assertEquals(new String(propVal), new String(NEWVALUE));
+
+    }
+
+    /**
      * Test tolerance of unversioned obstructions when adding paths with
      * {@link org.apache.subversion.javahl.SVNClient#checkout()},
      * {@link org.apache.subversion.javahl.SVNClient#update()}, and
@@ -3343,6 +3419,16 @@ public class BasicTests extends SVNTests
     }
 
     /**
+     * Test an explicit expose of SVNClient.
+     * (This used to cause a fatal exception in the Java Runtime)
+     */
+    public void testDispose() throws Throwable
+    {
+      SVNClient cl = new SVNClient();
+      cl.dispose();
+    }
+
+    /**
      * @return <code>file</code> converted into a -- possibly
      * <code>canonical</code>-ized -- Subversion-internal path
      * representation.

Modified: subversion/branches/revprop-packing/subversion/bindings/swig/python/svn/repos.py
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/bindings/swig/python/svn/repos.py?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/bindings/swig/python/svn/repos.py (original)
+++ subversion/branches/revprop-packing/subversion/bindings/swig/python/svn/repos.py Wed Aug 24 15:16:50 2011
@@ -72,12 +72,28 @@ class ChangedPath:
 
 
 class ChangeCollector(_svndelta.Editor):
-  """Available Since: 1.2.0
+  """An editor that, when driven, walks a revision or a transaction and
+  incrementally invokes a callback with ChangedPath instances corresponding to
+  paths changed in that revision.
+
+  Available Since: 1.2.0
   """
 
   # BATON FORMAT: [path, base_path, base_rev]
 
   def __init__(self, fs_ptr, root, pool=None, notify_cb=None):
+    """Construct a walker over the svn_fs_root_t ROOT, which must
+    be in the svn_fs_t FS_PTR.  Invoke NOTIFY_CB with a single argument
+    of type ChangedPath for each change under ROOT.
+
+    At this time, two ChangedPath objects will be passed for a path that had
+    been replaced in the revision/transaction.  This may change in the future.
+  
+    ### Can't we deduce FS_PTR from ROOT?
+
+    ### POOL is unused
+    """
+
     self.fs_ptr = fs_ptr
     self.changes = { } # path -> ChangedPathEntry()
     self.roots = { } # revision -> svn_svnfs_root_t
@@ -136,9 +152,9 @@ class ChangeCollector(_svndelta.Editor):
     self.changes[path] = ChangedPath(item_type,
                                      False,
                                      False,
-                                     base_path,
+                                     base_path,       # base_path
                                      parent_baton[2], # base_rev
-                                     None,            # (new) path
+                                     path,            # path
                                      False,           # added
                                      CHANGE_ACTION_DELETE,
                                      )

Modified: subversion/branches/revprop-packing/subversion/bindings/swig/python/tests/trac/versioncontrol/svn_fs.py
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/bindings/swig/python/tests/trac/versioncontrol/svn_fs.py?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/bindings/swig/python/tests/trac/versioncontrol/svn_fs.py (original)
+++ subversion/branches/revprop-packing/subversion/bindings/swig/python/tests/trac/versioncontrol/svn_fs.py Wed Aug 24 15:16:50 2011
@@ -407,7 +407,7 @@ class SubversionChangeset(Changeset):
                 else:
                     base_path = None
             action = ''
-            if not change.path:
+            if change.action == repos.CHANGE_ACTION_DELETE:
                 action = Changeset.DELETE
                 deletions[change.base_path] = idx
             elif change.added:

Modified: subversion/branches/revprop-packing/subversion/bindings/swig/ruby/test/test_client.rb
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/bindings/swig/ruby/test/test_client.rb?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/bindings/swig/ruby/test/test_client.rb (original)
+++ subversion/branches/revprop-packing/subversion/bindings/swig/ruby/test/test_client.rb Wed Aug 24 15:16:50 2011
@@ -1287,7 +1287,6 @@ class SvnClientTest < Test::Unit::TestCa
         ctx.mv(path1, path2)
       end
       ctx.revert([path1, path2])
-      FileUtils.rm(path2)
 
       File.open(path1, "w") {|f| f.print(src2)}
       assert_nothing_raised do

Modified: subversion/branches/revprop-packing/subversion/bindings/swig/ruby/test/util.rb
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/bindings/swig/ruby/test/util.rb?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/bindings/swig/ruby/test/util.rb (original)
+++ subversion/branches/revprop-packing/subversion/bindings/swig/ruby/test/util.rb Wed Aug 24 15:16:50 2011
@@ -262,7 +262,7 @@ realm = #{@realm}
             "svn://#{@svnserve_host}:#{@svnserve_port}#{@full_repos_path}"
           # Avoid a race by waiting a short time for svnserve to start up.
           # Without this, tests can fail with "Connection refused" errors.
-          sleep 0.1
+          sleep 1
           break
         end
       end

Modified: subversion/branches/revprop-packing/subversion/include/private/svn_client_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/include/private/svn_client_private.h?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/include/private/svn_client_private.h (original)
+++ subversion/branches/revprop-packing/subversion/include/private/svn_client_private.h Wed Aug 24 15:16:50 2011
@@ -48,7 +48,7 @@ svn_client__assert_homogeneous_target_ty
 
 /* Create a svn_client_status_t structure *CST for LOCAL_ABSPATH, shallow
  * copying data from *STATUS wherever possible and retrieving the other values
- * where needed. Peform temporary allocations in SCRATCH_POOL and allocate the
+ * where needed. Perform temporary allocations in SCRATCH_POOL and allocate the
  * result in RESULT_POOL
  */
 svn_error_t *

Modified: subversion/branches/revprop-packing/subversion/include/private/svn_sqlite.h
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/include/private/svn_sqlite.h?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/include/private/svn_sqlite.h (original)
+++ subversion/branches/revprop-packing/subversion/include/private/svn_sqlite.h Wed Aug 24 15:16:50 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/revprop-packing/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/include/private/svn_wc_private.h?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/include/private/svn_wc_private.h (original)
+++ subversion/branches/revprop-packing/subversion/include/private/svn_wc_private.h Wed Aug 24 15:16:50 2011
@@ -466,6 +466,22 @@ svn_wc__node_is_status_deleted(svn_boole
                                apr_pool_t *scratch_pool);
 
 /**
+ * Set @a *deleted_ancestor_abspath to the root of the delete operation
+ * that deleted @a local_abspath. If @a local_abspath itself was deleted
+ * and has no deleted ancestor, @a *deleted_ancestor_abspath will equal
+ * @a local_abspath. If @a local_abspath was not deleted,
+ * set @a *deleted_ancestor_abspath to @c NULL.
+ * @a *deleted_ancestor_abspath is allocated in @a result_pool.
+ * Use @a scratch_pool for all temporary allocations.
+ */ 
+svn_error_t *
+svn_wc__node_get_deleted_ancestor(const char **deleted_ancestor_abspath,
+                                  svn_wc_context_t *wc_ctx,
+                                  const char *local_abspath,
+                                  apr_pool_t *result_pool,
+                                  apr_pool_t *scratch_pool);
+
+/**
  * Set @a *is_server_excluded to whether @a local_abspath has been
  * excluded by the server, using @a wc_ctx.  If @a local_abspath is not
  * in the working copy, return @c SVN_ERR_WC_PATH_NOT_FOUND.
@@ -994,9 +1010,6 @@ svn_wc__get_not_present_descendants(cons
  * If DELETED is not NULL, set *DELETED to TRUE if the node is marked as
  * deleted in the working copy.
  *
- * If CONFLICTED is not NULL, set *CONFLICTED to TRUE if the node is somehow
- * conflicted.
- *
  * All output arguments except OBSTRUCTION_STATE can be NULL to ommit the
  * result.
  *
@@ -1007,7 +1020,6 @@ svn_wc__check_for_obstructions(svn_wc_no
                                svn_node_kind_t *kind,
                                svn_boolean_t *added,
                                svn_boolean_t *deleted,
-                               svn_boolean_t *conflicted,
                                svn_wc_context_t *wc_ctx,
                                const char *local_abspath,
                                svn_boolean_t no_wcroot_check,
@@ -1111,6 +1123,24 @@ svn_wc__delete_internal(svn_wc_context_t
                         void *notify_baton,
                         apr_pool_t *scratch_pool);
 
+/* If the node at LOCAL_ABSPATH was moved away set *MOVED_TO_ABSPATH to
+ * the absolute path of the copied move-target node, and *COPY_OP_ROOT_ABSPATH
+ * to the absolute path of the root node of the copy operation.
+ *
+ * If the node was not moved, set *MOVED_TO_ABSPATH and *COPY_OP_ROOT_ABSPATH
+ * to NULL.
+ *
+ * Either MOVED_TO_ABSPATH or OP_ROOT_ABSPATH may be NULL to indicate
+ * that the caller is not interested in the result.
+ */
+svn_error_t *
+svn_wc__node_was_moved_away(const char **moved_to_abspath,
+                            const char **copy_op_root_abspath,
+                            svn_wc_context_t *wc_ctx,
+                            const char *local_abspath,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool);
+
 /* If the node at LOCAL_ABSPATH was moved here set *MOVED_FROM_ABSPATH to
  * the absolute path of the deleted move-source node, and set
  * *DELETE_OP_ROOT_ABSPATH to the absolute path of the root node of the

Modified: subversion/branches/revprop-packing/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/include/svn_client.h?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/include/svn_client.h (original)
+++ subversion/branches/revprop-packing/subversion/include/svn_client.h Wed Aug 24 15:16:50 2011
@@ -2105,11 +2105,11 @@ typedef struct svn_client_status_t
    * svn_wc_status_modified and svn_wc_status_conflicted. */
   enum svn_wc_status_kind prop_status;
 
-  /** a node can be 'locked' if a working copy update is in progress or
+  /** A node can be 'locked' if a working copy update is in progress or
    * was interrupted. */
   svn_boolean_t wc_is_locked;
 
-  /** a file or directory can be 'copied' if it's scheduled for
+  /** A file or directory can be 'copied' if it's scheduled for
    * addition-with-history (or part of a subtree that is scheduled as such.).
    */
   svn_boolean_t copied;
@@ -2135,7 +2135,7 @@ typedef struct svn_client_status_t
   /** Last commit author of this item */
   const char *changed_author;
 
-    /** a file or directory can be 'switched' if the switch command has been
+  /** A file or directory can be 'switched' if the switch command has been
    * used.  If this is TRUE, then file_external will be FALSE.
    */
   svn_boolean_t switched;
@@ -2201,11 +2201,44 @@ typedef struct svn_client_status_t
 
   /** @} */
 
-  /** Reserved for libsvn_client's internal use; this value is only to be used for
-   * libsvn_client backwards compatibility wrappers. This value may be NULL or
-   * to other data in future versions. */
+  /** Reserved for libsvn_client's internal use; this value is only to be used
+   * for libsvn_client backwards compatibility wrappers. This value may be NULL
+   * or to other data in future versions. */
   const void *backwards_compatibility_baton;
 
+  /** Set to the local absolute path that this node was moved from, if this
+   * file or directory has been moved here locally and is the root of that
+   * move. Otherwise set to NULL.
+   *
+   * This will be NULL for moved-here nodes that are just part of a subtree
+   * that was moved along (and are not themselves a root of a different move
+   * operation).
+   * 
+   * @since New in 1.8. */
+  const char *moved_from_abspath;
+
+  /** Set to the local absolute path that this node was moved to, if this file
+   * or directory has been moved away locally and corresponds to the root
+   * of the destination side of the move. Otherwise set to NULL.
+   *
+   * Note: Saying just "root" here could be misleading. For example:
+   *   svn mv A AA;
+   *   svn mv AA/B BB;
+   * creates a situation where A/B is moved-to BB, but one could argue that
+   * the move source's root actually was AA/B. Note that, as far as the
+   * working copy is concerned, above case is exactly identical to:
+   *   svn mv A/B BB;
+   *   svn mv A AA;
+   * In both situations, @a moved_to_abspath would be set for nodes A (moved
+   * to AA) and A/B (moved to BB), only.
+   *
+   * This will be NULL for moved-away nodes that were just part of a subtree
+   * that was moved along (and are not themselves a root of a different move
+   * operation).
+   *
+   * @since New in 1.8. */
+  const char *moved_to_abspath;
+
   /* NOTE! Please update svn_client_status_dup() when adding new fields here. */
 } svn_client_status_t;
 
@@ -2743,6 +2776,10 @@ svn_client_blame(const char *path_or_url
  * If @a show_copies_as_adds is TRUE, then copied files will not be diffed
  * against their copyfrom source, and will appear in the diff output
  * in their entirety, as if they were newly added.
+ * ### BUGS: For a repos-repos diff, this is ignored. Instead, a file is
+ *     diffed against its copyfrom source iff the file is the diff target
+ *     and not if some parent directory is the diff target. For a repos-WC
+ *     diff, this is ignored if the file is the diff target.
  *
  * If @a use_git_diff_format is TRUE, then the git's extended diff format
  * will be used.

Modified: subversion/branches/revprop-packing/subversion/include/svn_ra.h
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/include/svn_ra.h?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/include/svn_ra.h (original)
+++ subversion/branches/revprop-packing/subversion/include/svn_ra.h Wed Aug 24 15:16:50 2011
@@ -1695,7 +1695,8 @@ svn_ra_get_file_revs(svn_ra_session_t *s
 /**
  * Lock each path in @a path_revs, which is a hash whose keys are the
  * paths to be locked, and whose values are the corresponding base
- * revisions for each path.
+ * revisions for each path.  The keys are (const char *) and the
+ * revisions are (svn_revnum_t *).
  *
  * Note that locking is never anonymous, so any server implementing
  * this function will have to "pull" a username from the client, if

Modified: subversion/branches/revprop-packing/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/include/svn_wc.h?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/include/svn_wc.h (original)
+++ subversion/branches/revprop-packing/subversion/include/svn_wc.h Wed Aug 24 15:16:50 2011
@@ -1551,7 +1551,11 @@ typedef enum svn_wc_conflict_reason_t
   /** Object is already added or schedule-add. @since New in 1.6. */
   svn_wc_conflict_reason_added,
   /** Object is already replaced. @since New in 1.7. */
-  svn_wc_conflict_reason_replaced
+  svn_wc_conflict_reason_replaced,
+  /** Object is moved away. @since New in 1.8. */
+  svn_wc_conflict_reason_moved_away,
+  /** Object is moved here. @since New in 1.8. */
+  svn_wc_conflict_reason_moved_here
 
 } svn_wc_conflict_reason_t;
 
@@ -1755,7 +1759,7 @@ typedef struct svn_wc_conflict_descripti
   /** Info on the "merge-right source" or "their" version of incoming change. */
   const svn_wc_conflict_version_t *src_right_version;
 
-  /* Remember to adjust svn_wc__conflict_description_dup()
+  /* Remember to adjust svn_wc__conflict_description2_dup()
    * if you add new fields to this struct. */
 } svn_wc_conflict_description2_t;
 
@@ -1849,8 +1853,6 @@ typedef struct svn_wc_conflict_descripti
    * @since New in 1.6. */
   svn_wc_conflict_version_t *src_right_version;
 
-  /* Remember to adjust svn_wc__conflict_description_dup()
-   * if you add new fields to this struct. */
 } svn_wc_conflict_description_t;
 
 /**
@@ -2058,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
@@ -3068,6 +3070,13 @@ typedef struct svn_wc_info_t
   /** The local absolute path of the working copy root.  */
   const char *wcroot_abspath;
 
+  /** The path the node was moved from, if it was moved here. Else NULL.
+   * @since New in 1.8. */
+  const char *moved_from_abspath;
+
+  /** The path the node was moved to, if it was moved away. Else NULL.
+   * @since New in 1.8. */
+  const char *moved_to_abspath;
 } svn_wc_info_t;
 
 /**
@@ -3612,6 +3621,39 @@ typedef struct svn_wc_status3_t
 
   /** @} */
 
+  /** Set to the local absolute path that this node was moved from, if this
+   * file or directory has been moved here locally and is the root of that
+   * move. Otherwise set to NULL.
+   *
+   * This will be NULL for moved-here nodes that are just part of a subtree
+   * that was moved along (and are not themselves a root of a different move
+   * operation).
+   * 
+   * @since New in 1.8. */
+  const char *moved_from_abspath;
+
+  /** Set to the local absolute path that this node was moved to, if this file
+   * or directory has been moved away locally and corresponds to the root
+   * of the destination side of the move. Otherwise set to NULL.
+   *
+   * Note: Saying just "root" here could be misleading. For example:
+   *   svn mv A AA;
+   *   svn mv AA/B BB;
+   * creates a situation where A/B is moved-to BB, but one could argue that
+   * the move source's root actually was AA/B. Note that, as far as the
+   * working copy is concerned, above case is exactly identical to:
+   *   svn mv A/B BB;
+   *   svn mv A AA;
+   * In both situations, @a moved_to_abspath would be set for nodes A (moved
+   * to AA) and A/B (moved to BB), only.
+   *
+   * This will be NULL for moved-away nodes that were just part of a subtree
+   * that was moved along (and are not themselves a root of a different move
+   * operation).
+   *
+   * @since New in 1.8. */
+  const char *moved_to_abspath;
+
   /* NOTE! Please update svn_wc_dup_status3() when adding new fields here. */
 } svn_wc_status3_t;
 

Modified: subversion/branches/revprop-packing/subversion/libsvn_client/blame.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_client/blame.c?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_client/blame.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_client/blame.c Wed Aug 24 15:16:50 2011
@@ -85,7 +85,7 @@ struct file_rev_baton {
   struct rev *rev;     /* the rev for which blame is being assigned
                           during a diff */
   struct blame_chain *chain;      /* the original blame chain. */
-  const char *tmp_path; /* temp file name to feed svn_io_open_unique_file */
+  const char *repos_root_url;    /* To construct a url */
   apr_pool_t *mainpool;  /* lives during the whole sequence of calls */
   apr_pool_t *lastpool;  /* pool used during previous call */
   apr_pool_t *currpool;  /* pool used during this call */
@@ -424,7 +424,11 @@ file_rev_handler(void *baton, const char
   if (frb->ctx->notify_func2)
     {
       svn_wc_notify_t *notify
-        = svn_wc_create_notify(path, svn_wc_notify_blame_revision, pool);
+            = svn_wc_create_notify_url(
+                            svn_path_url_add_component2(frb->repos_root_url,
+                                                        path+1, pool),
+                            svn_wc_notify_blame_revision, pool);
+      notify->path = path;
       notify->kind = svn_node_none;
       notify->content_state = notify->prop_state
         = svn_wc_notify_state_inapplicable;
@@ -642,8 +646,7 @@ svn_client_blame5(const char *target,
       frb.merged_chain->pool = pool;
     }
 
-  SVN_ERR(svn_io_temp_dir(&frb.tmp_path, pool));
-  frb.tmp_path = svn_dirent_join(frb.tmp_path, "tmp", pool),
+  SVN_ERR(svn_ra_get_repos_root2(ra_session, &frb.repos_root_url, pool));
 
   frb.mainpool = pool;
   /* The callback will flip the following two pools, because it needs

Modified: subversion/branches/revprop-packing/subversion/libsvn_client/cat.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_client/cat.c?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_client/cat.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_client/cat.c Wed Aug 24 15:16:50 2011
@@ -50,6 +50,7 @@ svn_client__get_normalized_stream(svn_st
                                   const char *local_abspath,
                                   const svn_opt_revision_t *revision,
                                   svn_boolean_t expand_keywords,
+                                  svn_boolean_t normalize_eols,
                                   svn_cancel_func_t cancel_func,
                                   void *cancel_baton,
                                   apr_pool_t *result_pool,
@@ -163,8 +164,10 @@ svn_client__get_normalized_stream(svn_st
 
   /* Wrap the output stream if translation is needed. */
   if (eol != NULL || kw != NULL)
-    input = svn_subst_stream_translated(input, eol, FALSE, kw, expand_keywords,
-                                        result_pool);
+    input = svn_subst_stream_translated(
+      input,
+      (eol_style && normalize_eols) ? SVN_SUBST_NATIVE_EOL_STR : eol,
+      FALSE, kw, expand_keywords, result_pool);
 
   *normal_stream = input;
 
@@ -211,7 +214,7 @@ svn_client_cat2(svn_stream_t *out,
 
       SVN_ERR(svn_dirent_get_absolute(&local_abspath, path_or_url, pool));
       SVN_ERR(svn_client__get_normalized_stream(&normal_stream, ctx->wc_ctx,
-                                            local_abspath, revision, TRUE,
+                                            local_abspath, revision, TRUE, FALSE,
                                             ctx->cancel_func, ctx->cancel_baton,
                                             pool, pool));
 

Modified: subversion/branches/revprop-packing/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_client/client.h?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_client/client.h (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_client/client.h Wed Aug 24 15:16:50 2011
@@ -595,11 +595,22 @@ svn_client__switch_internal(svn_revnum_t
 
    DEPTH is the depth to recurse.
 
-   RA_SESSION defines the additional RA session for requesting file
-   contents.
+   RA_SESSION is an RA session through which this editor may fetch
+   properties, file contents and directory listings of the 'old' side of the
+   diff. It is a separate RA session from the one through which this editor
+   is being driven.
 
    REVISION is the start revision in the comparison.
 
+   For each deleted directory, if WALK_DELETED_DIRS is true then just call
+   the 'dir_deleted' callback once, otherwise call the 'file_deleted' or
+   'dir_deleted' callback for each individual node in that subtree.
+
+   If TEXT_DELTAS is FALSE, then do not expect text deltas from the edit
+   drive, nor send text deltas to the diff callbacks.
+   ### TODO: The implementation currently does send text deltas to the diff
+       callbacks in many cases even if they are not wanted.
+
    If NOTIFY_FUNC is non-null, invoke it with NOTIFY_BATON for each
    file and directory operated on during the edit.
 
@@ -613,6 +624,7 @@ svn_client__get_diff_editor(const svn_de
                             svn_ra_session_t *ra_session,
                             svn_revnum_t revision,
                             svn_boolean_t walk_deleted_dirs,
+                            svn_boolean_t text_deltas,
                             const svn_wc_diff_callbacks4_t *diff_callbacks,
                             void *diff_cmd_baton,
                             svn_cancel_func_t cancel_func,
@@ -626,29 +638,23 @@ svn_client__get_diff_editor(const svn_de
 
 /*** Editor for diff summary ***/
 
-/* Create an editor for a repository diff summary, i.e. comparing one
-   repository version against the other and only providing information
-   about the changed items without the text deltas.
+/* Set *CALLBACKS and *CALLBACK_BATON to a set of diff callbacks that will
+   report a diff summary, i.e. only providing information about the changed
+   items without the text deltas.
 
-   TARGET is the target of the diff, relative to the root of the edit.
+   TARGET is the target path, relative to the anchor, of the diff.
 
    SUMMARIZE_FUNC is called with SUMMARIZE_BATON as parameter by the
-   created svn_delta_editor_t for each changed item.
-
-   See svn_client__get_diff_editor() for a description of the other
-   parameters.  */
+   created callbacks for each changed item.
+*/
 svn_error_t *
-svn_client__get_diff_summarize_editor(const char *target,
-                                      svn_client_diff_summarize_func_t
-                                      summarize_func,
-                                      void *summarize_baton,
-                                      svn_ra_session_t *ra_session,
-                                      svn_revnum_t revision,
-                                      svn_cancel_func_t cancel_func,
-                                      void *cancel_baton,
-                                      const svn_delta_editor_t **editor,
-                                      void **edit_baton,
-                                      apr_pool_t *pool);
+svn_client__get_diff_summarize_callbacks(
+                        svn_wc_diff_callbacks4_t **callbacks,
+                        void **callback_baton,
+                        const char *target,
+                        svn_client_diff_summarize_func_t summarize_func,
+                        void *summarize_baton,
+                        apr_pool_t *pool);
 
 /* ---------------------------------------------------------------- */
 
@@ -1051,13 +1057,21 @@ svn_client__ensure_revprop_table(apr_has
 
 /* Return a potentially translated version of local file LOCAL_ABSPATH
    in NORMAL_STREAM.  REVISION must be one of the following: BASE, COMMITTED,
-   WORKING.  Uses SCRATCH_POOL for temporary allocations. */
+   WORKING.
+
+   EXPAND_KEYWORDS operates as per the EXPAND argument to
+   svn_subst_stream_translated, which see.  If NORMALIZE_EOLS is TRUE and
+   LOCAL_ABSPATH requires translation, then normalize the line endings in
+   *NORMAL_STREAM.
+
+   Uses SCRATCH_POOL for temporary allocations. */
 svn_error_t *
 svn_client__get_normalized_stream(svn_stream_t **normal_stream,
                                   svn_wc_context_t *wc_ctx,
                                   const char *local_abspath,
                                   const svn_opt_revision_t *revision,
                                   svn_boolean_t expand_keywords,
+                                  svn_boolean_t normalize_eols,
                                   svn_cancel_func_t cancel_func,
                                   void *cancel_baton,
                                   apr_pool_t *result_pool,

Modified: subversion/branches/revprop-packing/subversion/libsvn_client/cmdline.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_client/cmdline.c?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_client/cmdline.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_client/cmdline.c Wed Aug 24 15:16:50 2011
@@ -292,7 +292,9 @@ svn_client_args_to_target_array2(apr_arr
                                                   original_target, pool));
                   err2 = svn_wc_read_kind(&kind, ctx->wc_ctx, target_abspath,
                                           FALSE, pool);
-                  if (err2 && err2->apr_err == SVN_ERR_WC_NOT_WORKING_COPY)
+                  if (err2
+                      && (err2->apr_err == SVN_ERR_WC_NOT_WORKING_COPY
+                          || err2->apr_err == SVN_ERR_WC_UPGRADE_REQUIRED))
                     {
                       svn_error_clear(err2);
                     }

Modified: subversion/branches/revprop-packing/subversion/libsvn_client/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_client/commit.c?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_client/commit.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_client/commit.c Wed Aug 24 15:16:50 2011
@@ -696,7 +696,6 @@ svn_client_import4(const char *path,
   apr_hash_t *excludes = apr_hash_make(pool);
   svn_node_kind_t kind;
   const char *local_abspath;
-  const char *base_dir_abspath;
   apr_array_header_t *new_entries = apr_array_make(pool, 4,
                                                    sizeof(const char *));
   const char *temp;
@@ -708,7 +707,6 @@ svn_client_import4(const char *path,
                              _("'%s' is not a local path"), path);
 
   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
-  base_dir_abspath = local_abspath;
 
   /* Create a new commit item and add it to the array. */
   if (SVN_CLIENT__HAS_LOG_MSG_FUNC(ctx))
@@ -739,8 +737,6 @@ svn_client_import4(const char *path,
     }
 
   SVN_ERR(svn_io_check_path(local_abspath, &kind, pool));
-  if (kind == svn_node_file)
-    base_dir_abspath = svn_dirent_dirname(local_abspath, pool);
 
   /* Figure out all the path components we need to create just to have
      a place to stick our imported tree. */
@@ -770,7 +766,7 @@ svn_client_import4(const char *path,
         }
     }
   while ((err = get_ra_editor(&ra_session,
-                              &editor, &edit_baton, ctx, url, base_dir_abspath,
+                              &editor, &edit_baton, ctx, url, NULL,
                               log_msg, NULL, revprop_table, FALSE, NULL, TRUE,
                               commit_callback, commit_baton, subpool)));
 
@@ -1356,6 +1352,128 @@ svn_client_commit5(const apr_array_heade
       goto cleanup;
   }
 
+  /* For every target that was moved verify that both halves of the
+   * move are part of the commit. */
+  for (i = 0; i < commit_items->nelts; i++)
+    {
+      svn_client_commit_item3_t *item =
+        APR_ARRAY_IDX(commit_items, i, svn_client_commit_item3_t *);
+
+      svn_pool_clear(iterpool);
+
+      if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_IS_COPY)
+        {
+          const char *moved_from_abspath;
+          const char *delete_op_root_abspath;
+
+          cmt_err = svn_error_trace(svn_wc__node_was_moved_here(
+                                      &moved_from_abspath,
+                                      &delete_op_root_abspath,
+                                      ctx->wc_ctx, item->path,
+                                      iterpool, iterpool));
+          if (cmt_err)
+            goto cleanup;
+
+          if (moved_from_abspath && delete_op_root_abspath &&
+              strcmp(moved_from_abspath, delete_op_root_abspath) == 0)
+
+            {
+              svn_boolean_t found_delete_half =
+                (apr_hash_get(committables->by_path, delete_op_root_abspath,
+                               APR_HASH_KEY_STRING) != NULL);
+              
+              if (!found_delete_half)
+                {
+                  const char *delete_half_parent_abspath;
+
+                  /* The delete-half isn't in the commit target list.
+                   * However, it might itself be the child of a deleted node,
+                   * either because of another move or a deletion.
+                   *
+                   * For example, consider: mv A/B B; mv B/C C; commit;
+                   * C's moved-from A/B/C is a child of the deleted A/B.
+                   * A/B/C does not appear in the commit target list, but
+                   * A/B does appear.
+                   * (Note that moved-from information is always stored
+                   * relative to the BASE tree, so we have 'C moved-from
+                   * A/B/C', not 'C moved-from B/C'.)
+                   *
+                   * An example involving a move and a delete would be:
+                   * mv A/B C; rm A; commit;
+                   * Now C is moved-from A/B which does not appear in the
+                   * commit target list, but A does appear.
+                   */
+
+                  /* Scan upwards for a deletion op-root from the
+                   * delete-half's parent directory. */
+                  delete_half_parent_abspath =
+                    svn_dirent_dirname(delete_op_root_abspath, iterpool);
+                  if (strcmp(delete_op_root_abspath,
+                             delete_half_parent_abspath) != 0)
+                    {
+                      const char *parent_delete_op_root_abspath;
+
+                      cmt_err = svn_error_trace(
+                                  svn_wc__node_get_deleted_ancestor(
+                                    &parent_delete_op_root_abspath,
+                                    ctx->wc_ctx, delete_half_parent_abspath,
+                                    iterpool, iterpool));
+                      if (cmt_err)
+                        goto cleanup;
+
+                      if (parent_delete_op_root_abspath)
+                        found_delete_half =
+                          (apr_hash_get(committables->by_path,
+                                        parent_delete_op_root_abspath,
+                                        APR_HASH_KEY_STRING) != NULL);
+                    }
+                }
+
+              if (!found_delete_half)
+                {
+                  cmt_err = svn_error_createf(
+                              SVN_ERR_ILLEGAL_TARGET, NULL,
+                              _("Cannot commit '%s' because it was moved from "
+                                "'%s' which is not part of the commit; both "
+                                "sides of the move must be committed together"),
+                              svn_dirent_local_style(item->path, iterpool),
+                              svn_dirent_local_style(delete_op_root_abspath,
+                                                     iterpool));
+                  goto cleanup;
+                }
+            }
+        }
+      else if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
+        {
+          const char *moved_to_abspath;
+          const char *copy_op_root_abspath;
+
+          cmt_err = svn_error_trace(svn_wc__node_was_moved_away(
+                                      &moved_to_abspath,
+                                      &copy_op_root_abspath,
+                                      ctx->wc_ctx, item->path,
+                                      iterpool, iterpool));
+          if (cmt_err)
+            goto cleanup;
+
+          if (moved_to_abspath && copy_op_root_abspath &&
+              strcmp(moved_to_abspath, copy_op_root_abspath) == 0 &&
+              apr_hash_get(committables->by_path, copy_op_root_abspath,
+                           APR_HASH_KEY_STRING) == NULL)
+            {
+              cmt_err = svn_error_createf(
+                          SVN_ERR_ILLEGAL_TARGET, NULL,
+                         _("Cannot commit '%s' because it was moved to '%s' "
+                           "which is not part of the commit; both sides of "
+                           "the move must be committed together"),
+                         svn_dirent_local_style(item->path, iterpool),
+                         svn_dirent_local_style(copy_op_root_abspath,
+                                                iterpool));
+              goto cleanup;
+            }
+        }
+    }
+
   /* Go get a log message.  If an error occurs, or no log message is
      specified, abort the operation. */
   if (SVN_CLIENT__HAS_LOG_MSG_FUNC(ctx))

Modified: subversion/branches/revprop-packing/subversion/libsvn_client/diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_client/diff.c?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_client/diff.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_client/diff.c Wed Aug 24 15:16:50 2011
@@ -400,15 +400,22 @@ print_git_diff_header_deleted(svn_stream
  * OS using HEADER_ENCODING. All allocations are done in RESULT_POOL. */
 static svn_error_t *
 print_git_diff_header_copied(svn_stream_t *os, const char *header_encoding,
-                             const char *copyfrom_path, const char *path,
+                             const char *copyfrom_path,
+                             svn_revnum_t copyfrom_rev,
+                             const char *path,
                              apr_pool_t *result_pool)
 {
   SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, result_pool,
                                       "diff --git a/%s b/%s%s",
                                       copyfrom_path, path, APR_EOL_STR));
-  SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, result_pool,
-                                      "copy from %s%s", copyfrom_path,
-                                      APR_EOL_STR));
+  if (copyfrom_rev != SVN_INVALID_REVNUM)
+    SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, result_pool,
+                                        "copy from %s@%ld%s", copyfrom_path,
+                                        copyfrom_rev, APR_EOL_STR));
+  else
+    SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, result_pool,
+                                        "copy from %s%s", copyfrom_path,
+                                        APR_EOL_STR));
   SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, result_pool,
                                       "copy to %s%s", path, APR_EOL_STR));
   return SVN_NO_ERROR;
@@ -450,9 +457,10 @@ print_git_diff_header_modified(svn_strea
  * HEADER_ENCODING. Return suitable diff labels for the git diff in *LABEL1
  * and *LABEL2. REPOS_RELPATH1 and REPOS_RELPATH2 are relative to reposroot.
  * are the paths passed to the original diff command. REV1 and REV2 are
- * revisions being diffed. COPYFROM_PATH indicates where the diffed item
- * was copied from. RA_SESSION and WC_CTX are used to adjust paths in the
- * headers to be relative to the repository root.
+ * revisions being diffed. COPYFROM_PATH and COPYFROM_REV indicate where the
+ * diffed item was copied from.
+ * RA_SESSION and WC_CTX are used to adjust paths in the headers to be
+ * relative to the repository root.
  * WC_ROOT_ABSPATH is the absolute path to the root directory of a working
  * copy involved in a repos-wc diff, and may be NULL.
  * Use SCRATCH_POOL for temporary allocations. */
@@ -465,6 +473,7 @@ print_git_diff_header(svn_stream_t *os,
                       svn_revnum_t rev1,
                       svn_revnum_t rev2,
                       const char *copyfrom_path,
+                      svn_revnum_t copyfrom_rev,
                       const char *header_encoding,
                       svn_ra_session_t *ra_session,
                       svn_wc_context_t *wc_ctx,
@@ -484,7 +493,8 @@ print_git_diff_header(svn_stream_t *os,
   else if (operation == svn_diff_op_copied)
     {
       SVN_ERR(print_git_diff_header_copied(os, header_encoding,
-                                           copyfrom_path, repos_relpath2,
+                                           copyfrom_path, copyfrom_rev,
+                                           repos_relpath2,
                                            scratch_pool));
       *label1 = diff_label(apr_psprintf(scratch_pool, "a/%s", copyfrom_path),
                            rev1, scratch_pool);
@@ -605,6 +615,7 @@ display_prop_diffs(const apr_array_heade
           SVN_ERR(print_git_diff_header(os, &label1, &label2,
                                         svn_diff_op_modified,
                                         path1, path2, rev1, rev2, NULL,
+                                        SVN_INVALID_REVNUM,
                                         encoding, ra_session, wc_ctx,
                                         wc_root_abspath, pool));
           SVN_ERR(svn_stream_close(os));
@@ -809,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;
 
@@ -880,7 +890,7 @@ diff_dir_props_changed(svn_wc_notify_sta
                                             dir_was_added,
                                             propchanges,
                                             original_props,
-                                            diff_baton,
+                                            diff_cmd_baton,
                                             scratch_pool));
 }
 
@@ -899,9 +909,9 @@ diff_content_changed(const char *path,
                      const char *mimetype2,
                      svn_diff_operation_kind_t operation,
                      const char *copyfrom_path,
-                     void *diff_baton)
+                     svn_revnum_t copyfrom_rev,
+                     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;
@@ -1028,6 +1038,7 @@ diff_content_changed(const char *path,
               SVN_ERR(print_git_diff_header(os, &label1, &label2, operation,
                                             tmp_path1, tmp_path2, rev1, rev2,
                                             copyfrom_path,
+                                            copyfrom_rev,
                                             diff_cmd_baton->header_encoding,
                                             diff_cmd_baton->ra_session,
                                             diff_cmd_baton->wc_ctx,
@@ -1092,17 +1103,19 @@ 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)
     SVN_ERR(diff_content_changed(path,
                                  tmpfile1, tmpfile2, rev1, rev2,
                                  mimetype1, mimetype2,
-                                 svn_diff_op_modified, NULL, diff_baton));
+                                 svn_diff_op_modified, NULL,
+                                 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)
@@ -1152,16 +1165,17 @@ diff_file_added(svn_wc_notify_state_t *c
                                  tmpfile1, tmpfile2, rev1, rev2,
                                  mimetype1, mimetype2,
                                  svn_diff_op_copied, copyfrom_path,
-                                 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, diff_baton));
+                                 svn_diff_op_added, NULL, 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)
@@ -1208,7 +1222,8 @@ diff_file_deleted(svn_wc_notify_state_t 
                                      diff_cmd_baton->revnum1,
                                      diff_cmd_baton->revnum2,
                                      mimetype1, mimetype2,
-                                     svn_diff_op_deleted, NULL, diff_baton));
+                                     svn_diff_op_deleted, NULL,
+                                     SVN_INVALID_REVNUM, diff_cmd_baton));
     }
 
   /* We don't list all the deleted properties. */
@@ -1737,7 +1752,8 @@ diff_repos_repos(const svn_wc_diff_callb
   SVN_ERR(svn_client__get_diff_editor(
                 &diff_editor, &diff_edit_baton,
                 NULL, "", depth,
-                extra_ra_session, rev1, TRUE,
+                extra_ra_session, rev1, TRUE /* walk_deleted_dirs */,
+                TRUE /* text_deltas */,
                 callbacks, callback_baton,
                 ctx->cancel_func, ctx->cancel_baton,
                 NULL /* no notify_func */, NULL /* no notify_baton */,
@@ -1746,7 +1762,7 @@ diff_repos_repos(const svn_wc_diff_callb
   /* We want to switch our txn into URL2 */
   SVN_ERR(svn_ra_do_diff3
           (ra_session, &reporter, &reporter_baton, rev2, target1,
-           depth, ignore_ancestry, TRUE,
+           depth, ignore_ancestry, TRUE /* text_deltas */,
            url2, diff_editor, diff_edit_baton, pool));
 
   /* Drive the reporter; do the diff. */
@@ -1954,6 +1970,7 @@ do_diff(const svn_wc_diff_callbacks4_t *
     {
       if (is_repos2)
         {
+          /* ### Ignores 'show_copies_as_adds'. */
           SVN_ERR(diff_repos_repos(callbacks, callback_baton, ctx,
                                    path1, path2, revision1, revision2,
                                    peg_revision, depth, ignore_ancestry,
@@ -1990,6 +2007,64 @@ do_diff(const svn_wc_diff_callbacks4_t *
   return SVN_NO_ERROR;
 }
 
+/* Perform a summary diff between two working-copy paths.
+
+   PATH1 and PATH2 are both working copy paths.  REVISION1 and
+   REVISION2 are their respective revisions.
+
+   All other options are the same as those passed to svn_client_diff5(). */
+static svn_error_t *
+diff_summarize_wc_wc(svn_client_diff_summarize_func_t summarize_func,
+                     void *summarize_baton,
+                     const char *path1,
+                     const svn_opt_revision_t *revision1,
+                     const char *path2,
+                     const svn_opt_revision_t *revision2,
+                     svn_depth_t depth,
+                     svn_boolean_t ignore_ancestry,
+                     const apr_array_header_t *changelists,
+                     svn_client_ctx_t *ctx,
+                     apr_pool_t *pool)
+{
+  svn_wc_diff_callbacks4_t *callbacks;
+  void *callback_baton;
+  const char *abspath1, *target1;
+  svn_node_kind_t kind;
+
+  SVN_ERR_ASSERT(! svn_path_is_url(path1));
+  SVN_ERR_ASSERT(! svn_path_is_url(path2));
+
+  /* Currently we support only the case where path1 and path2 are the
+     same path. */
+  if ((strcmp(path1, path2) != 0)
+      || (! ((revision1->kind == svn_opt_revision_base)
+             && (revision2->kind == svn_opt_revision_working))))
+    return unsupported_diff_error
+      (svn_error_create
+       (SVN_ERR_INCORRECT_PARAMS, NULL,
+        _("Only diffs between a path's text-base "
+          "and its working files are supported at this time")));
+
+  /* Find the node kind of PATH1 so that we know whether the diff drive will
+     be anchored at PATH1 or its parent dir. */
+  SVN_ERR(svn_dirent_get_absolute(&abspath1, path1, pool));
+  SVN_ERR(svn_wc_read_kind(&kind, ctx->wc_ctx, abspath1, FALSE, pool));
+  target1 = (kind == svn_node_dir) ? "" : svn_dirent_basename(path1, pool);
+  SVN_ERR(svn_client__get_diff_summarize_callbacks(
+            &callbacks, &callback_baton, target1,
+            summarize_func, summarize_baton, pool));
+
+  SVN_ERR(svn_wc_diff6(ctx->wc_ctx,
+                       abspath1,
+                       callbacks, callback_baton,
+                       depth,
+                       ignore_ancestry, FALSE /* show_copies_as_adds */,
+                       FALSE /* use_git_diff_format */, changelists,
+                       ctx->cancel_func, ctx->cancel_baton,
+                       pool));
+  return SVN_NO_ERROR;
+}
+
 /* Perform a diff summary between two repository paths. */
 static svn_error_t *
 diff_summarize_repos_repos(svn_client_diff_summarize_func_t summarize_func,
@@ -2022,6 +2097,8 @@ diff_summarize_repos_repos(svn_client_di
   const char *target1;
   const char *target2;
   svn_ra_session_t *ra_session;
+  svn_wc_diff_callbacks4_t *callbacks;
+  void *callback_baton;
 
   /* Prepare info for the repos repos diff. */
   SVN_ERR(diff_prepare_repos_repos(&url1, &url2, &base_path, &rev1, &rev2,
@@ -2030,6 +2107,10 @@ diff_summarize_repos_repos(svn_client_di
                                    path1, path2, revision1, revision2,
                                    peg_revision, pool));
 
+  SVN_ERR(svn_client__get_diff_summarize_callbacks(
+            &callbacks, &callback_baton,
+            target1, summarize_func, summarize_baton, pool));
+
   /* Now, we open an extra RA session to the correct anchor
      location for URL1.  This is used to get the kind of deleted paths.  */
   SVN_ERR(svn_client__open_ra_session_internal(&extra_ra_session, NULL,
@@ -2037,10 +2118,13 @@ diff_summarize_repos_repos(svn_client_di
                                                TRUE, ctx, pool));
 
   /* Set up the repos_diff editor. */
-  SVN_ERR(svn_client__get_diff_summarize_editor
-          (target2, summarize_func,
-           summarize_baton, extra_ra_session, rev1, ctx->cancel_func,
-           ctx->cancel_baton, &diff_editor, &diff_edit_baton, pool));
+  SVN_ERR(svn_client__get_diff_editor(&diff_editor, &diff_edit_baton,
+            NULL /* wc_ctx */, "", depth,
+            extra_ra_session, rev1, TRUE /* walk_deleted_dirs */,
+            FALSE /* text_deltas */,
+            callbacks, callback_baton,
+            ctx->cancel_func, ctx->cancel_baton,
+            NULL /* notify_func */, NULL /* notify_baton */, pool));
 
   /* We want to switch our txn into URL2 */
   SVN_ERR(svn_ra_do_diff3
@@ -2068,6 +2152,7 @@ do_diff_summarize(svn_client_diff_summar
                   const svn_opt_revision_t *peg_revision,
                   svn_depth_t depth,
                   svn_boolean_t ignore_ancestry,
+                  const apr_array_header_t *changelists,
                   apr_pool_t *pool)
 {
   svn_boolean_t is_repos1;
@@ -2082,10 +2167,16 @@ do_diff_summarize(svn_client_diff_summar
                                       path1, path2, revision1, revision2,
                                       peg_revision, depth, ignore_ancestry,
                                       pool);
+  else if (! is_repos1 && ! is_repos2)
+    return diff_summarize_wc_wc(summarize_func, summarize_baton,
+                                path1, revision1, path2, revision2,
+                                depth, ignore_ancestry,
+                                changelists, ctx, pool);
   else
-    return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-                            _("Summarizing diff can only compare repository "
-                              "to repository"));
+   return unsupported_diff_error(
+            svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                             _("Summarizing diff cannot compare repository "
+                               "to WC")));
 }
 
 
@@ -2315,10 +2406,9 @@ svn_client_diff_summarize2(const char *p
   svn_opt_revision_t peg_revision;
   peg_revision.kind = svn_opt_revision_unspecified;
 
-  /* ### CHANGELISTS parameter isn't used */
   return do_diff_summarize(summarize_func, summarize_baton, ctx,
                            path1, path2, revision1, revision2, &peg_revision,
-                           depth, ignore_ancestry, pool);
+                           depth, ignore_ancestry, changelists, pool);
 }
 
 svn_error_t *
@@ -2334,10 +2424,10 @@ svn_client_diff_summarize_peg2(const cha
                                svn_client_ctx_t *ctx,
                                apr_pool_t *pool)
 {
-  /* ### CHANGELISTS parameter isn't used */
   return do_diff_summarize(summarize_func, summarize_baton, ctx,
                            path, path, start_revision, end_revision,
-                           peg_revision, depth, ignore_ancestry, pool);
+                           peg_revision,
+                           depth, ignore_ancestry, changelists, pool);
 }
 
 svn_client_diff_summarize_t *

Modified: subversion/branches/revprop-packing/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_client/externals.c?rev=1161147&r1=1161146&r2=1161147&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_client/externals.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_client/externals.c Wed Aug 24 15:16:50 2011
@@ -898,6 +898,11 @@ handle_external_item_change(const struct
                    scratch_pool));
           break;
         case svn_node_file:
+          if (strcmp(eb->repos_root_url, ra_cache.repos_root_url))
+            return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                      _("Unsupported external: "
+                        "url of file external '%s' is not in repository '%s'"),
+                      new_url, eb->repos_root_url);
           SVN_ERR(switch_file_external(local_abspath,
                                        new_url,
                                        &new_item->peg_revision,
@@ -947,6 +952,11 @@ handle_external_item_change(const struct
                                       scratch_pool));
           break;
         case svn_node_file:
+          if (strcmp(eb->repos_root_url, ra_cache.repos_root_url))
+            return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                      _("Unsupported external: "
+                        "url of file external '%s' is not in repository '%s'"),
+                      new_url, eb->repos_root_url);
           SVN_ERR(switch_file_external(local_abspath,
                                        new_url,
                                        &new_item->peg_revision,