You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pb...@apache.org on 2010/11/05 14:23:01 UTC

svn commit: r1031554 [1/2] - in /subversion/branches/issue-3668-3669: ./ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/ subversion/bi...

Author: pburba
Date: Fri Nov  5 13:23:00 2010
New Revision: 1031554

URL: http://svn.apache.org/viewvc?rev=1031554&view=rev
Log:
On the issue-3668-3669 branch: Sync with subversion/trunk.

Added:
    subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/apache/subversion/javahl/Info.java
      - copied unchanged from r1031553, subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/Info.java
Removed:
    subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/apache/subversion/javahl/Info2.java
Modified:
    subversion/branches/issue-3668-3669/   (props changed)
    subversion/branches/issue-3668-3669/COMMITTERS
    subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/CreateJ.cpp
    subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/CreateJ.h
    subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/EnumMapper.cpp
    subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/InfoCallback.cpp
    subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/InfoCallback.java
    subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/tigris/subversion/javahl/Info.java
    subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/tigris/subversion/javahl/Info2.java
    subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java
    subversion/branches/issue-3668-3669/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
    subversion/branches/issue-3668-3669/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNReposTests.java
    subversion/branches/issue-3668-3669/subversion/include/svn_client.h
    subversion/branches/issue-3668-3669/subversion/include/svn_wc.h
    subversion/branches/issue-3668-3669/subversion/libsvn_client/blame.c
    subversion/branches/issue-3668-3669/subversion/libsvn_client/copy.c
    subversion/branches/issue-3668-3669/subversion/libsvn_client/deprecated.c
    subversion/branches/issue-3668-3669/subversion/libsvn_client/export.c
    subversion/branches/issue-3668-3669/subversion/libsvn_client/info.c
    subversion/branches/issue-3668-3669/subversion/libsvn_client/relocate.c
    subversion/branches/issue-3668-3669/subversion/libsvn_client/status.c
    subversion/branches/issue-3668-3669/subversion/libsvn_diff/parse-diff.c
    subversion/branches/issue-3668-3669/subversion/libsvn_subr/subst.c
    subversion/branches/issue-3668-3669/subversion/libsvn_wc/adm_ops.c
    subversion/branches/issue-3668-3669/subversion/libsvn_wc/update_editor.c
    subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc-queries.sql
    subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc_db.c
    subversion/branches/issue-3668-3669/subversion/svn/info-cmd.c
    subversion/branches/issue-3668-3669/subversion/svn/schema/info.rnc
    subversion/branches/issue-3668-3669/subversion/svn/status-cmd.c
    subversion/branches/issue-3668-3669/subversion/tests/cmdline/blame_tests.py
    subversion/branches/issue-3668-3669/subversion/tests/cmdline/copy_tests.py
    subversion/branches/issue-3668-3669/subversion/tests/cmdline/info_tests.py
    subversion/branches/issue-3668-3669/subversion/tests/cmdline/input_validation_tests.py
    subversion/branches/issue-3668-3669/subversion/tests/cmdline/schedule_tests.py
    subversion/branches/issue-3668-3669/subversion/tests/cmdline/svntest/sandbox.py
    subversion/branches/issue-3668-3669/subversion/tests/libsvn_wc/op-depth-test.c

Propchange: subversion/branches/issue-3668-3669/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Nov  5 13:23:00 2010
@@ -23,7 +23,7 @@
 /subversion/branches/log-g-performance:870941-871032
 /subversion/branches/merge-skips-obstructions:874525-874615
 /subversion/branches/nfc-nfd-aware-client:870276,870376
-/subversion/branches/performance:982355,983764,983766,984927,984984,985014,985037,985046,985472,985477,985482,985500,985606,985669,987888,987893,995507,995603,1001413,1025660,1028092,1028094,1028104,1029038,1029090
+/subversion/branches/performance:982355,983764,983766,984927,984984,985014,985037,985046,985472,985477,985482,985500,985606,985669,986453,987888,987893,995507,995603,1001413,1025660,1028092,1028094,1028104,1029038,1029042,1029090,1029092,1029335,1030763
 /subversion/branches/ra_serf-digest-authn:875693-876404
 /subversion/branches/reintegrate-improvements:873853-874164
 /subversion/branches/subtree-mergeinfo:876734-878766
@@ -38,3 +38,4 @@
 /subversion/branches/tc_url_rev:874351-874483
 /subversion/branches/tree-conflicts:868291-873154
 /subversion/branches/tree-conflicts-notify:873926-874008
+/subversion/trunk:1031000-1031553

Modified: subversion/branches/issue-3668-3669/COMMITTERS
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/COMMITTERS?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/COMMITTERS [UTF-8] (original)
+++ subversion/branches/issue-3668-3669/COMMITTERS [UTF-8] Fri Nov  5 13:23:00 2010
@@ -180,6 +180,8 @@ giorgio_valoti   Giorgio Valoti <giorgio
                                                               br.)
         holden   Holden Karau <ho...@pigscanfly.ca>         (scheme-bindings br.)
        stefan2   Stefan Fuhrmann <st...@alice-dsl.de> (performance br.)
+       jcorvel   Johan Corveleyn <jc...@gmail.com>         (diff-
+                                                              optimizations br.)
 
   Subprojects that are complete, abandoned or have moved elsewhere:
 

Modified: subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/CreateJ.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/CreateJ.cpp?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/CreateJ.cpp (original)
+++ subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/CreateJ.cpp Fri Nov  5 13:23:00 2010
@@ -177,7 +177,7 @@ CreateJ::ConflictVersion(const svn_wc_co
 }
 
 jobject
-CreateJ::Info2(const char *path, const svn_info_t *info)
+CreateJ::Info(const char *path, const svn_info_t *info)
 {
   JNIEnv *env = JNIUtil::getEnv();
 
@@ -186,7 +186,7 @@ CreateJ::Info2(const char *path, const s
   if (JNIUtil::isJavaExceptionThrown())
     return NULL;
 
-  jclass clazz = env->FindClass(JAVA_PACKAGE "/Info2");
+  jclass clazz = env->FindClass(JAVA_PACKAGE "/Info");
   if (JNIUtil::isJavaExceptionThrown())
     POP_AND_RETURN_NULL;
 
@@ -194,12 +194,13 @@ CreateJ::Info2(const char *path, const s
   if (mid == 0)
     {
       mid = env->GetMethodID(clazz, "<init>",
-                             "(Ljava/lang/String;Ljava/lang/String;J"
+                             "(Ljava/lang/String;Ljava/lang/String;"
+                             "Ljava/lang/String;J"
                              "L"JAVA_PACKAGE"/NodeKind;"
                              "Ljava/lang/String;Ljava/lang/String;"
                              "JJLjava/lang/String;"
                              "L"JAVA_PACKAGE"/Lock;Z"
-                             "L"JAVA_PACKAGE"/Info2$ScheduleKind;"
+                             "L"JAVA_PACKAGE"/Info$ScheduleKind;"
                              "Ljava/lang/String;JJJ"
                              "Ljava/lang/String;Ljava/lang/String;"
                              "Ljava/lang/String;Ljava/lang/String;"
@@ -214,6 +215,10 @@ CreateJ::Info2(const char *path, const s
   if (JNIUtil::isJavaExceptionThrown())
     POP_AND_RETURN_NULL;
 
+  jstring jwcroot = JNIUtil::makeJString(info->wcroot_abspath);
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+
   jstring jurl = JNIUtil::makeJString(info->URL);
   if (JNIUtil::isJavaExceptionThrown())
     POP_AND_RETURN_NULL;
@@ -280,7 +285,8 @@ CreateJ::Info2(const char *path, const s
   jlong jreposSize = info->size == SVN_INFO_SIZE_UNKNOWN
     ? -1 : (jlong) info->size;
 
-  jobject jinfo2 = env->NewObject(clazz, mid, jpath, jurl, (jlong) info->rev,
+  jobject jinfo2 = env->NewObject(clazz, mid, jpath, jwcroot, jurl,
+                                  (jlong) info->rev,
                                   jnodeKind, jreposRootUrl, jreportUUID,
                                   (jlong) info->last_changed_rev,
                                   (jlong) info->last_changed_date,

Modified: subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/CreateJ.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/CreateJ.h?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/CreateJ.h (original)
+++ subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/CreateJ.h Fri Nov  5 13:23:00 2010
@@ -46,7 +46,7 @@ class CreateJ
   ConflictDescriptor(const svn_wc_conflict_description_t *desc);
 
   static jobject
-  Info2(const char *path, const svn_info_t *info);
+  Info(const char *path, const svn_info_t *info);
 
   static jobject
   Lock(const svn_lock_t *lock);

Modified: subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/EnumMapper.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/EnumMapper.cpp?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/EnumMapper.cpp (original)
+++ subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/EnumMapper.cpp Fri Nov  5 13:23:00 2010
@@ -132,7 +132,7 @@ jobject EnumMapper::mapNotifyLockState(s
 jobject EnumMapper::mapScheduleKind(svn_wc_schedule_t schedule)
 {
   // We're assuming a valid value for the C enum above
-  return mapEnum(JAVA_PACKAGE"/Info2$ScheduleKind", (int) schedule);
+  return mapEnum(JAVA_PACKAGE"/Info$ScheduleKind", (int) schedule);
 }
 
 /**

Modified: subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/InfoCallback.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/InfoCallback.cpp?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/InfoCallback.cpp (original)
+++ subversion/branches/issue-3668-3669/subversion/bindings/javahl/native/InfoCallback.cpp Fri Nov  5 13:23:00 2010
@@ -85,12 +85,12 @@ InfoCallback::singleInfo(const char *pat
         POP_AND_RETURN(SVN_NO_ERROR);
 
       mid = env->GetMethodID(clazz, "singleInfo",
-                             "(L"JAVA_PACKAGE"/Info2;)V");
+                             "(L"JAVA_PACKAGE"/Info;)V");
       if (JNIUtil::isJavaExceptionThrown() || mid == 0)
         POP_AND_RETURN(SVN_NO_ERROR);
     }
 
-  jobject jinfo2 = CreateJ::Info2(path, info);
+  jobject jinfo2 = CreateJ::Info(path, info);
   if (jinfo2 == NULL || JNIUtil::isJavaExceptionThrown())
     POP_AND_RETURN(SVN_NO_ERROR);
 

Modified: subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/InfoCallback.java
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/InfoCallback.java?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/InfoCallback.java (original)
+++ subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/InfoCallback.java Fri Nov  5 13:23:00 2010
@@ -23,7 +23,7 @@
 
 package org.apache.subversion.javahl.callback;
 
-import org.apache.subversion.javahl.Info2;
+import org.apache.subversion.javahl.Info;
 import org.apache.subversion.javahl.ISVNClient;
 
 /**
@@ -36,5 +36,5 @@ public interface InfoCallback
      * the method will be called for every line in a file.
      * @param info      the Info2 object
      */
-    public void singleInfo(Info2 info);
+    public void singleInfo(Info info);
 }

Modified: subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/tigris/subversion/javahl/Info.java
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/tigris/subversion/javahl/Info.java?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/tigris/subversion/javahl/Info.java (original)
+++ subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/tigris/subversion/javahl/Info.java Fri Nov  5 13:23:00 2010
@@ -144,7 +144,7 @@ public class Info implements java.io.Ser
     /**
      * A backward-compat constructor
      */
-    public Info(org.apache.subversion.javahl.Info2 aInfo)
+    public Info(org.apache.subversion.javahl.Info aInfo)
     {
         this((new File(aInfo.getPath())).getName(), aInfo.getUrl(),
              aInfo.getReposUUID(), aInfo.getReposRootUrl(),
@@ -153,7 +153,7 @@ public class Info implements java.io.Ser
              aInfo.getLastChangedAuthor(), aInfo.getRev(),
              aInfo.getLastChangedRev(), aInfo.getLastChangedDate(),
              aInfo.getTextTime(), aInfo.getPropTime(), aInfo.getCopyFromUrl() != null,
-             aInfo.getSchedule() == org.apache.subversion.javahl.Info2.ScheduleKind.delete,
+             aInfo.getSchedule() == org.apache.subversion.javahl.Info.ScheduleKind.delete,
              checkAbsent(aInfo.getPath()), checkIncomplete(aInfo.getPath()),
              aInfo.getCopyFromRev(), aInfo.getCopyFromUrl());
     }

Modified: subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/tigris/subversion/javahl/Info2.java
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/tigris/subversion/javahl/Info2.java?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/tigris/subversion/javahl/Info2.java (original)
+++ subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/tigris/subversion/javahl/Info2.java Fri Nov  5 13:23:00 2010
@@ -250,7 +250,7 @@ public class Info2 implements java.io.Se
     /**
      * A backward-compat constructor.
      */
-    public Info2(org.apache.subversion.javahl.Info2 aInfo)
+    public Info2(org.apache.subversion.javahl.Info aInfo)
     {
         this(aInfo.getPath(), aInfo.getUrl(), aInfo.getRev(),
              NodeKind.fromApache(aInfo.getKind()),

Modified: subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java (original)
+++ subversion/branches/issue-3668-3669/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java Fri Nov  5 13:23:00 2010
@@ -2348,15 +2348,15 @@ public class SVNClient implements SVNCli
     {
         try
         {
-        	final List<org.apache.subversion.javahl.Info2> infos =
-        		new ArrayList<org.apache.subversion.javahl.Info2>();
+        	final List<org.apache.subversion.javahl.Info> infos =
+        		new ArrayList<org.apache.subversion.javahl.Info>();
         	aSVNClient.info2(path,
         					org.apache.subversion.javahl.Revision.HEAD,
         					org.apache.subversion.javahl.Revision.HEAD,
         					org.apache.subversion.javahl.Depth.empty,
         				    null, new org.apache.subversion.javahl.callback.InfoCallback()
         	{
-				public void singleInfo(org.apache.subversion.javahl.Info2 info) {
+				public void singleInfo(org.apache.subversion.javahl.Info info) {
 					infos.add(info);
 				}
         	});
@@ -2593,7 +2593,7 @@ public class SVNClient implements SVNCli
                           Depth.toADepth(depth), changelists == null ? null
                             : Arrays.asList(changelists),
         new org.apache.subversion.javahl.callback.InfoCallback () {
-            public void singleInfo(org.apache.subversion.javahl.Info2 aInfo)
+            public void singleInfo(org.apache.subversion.javahl.Info aInfo)
             {
                 callback.singleInfo(aInfo == null ? null : new Info2(aInfo));
             }

Modified: subversion/branches/issue-3668-3669/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java (original)
+++ subversion/branches/issue-3668-3669/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java Fri Nov  5 13:23:00 2010
@@ -452,7 +452,7 @@ public class BasicTests extends SVNTests
                  client.update(thisTest.getWCPathSet("/A/B"),
                                null, Depth.unknown, false, false, false)[0],
                      rev);
-        Info2 Binfo = collectInfos(thisTest.getWCPath() + "/A/B", null, null,
+        Info Binfo = collectInfos(thisTest.getWCPath() + "/A/B", null, null,
                                    Depth.empty, null)[0];
         long BCommitDate = Binfo.getLastChangedDate().getTime();
         long BCommitRev = rev;
@@ -1959,12 +1959,12 @@ public class BasicTests extends SVNTests
         OneTest thisTest = new OneTest();
 
         // get the item information and test it
-        Info2 info = collectInfos(thisTest.getWCPath()+"/A/mu", null, null,
+        Info info = collectInfos(thisTest.getWCPath()+"/A/mu", null, null,
                                   Depth.empty, null)[0];
         assertEquals("wrong revision from info", 1,
                      info.getLastChangedRev());
         assertEquals("wrong schedule kind from info",
-                     Info2.ScheduleKind.normal, info.getSchedule());
+                     Info.ScheduleKind.normal, info.getSchedule());
         assertEquals("wrong node kind from info", NodeKind.file,
                      info.getKind());
     }
@@ -2085,13 +2085,13 @@ public class BasicTests extends SVNTests
         OneTest thisTest = new OneTest();
 
         final String failureMsg = "Incorrect number of info objects";
-        Info2[] infos = collectInfos(thisTest.getWCPath(), null, null,
+        Info[] infos = collectInfos(thisTest.getWCPath(), null, null,
                                      Depth.empty, null);
         assertEquals(failureMsg, 1, infos.length);
         infos = collectInfos(thisTest.getWCPath(), null, null, Depth.infinity,
                              null);
         assertEquals(failureMsg, 21, infos.length);
-        for (Info2 info : infos)
+        for (Info info : infos)
         {
             assertNull("Unexpected changelist present",
                        info.getChangelistName());
@@ -3486,13 +3486,13 @@ public class BasicTests extends SVNTests
     }
 
     private class MyInfoCallback implements InfoCallback {
-        private Info2 info;
+        private Info info;
 
-        public void singleInfo(Info2 info) {
+        public void singleInfo(Info info) {
             this.info = info;
         }
 
-        public Info2 getInfo() {
+        public Info getInfo() {
             return info;
         }
     }
@@ -3627,19 +3627,19 @@ public class BasicTests extends SVNTests
         return callback.getDirEntryArray();
     }
 
-    private Info2[] collectInfos(String pathOrUrl, Revision revision,
+    private Info[] collectInfos(String pathOrUrl, Revision revision,
                                  Revision pegRevision, Depth depth,
                                  Collection<String> changelists)
         throws ClientException
     {
-       final List<Info2> infos = new ArrayList<Info2>();
+       final List<Info> infos = new ArrayList<Info>();
        
         client.info2(pathOrUrl, revision, pegRevision, depth, changelists,
                      new InfoCallback () {
-            public void singleInfo(Info2 info)
+            public void singleInfo(Info info)
             { infos.add(info); }           
         });
-        return infos.toArray(new Info2[infos.size()]);
+        return infos.toArray(new Info[infos.size()]);
     }
 
     private LogMessage[] collectLogMessages(String path, Revision pegRevision,

Modified: subversion/branches/issue-3668-3669/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNReposTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNReposTests.java?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNReposTests.java (original)
+++ subversion/branches/issue-3668-3669/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNReposTests.java Fri Nov  5 13:23:00 2010
@@ -109,10 +109,10 @@ public class SVNReposTests extends SVNTe
         OneTest thisTest = new OneTest(false,false);
         // verify zero revisions in new repos
         URI repoUrl = makeReposUrl(thisTest.getRepository());
-        final Info2[] infoHolder = new Info2[1];
+        final Info[] infoHolder = new Info[1];
         InfoCallback mycallback = new InfoCallback()
         {
-            public void singleInfo(Info2 info)
+            public void singleInfo(Info info)
             {
                 infoHolder[0] = info;
             }

Modified: subversion/branches/issue-3668-3669/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/include/svn_client.h?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/include/svn_client.h (original)
+++ subversion/branches/issue-3668-3669/subversion/include/svn_client.h Fri Nov  5 13:23:00 2010
@@ -3470,12 +3470,13 @@ svn_client_upgrade(const char *dir,
  */
 
 /**
- * Recursively modify a working copy rooted at @a wcroot_dir, changing any
- * repository URLs that begin with @a from to begin with @a to instead.
+ * Recursively modify a working copy rooted at @a wcroot_dir, changing
+ * any repository URLs that begin with @a from_prefix to begin with @a
+ * to_prefix instead.
  *
  * @param wcroot_dir Working copy root directory
- * @param from Original URL
- * @param to New URL
+ * @param from_prefix Original URL
+ * @param to_prefix New URL
  * @param ignore_externals If not set, recurse into external working
  *        copies after relocating the primary working copy
  * @param ctx svn_client_ctx_t
@@ -3485,8 +3486,8 @@ svn_client_upgrade(const char *dir,
  */
 svn_error_t *
 svn_client_relocate2(const char *wcroot_dir,
-                     const char *from,
-                     const char *to,
+                     const char *from_prefix,
+                     const char *to_prefix,
                      svn_boolean_t ignore_externals,
                      svn_client_ctx_t *ctx,
                      apr_pool_t *pool);
@@ -3504,8 +3505,8 @@ svn_client_relocate2(const char *wcroot_
 SVN_DEPRECATED
 svn_error_t *
 svn_client_relocate(const char *dir,
-                    const char *from,
-                    const char *to,
+                    const char *from_prefix,
+                    const char *to_prefix,
                     svn_boolean_t recurse,
                     svn_client_ctx_t *ctx,
                     apr_pool_t *pool);
@@ -4458,13 +4459,14 @@ svn_client_revprop_list(apr_hash_t **pro
  * @a *result_rev to the value of the revision actually exported (set
  * it to #SVN_INVALID_REVNUM for local exports).
  *
- * @a from is either the path the working copy on disk, or a URL to the
- * repository you wish to export.
+ * @a from_path_or_url is either the path the working copy on disk, or
+ * a URL to the repository you wish to export.
  *
- * When exporting a directory @a to is the path to the directory where
- * you wish to create the exported tree, when exporting a file it is
- * the path of the file that will be created.  If @a to is the empty
- * path the name of the file/directory in the repository will be used.
+ * When exporting a directory @a to_path is the path to the directory
+ * where you wish to create the exported tree, when exporting a file
+ * it is the path of the file that will be created.  If @a to_path is
+ * the empty path the name of the file/directory in the repository
+ * will be used.
  *
  * @a peg_revision is the revision where the path is first looked up
  * when exporting from a repository.  If @a peg_revision->kind is
@@ -4482,7 +4484,8 @@ svn_client_revprop_list(apr_hash_t **pro
  *
  * @a ctx is a context used for authentication in the repository case.
  *
- * @a overwrite if TRUE will cause the export to overwrite files or directories.
+ * @a overwrite if TRUE will cause the export to overwrite files or
+ * directories.
  *
  * If @a ignore_externals is set, don't process externals definitions
  * as part of this operation.
@@ -4490,17 +4493,18 @@ svn_client_revprop_list(apr_hash_t **pro
  * If @a ignore_keywords is set, don't expand keywords as part of this
  * operation.
  *
- * @a native_eol allows you to override the standard eol marker on the platform
- * you are running on.  Can be either "LF", "CR" or "CRLF" or NULL.  If NULL
- * will use the standard eol marker.  Any other value will cause the
- * #SVN_ERR_IO_UNKNOWN_EOL error to be returned.
- *
- * If @a depth is #svn_depth_infinity, export fully recursively.
- * Else if it is #svn_depth_immediates, export @a from and its immediate
- * children (if any), but with subdirectories empty and at
- * #svn_depth_empty.  Else if #svn_depth_files, export @a from and
- * its immediate file children (if any) only.  If @a depth is
- * #svn_depth_empty, then export exactly @a from and none of its children.
+ * @a native_eol allows you to override the standard eol marker on the
+ * platform you are running on.  Can be either "LF", "CR" or "CRLF" or
+ * NULL.  If NULL will use the standard eol marker.  Any other value
+ * will cause the #SVN_ERR_IO_UNKNOWN_EOL error to be returned.
+ *
+ * If @a depth is #svn_depth_infinity, export fully recursively.  Else
+ * if it is #svn_depth_immediates, export @a from_path_or_url and its
+ * immediate children (if any), but with subdirectories empty and at
+ * #svn_depth_empty.  Else if #svn_depth_files, export @a
+ * from_path_or_url and its immediate file children (if any) only.  If
+ * @a depth is #svn_depth_empty, then export exactly @a
+ * from_path_or_url and none of its children.
  *
  * All allocations are done in @a pool.
  *
@@ -4508,8 +4512,8 @@ svn_client_revprop_list(apr_hash_t **pro
  */
 svn_error_t *
 svn_client_export5(svn_revnum_t *result_rev,
-                   const char *from,
-                   const char *to,
+                   const char *from_path_or_url,
+                   const char *to_path,
                    const svn_opt_revision_t *peg_revision,
                    const svn_opt_revision_t *revision,
                    svn_boolean_t overwrite,
@@ -4530,8 +4534,8 @@ svn_client_export5(svn_revnum_t *result_
  */
 svn_error_t *
 svn_client_export4(svn_revnum_t *result_rev,
-                   const char *from,
-                   const char *to,
+                   const char *from_path_or_url,
+                   const char *to_path,
                    const svn_opt_revision_t *peg_revision,
                    const svn_opt_revision_t *revision,
                    svn_boolean_t overwrite,
@@ -4555,8 +4559,8 @@ svn_client_export4(svn_revnum_t *result_
 SVN_DEPRECATED
 svn_error_t *
 svn_client_export3(svn_revnum_t *result_rev,
-                   const char *from,
-                   const char *to,
+                   const char *from_path_or_url,
+                   const char *to_path,
                    const svn_opt_revision_t *peg_revision,
                    const svn_opt_revision_t *revision,
                    svn_boolean_t overwrite,
@@ -4579,8 +4583,8 @@ svn_client_export3(svn_revnum_t *result_
 SVN_DEPRECATED
 svn_error_t *
 svn_client_export2(svn_revnum_t *result_rev,
-                   const char *from,
-                   const char *to,
+                   const char *from_path_or_url,
+                   const char *to_path,
                    svn_opt_revision_t *revision,
                    svn_boolean_t force,
                    const char *native_eol,
@@ -4597,8 +4601,8 @@ svn_client_export2(svn_revnum_t *result_
 SVN_DEPRECATED
 svn_error_t *
 svn_client_export(svn_revnum_t *result_rev,
-                  const char *from,
-                  const char *to,
+                  const char *from_path_or_url,
+                  const char *to_path,
                   svn_opt_revision_t *revision,
                   svn_boolean_t force,
                   svn_client_ctx_t *ctx,
@@ -5125,6 +5129,12 @@ typedef struct svn_info_t
    */
   svn_wc_conflict_description_t *tree_conflict;
 
+  /**
+   * The local absolute path of the working copy root.
+   * @since New in 1.7.
+   */
+  const char *wcroot_abspath;
+
   /** @} */
 
 } svn_info_t;

Modified: subversion/branches/issue-3668-3669/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/include/svn_wc.h?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/include/svn_wc.h (original)
+++ subversion/branches/issue-3668-3669/subversion/include/svn_wc.h Fri Nov  5 13:23:00 2010
@@ -4230,23 +4230,6 @@ svn_wc_add_from_disk(svn_wc_context_t *w
                      apr_pool_t *scratch_pool);
 
 /**
- * Convert the nested pristine working copy rooted at @a local_abspath into
- * a copied subtree in the outer working copy.
- *
- * @a local_abspath must be the root of a nested working copy that has no
- * local modifications.  The parent directory of @a local_abspath must be a
- * versioned directory in the outer WC, and must belong to the same
- * repository as the nested WC.  The nested WC will be integrated into the
- * parent's WC, and will no longer be a separate WC.
- *
- * This is a replacement for svn_wc_add4() case 1.
- */
-svn_error_t *
-svn_wc__integrate_nested_wc_as_copy(svn_wc_context_t *wc_ctx,
-                                    const char *local_abspath,
-                                    apr_pool_t *scratch_pool);
-
-/**
  * Put @a local_abspath under version control by registering it as addition
  * or copy in the database containing its parent. The new node is scheduled
  * for addition to the repository below its parent node.
@@ -4283,7 +4266,7 @@ svn_wc__integrate_nested_wc_as_copy(svn_
  * When the @a local_abspath has been added, then @a notify_func will be
  * called (if it is not @c NULL) with the @a notify_baton and the path.
  *
- * @note For case 1, prefer svn_wc__integrate_nested_wc_as_copy().
+ * @note Case 1 is deprecated. Consider doing a WC-to-WC copy instead.
  * @note For case 2a, prefer svn_wc_add_from_disk().
  *
  * @since New in 1.7.
@@ -4475,9 +4458,9 @@ svn_wc_add_repos_file(const char *dst_pa
  * hold a write lock.
  *
  * If @a local_abspath is a file, all its info will be removed from the
- * administrative area.  If @a name is a directory, then the administrative
- * area will be deleted, along with *all* the administrative areas anywhere
- * in the tree below @a adm_access.
+ * administrative area.  If @a local_abspath is a directory, then the
+ * administrative area will be deleted, along with *all* the administrative
+ * areas anywhere in the tree below @a adm_access.
  *
  * Normally, only administrative data is removed.  However, if
  * @a destroy_wf is TRUE, then all working file(s) and dirs are deleted
@@ -5102,7 +5085,7 @@ svn_wc_crawl_revisions(const char *path,
                        apr_pool_t *pool);
 
 
-/* Updates. */
+/* Working copy roots. */
 
 /** Set @a *wc_root to @c TRUE if @a local_abspath represents a "working copy
  * root", @c FALSE otherwise. Here, @a local_abspath is a "working copy root"
@@ -5138,6 +5121,21 @@ svn_wc_is_wc_root(svn_boolean_t *wc_root
                   svn_wc_adm_access_t *adm_access,
                   apr_pool_t *pool);
 
+/**
+ * Set @a *wcroot_abspath to the local abspath of the root of the
+ * working copy in which @a local_abspath resides.
+ *
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_wc_get_wc_root(const char **wcroot_abspath,
+                   svn_wc_context_t *wc_ctx,
+                   const char *local_abspath,
+                   apr_pool_t *scratch_pool,
+                   apr_pool_t *result_pool);
+
+
+/* Updates. */
 
 /** Conditionally split @a path into an @a anchor and @a target for the
  * purpose of updating and committing.

Modified: subversion/branches/issue-3668-3669/subversion/libsvn_client/blame.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_client/blame.c?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_client/blame.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_client/blame.c Fri Nov  5 13:23:00 2010
@@ -490,8 +490,10 @@ file_rev_handler(void *baton, const char
 
   if (revnum < frb->start_rev)
     {
-      /* We shouldn't get more than one revision before start. */
-      SVN_ERR_ASSERT(frb->last_filename == NULL);
+      /* We shouldn't get more than one revision before the starting
+         revision (unless of including merged revisions). */
+      SVN_ERR_ASSERT((frb->last_filename == NULL)
+                     || frb->include_merged_revisions);
 
       /* The file existed before start_rev; generate no blame info for
          lines from this revision (or before). */

Modified: subversion/branches/issue-3668-3669/subversion/libsvn_client/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_client/copy.c?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_client/copy.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_client/copy.c Fri Nov  5 13:23:00 2010
@@ -1409,6 +1409,35 @@ wc_to_repos_copy(const apr_array_header_
   return SVN_NO_ERROR;
 }
 
+/* A baton for notification_adjust_func(). */
+struct notification_adjust_baton
+{
+  svn_wc_notify_func2_t inner_func;
+  void *inner_baton;
+  const char *checkout_abspath;
+  const char *final_abspath;
+};
+
+/* A svn_wc_notify_func2_t function that wraps BATON->inner_func (whose
+ * baton is BATON->inner_baton) and adjusts the notification paths that
+ * start with BATON->checkout_abspath to start instead with
+ * BATON->final_abspath. */
+static void
+notification_adjust_func(void *baton,
+                         const svn_wc_notify_t *notify,
+                         apr_pool_t *pool)
+{
+  struct notification_adjust_baton *nb = baton;
+  svn_wc_notify_t *inner_notify = svn_wc_dup_notify(notify, pool);
+  const char *relpath;
+
+  relpath = svn_dirent_skip_ancestor(nb->checkout_abspath, notify->path);
+  inner_notify->path = svn_dirent_join(nb->final_abspath, relpath, pool);
+
+  if (nb->inner_func)
+    nb->inner_func(nb->inner_baton, inner_notify, pool);
+}
+
 /* Peform each individual copy operation for a repos -> wc copy.  A
    helper for repos_to_wc_copy().
 
@@ -1429,27 +1458,77 @@ repos_to_wc_copy_single(svn_client__copy
   if (pair->src_kind == svn_node_dir)
     {
       svn_boolean_t sleep_needed = FALSE;
+      const char *tmp_abspath;
+
+      /* Find a temporary location in which to check out the copy source.
+       * (This function is deprecated, but we intend to replace this whole
+       * code path with something else.) */
+      SVN_ERR(svn_wc_create_tmp_file2(NULL, &tmp_abspath, dst_abspath,
+                                      svn_io_file_del_on_close, pool));
 
       /* Make a new checkout of the requested source. While doing so,
        * resolve pair->src_revnum to an actual revision number in case it
        * was until now 'invalid' meaning 'head'.  Ask this function not to
        * sleep for timestamps, by passing a sleep_needed output param.
-       * This sends notifications for all nodes except the root node. */
-      SVN_ERR(svn_client__checkout_internal(&pair->src_revnum,
-                                            pair->src_original,
-                                            dst_abspath,
-                                            &pair->src_peg_revision,
-                                            &pair->src_op_revision, NULL,
-                                            svn_depth_infinity,
-                                            ignore_externals, FALSE, TRUE,
-                                            &sleep_needed, ctx, pool));
+       * Send notifications for all nodes except the root node, and adjust
+       * them to refer to the destination rather than this temporary path. */
+      {
+        svn_wc_notify_func2_t old_notify_func2 = ctx->notify_func2;
+        void *old_notify_baton2 = ctx->notify_baton2;
+        struct notification_adjust_baton nb;
+
+        nb.inner_func = ctx->notify_func2;
+        nb.inner_baton = ctx->notify_baton2;
+        nb.checkout_abspath = tmp_abspath;
+        nb.final_abspath = dst_abspath;
+        ctx->notify_func2 = notification_adjust_func;
+        ctx->notify_baton2 = &nb;
+
+        SVN_ERR(svn_client__checkout_internal(&pair->src_revnum,
+                                              pair->src_original,
+                                              tmp_abspath,
+                                              &pair->src_peg_revision,
+                                              &pair->src_op_revision, NULL,
+                                              svn_depth_infinity,
+                                              ignore_externals, FALSE, TRUE,
+                                              &sleep_needed, ctx, pool));
+
+        ctx->notify_func2 = old_notify_func2;
+        ctx->notify_baton2 = old_notify_baton2;
+      }
 
-      if (! same_repositories)
+      /* Schedule dst_path for addition in parent, with copy history.
+         Don't send any notification here.
+         Then remove the temporary checkout's .svn dir in preparation for
+         moving the rest of it into the final destination. */
+      if (same_repositories)
+        {
+          SVN_ERR(svn_wc_copy3(ctx->wc_ctx, tmp_abspath, dst_abspath,
+                               TRUE /* metadata_only */,
+                               ctx->cancel_func, ctx->cancel_baton,
+                               NULL, NULL, pool));
+          SVN_ERR(svn_wc__acquire_write_lock(NULL, ctx->wc_ctx, tmp_abspath,
+                                             FALSE, pool, pool));
+          SVN_ERR(svn_wc_remove_from_revision_control2(ctx->wc_ctx,
+                                                       tmp_abspath,
+                                                       FALSE, FALSE,
+                                                       ctx->cancel_func,
+                                                       ctx->cancel_baton,
+                                                       pool));
+        }
+      else
         {
           /* ### We want to schedule this as a simple add, or even better
              a copy from a foreign repos, but we don't yet have the
-             WC APIs to do that. */
+             WC APIs to do that, so we will just move the whole WC into
+             place as a disjoint, nested WC. */
+        }
 
+      /* Move the temporary disk tree into place. */
+      SVN_ERR(svn_io_file_rename(tmp_abspath, dst_abspath, pool));
+
+      if (! same_repositories)
+        {
           svn_io_sleep_for_timestamps(dst_abspath, pool);
 
           return svn_error_createf
@@ -1457,14 +1536,6 @@ repos_to_wc_copy_single(svn_client__copy
              _("Source URL '%s' is from foreign repository; "
                "leaving it as a disjoint WC"), pair->src_abspath_or_url);
         }
-
-      /* Schedule dst_path for addition in parent, with copy history.
-         Don't send any notification here.
-
-         ### This is a wierd way to do it. See the doc string of
-             svn_wc_add_repos_file4() for more about the controversy. */
-      SVN_ERR(svn_wc__integrate_nested_wc_as_copy(ctx->wc_ctx, dst_abspath,
-                                                  pool));
     } /* end directory case */
 
   else if (pair->src_kind == svn_node_file)

Modified: subversion/branches/issue-3668-3669/subversion/libsvn_client/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_client/deprecated.c?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_client/deprecated.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_client/deprecated.c Fri Nov  5 13:23:00 2010
@@ -1011,8 +1011,8 @@ svn_client_diff_summarize_peg(const char
 /*** From export.c ***/
 svn_error_t *
 svn_client_export4(svn_revnum_t *result_rev,
-                   const char *from,
-                   const char *to,
+                   const char *from_path_or_url,
+                   const char *to_path,
                    const svn_opt_revision_t *peg_revision,
                    const svn_opt_revision_t *revision,
                    svn_boolean_t overwrite,
@@ -1022,15 +1022,15 @@ svn_client_export4(svn_revnum_t *result_
                    svn_client_ctx_t *ctx,
                    apr_pool_t *pool)
 {
-  return svn_client_export5(result_rev, from, to, peg_revision, revision,
-                            overwrite, ignore_externals, FALSE, depth,
-                            native_eol, ctx, pool);
+  return svn_client_export5(result_rev, from_path_or_url, to_path,
+                            peg_revision, revision, overwrite, ignore_externals,
+                            FALSE, depth, native_eol, ctx, pool);
 }
 
 svn_error_t *
 svn_client_export3(svn_revnum_t *result_rev,
-                   const char *from,
-                   const char *to,
+                   const char *from_path_or_url,
+                   const char *to_path,
                    const svn_opt_revision_t *peg_revision,
                    const svn_opt_revision_t *revision,
                    svn_boolean_t overwrite,
@@ -1040,16 +1040,16 @@ svn_client_export3(svn_revnum_t *result_
                    svn_client_ctx_t *ctx,
                    apr_pool_t *pool)
 {
-  return svn_client_export4(result_rev, from, to, peg_revision, revision,
-                            overwrite, ignore_externals,
+  return svn_client_export4(result_rev, from_path_or_url, to_path,
+                            peg_revision, revision, overwrite, ignore_externals,
                             SVN_DEPTH_INFINITY_OR_FILES(recurse),
                             native_eol, ctx, pool);
 }
 
 svn_error_t *
 svn_client_export2(svn_revnum_t *result_rev,
-                   const char *from,
-                   const char *to,
+                   const char *from_path_or_url,
+                   const char *to_path,
                    svn_opt_revision_t *revision,
                    svn_boolean_t force,
                    const char *native_eol,
@@ -1060,23 +1060,23 @@ svn_client_export2(svn_revnum_t *result_
 
   peg_revision.kind = svn_opt_revision_unspecified;
 
-  return svn_client_export3(result_rev, from, to, &peg_revision,
-                            revision, force, FALSE, TRUE,
+  return svn_client_export3(result_rev, from_path_or_url, to_path,
+                            &peg_revision, revision, force, FALSE, TRUE,
                             native_eol, ctx, pool);
 }
 
 
 svn_error_t *
 svn_client_export(svn_revnum_t *result_rev,
-                  const char *from,
-                  const char *to,
+                  const char *from_path_or_url,
+                  const char *to_path,
                   svn_opt_revision_t *revision,
                   svn_boolean_t force,
                   svn_client_ctx_t *ctx,
                   apr_pool_t *pool)
 {
-  return svn_client_export2(result_rev, from, to, revision, force, NULL, ctx,
-                            pool);
+  return svn_client_export2(result_rev, from_path_or_url, to_path, revision,
+                            force, NULL, ctx, pool);
 }
 
 /*** From list.c ***/
@@ -2083,8 +2083,8 @@ svn_client_mergeinfo_log_eligible(const 
 /*** From relocate.c ***/
 svn_error_t *
 svn_client_relocate(const char *path,
-                    const char *from,
-                    const char *to,
+                    const char *from_prefix,
+                    const char *to_prefix,
                     svn_boolean_t recurse,
                     svn_client_ctx_t *ctx,
                     apr_pool_t *pool)
@@ -2092,5 +2092,5 @@ svn_client_relocate(const char *path,
   if (! recurse)
     svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, 0,
                      _("Non-recursive relocation not supported"));
-  return svn_client_relocate2(path, from, to, TRUE, ctx, pool);
+  return svn_client_relocate2(path, from_prefix, to_prefix, TRUE, ctx, pool);
 }

Modified: subversion/branches/issue-3668-3669/subversion/libsvn_client/export.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_client/export.c?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_client/export.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_client/export.c Fri Nov  5 13:23:00 2010
@@ -929,8 +929,8 @@ close_file(void *file_baton,
 
 svn_error_t *
 svn_client_export5(svn_revnum_t *result_rev,
-                   const char *from,
-                   const char *to,
+                   const char *from_path_or_url,
+                   const char *to_path,
                    const svn_opt_revision_t *peg_revision,
                    const svn_opt_revision_t *revision,
                    svn_boolean_t overwrite,
@@ -947,15 +947,16 @@ svn_client_export5(svn_revnum_t *result_
   SVN_ERR_ASSERT(peg_revision != NULL);
   SVN_ERR_ASSERT(revision != NULL);
 
-  if (svn_path_is_url(to))
+  if (svn_path_is_url(to_path))
     return svn_error_return(svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
                                               _("'%s' is not a local path"),
-                                              to));
+                                              to_path));
     
-  peg_revision = svn_cl__rev_default_to_head_or_working(peg_revision, from);
+  peg_revision = svn_cl__rev_default_to_head_or_working(peg_revision,
+                                                        from_path_or_url);
   revision = svn_cl__rev_default_to_peg(revision, peg_revision);
 
-  if (svn_path_is_url(from) ||
+  if (svn_path_is_url(from_path_or_url) ||
       ! SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(revision->kind))
     {
       svn_revnum_t revnum;
@@ -966,14 +967,14 @@ svn_client_export5(svn_revnum_t *result_
 
       /* Get the RA connection. */
       SVN_ERR(svn_client__ra_session_from_path(&ra_session, &revnum,
-                                               &url, from, NULL,
+                                               &url, from_path_or_url, NULL,
                                                peg_revision,
                                                revision, ctx, pool));
 
       /* Get the repository root. */
       SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root_url, pool));
 
-      eb->root_path = to;
+      eb->root_path = to_path;
       eb->root_url = url;
       eb->force = overwrite;
       eb->target_revision = &edit_revision;
@@ -993,10 +994,11 @@ svn_client_export5(svn_revnum_t *result_
           apr_hash_index_t *hi;
           struct file_baton *fb = apr_pcalloc(pool, sizeof(*fb));
 
-          if (svn_path_is_empty(to))
+          if (svn_path_is_empty(to_path))
             {
-              to = svn_path_uri_decode(svn_uri_basename(from, NULL), pool);
-              eb->root_path = to;
+              to_path = svn_path_uri_decode(svn_uri_basename(from_path_or_url,
+                                                             NULL), pool);
+              eb->root_path = to_path;
             }
           
           /* Since you cannot actually root an editor at a file, we
@@ -1090,19 +1092,19 @@ svn_client_export5(svn_revnum_t *result_
            * So we just create the empty dir manually; but we do it via
            * open_root_internal(), in order to get proper notification.
            */
-          SVN_ERR(svn_io_check_path(to, &kind, pool));
+          SVN_ERR(svn_io_check_path(to_path, &kind, pool));
           if (kind == svn_node_none)
             SVN_ERR(open_root_internal
-                    (to, overwrite, ctx->notify_func2,
+                    (to_path, overwrite, ctx->notify_func2,
                      ctx->notify_baton2, pool));
 
           if (! ignore_externals && depth == svn_depth_infinity)
             {
               const char *to_abspath;
 
-              SVN_ERR(svn_dirent_get_absolute(&to_abspath, to, pool));
+              SVN_ERR(svn_dirent_get_absolute(&to_abspath, to_path, pool));
               SVN_ERR(svn_client__fetch_externals(eb->externals,
-                                                  from, to_abspath,
+                                                  from_path_or_url, to_abspath,
                                                   repos_root_url, depth, TRUE,
                                                   native_eol, &use_sleep,
                                                   ctx, pool));
@@ -1111,7 +1113,8 @@ svn_client_export5(svn_revnum_t *result_
       else if (kind == svn_node_none)
         {
           return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
-                                   _("URL '%s' doesn't exist"), from);
+                                   _("URL '%s' doesn't exist"),
+                                   from_path_or_url);
         }
       /* kind == svn_node_unknown not handled */
     }
@@ -1119,8 +1122,8 @@ svn_client_export5(svn_revnum_t *result_
     {
       /* This is a working copy export. */
       /* just copy the contents of the working copy into the target path. */
-      SVN_ERR(copy_versioned_files(from, to, revision, overwrite,
-                                   ignore_externals, ignore_keywords,
+      SVN_ERR(copy_versioned_files(from_path_or_url, to_path, revision,
+                                   overwrite, ignore_externals, ignore_keywords,
                                    depth, native_eol, ctx, pool));
     }
 
@@ -1128,7 +1131,7 @@ svn_client_export5(svn_revnum_t *result_
   if (ctx->notify_func2)
     {
       svn_wc_notify_t *notify
-        = svn_wc_create_notify(to,
+        = svn_wc_create_notify(to_path,
                                svn_wc_notify_update_completed, pool);
       notify->revision = edit_revision;
       (*ctx->notify_func2)(ctx->notify_baton2, notify, pool);

Modified: subversion/branches/issue-3668-3669/subversion/libsvn_client/info.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_client/info.c?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_client/info.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_client/info.c Fri Nov  5 13:23:00 2010
@@ -167,6 +167,9 @@ build_info_for_entry(svn_info_t **info,
   SVN_ERR(svn_wc__node_get_schedule(&tmpinfo->schedule, NULL,
                                     wc_ctx, local_abspath, pool));
 
+  SVN_ERR(svn_wc_get_wc_root(&tmpinfo->wcroot_abspath, wc_ctx,
+                             local_abspath, pool, pool));
+
   /* Some random stuffs we don't have wc-ng apis for yet */
   SVN_ERR(svn_wc__node_get_info_bits(&tmpinfo->text_time,
                                      &tmpinfo->conflict_old,
@@ -692,6 +695,8 @@ svn_info_dup(const svn_info_t *info, apr
     dupinfo->conflict_wrk = apr_pstrdup(pool, info->conflict_wrk);
   if (info->prejfile)
     dupinfo->prejfile = apr_pstrdup(pool, info->prejfile);
+  if (info->wcroot_abspath)
+    dupinfo->wcroot_abspath = apr_pstrdup(pool, info->wcroot_abspath);
 
   return dupinfo;
 }

Modified: subversion/branches/issue-3668-3669/subversion/libsvn_client/relocate.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_client/relocate.c?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_client/relocate.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_client/relocate.c Fri Nov  5 13:23:00 2010
@@ -229,8 +229,8 @@ relocate_externals(const char *local_abs
 
 svn_error_t *
 svn_client_relocate2(const char *wcroot_dir,
-                     const char *from,
-                     const char *to,
+                     const char *from_prefix,
+                     const char *to_prefix,
                      svn_boolean_t ignore_externals,
                      svn_client_ctx_t *ctx,
                      apr_pool_t *pool)
@@ -254,8 +254,8 @@ svn_client_relocate2(const char *wcroot_
   if (ignore_externals)
     {
       return svn_error_return(svn_wc_relocate4(ctx->wc_ctx, local_abspath,
-                                               from, to, validator_func, &vb,
-                                               pool));
+                                               from_prefix, to_prefix,
+                                               validator_func, &vb, pool));
     }
 
   /* Fetch our current root URL. */
@@ -263,7 +263,7 @@ svn_client_relocate2(const char *wcroot_
                                         ctx, pool));
 
   /* Perform the relocation. */
-  SVN_ERR(svn_wc_relocate4(ctx->wc_ctx, local_abspath, from, to,
+  SVN_ERR(svn_wc_relocate4(ctx->wc_ctx, local_abspath, from_prefix, to_prefix,
                            validator_func, &vb, pool));
 
   /* Now fetch new current root URL. */

Modified: subversion/branches/issue-3668-3669/subversion/libsvn_client/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_client/status.c?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_client/status.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_client/status.c Fri Nov  5 13:23:00 2010
@@ -32,6 +32,7 @@
 #include "svn_pools.h"
 #include "client.h"
 
+#include "svn_path.h"
 #include "svn_dirent_uri.h"
 #include "svn_delta.h"
 #include "svn_client.h"
@@ -268,6 +269,11 @@ svn_client_status5(svn_revnum_t *result_
   apr_hash_t *changelist_hash = NULL;
   struct svn_cl__externals_store externals_store = { NULL };
 
+  if (svn_path_is_url(path))
+    return svn_error_return(svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+                                              _("'%s' is not a local path"),
+                                              path));
+
   if (changelists && changelists->nelts)
     SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelists, pool));
 

Modified: subversion/branches/issue-3668-3669/subversion/libsvn_diff/parse-diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_diff/parse-diff.c?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_diff/parse-diff.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_diff/parse-diff.c Fri Nov  5 13:23:00 2010
@@ -190,6 +190,7 @@ parse_hunk_header(const char *header, sv
                   const char *atat, apr_pool_t *pool)
 {
   const char *p;
+  const char *start;
   svn_stringbuf_t *range;
 
   p = header + strlen(atat);
@@ -202,16 +203,18 @@ parse_hunk_header(const char *header, sv
     return FALSE;
   /* OK, this may be worth allocating some memory for... */
   range = svn_stringbuf_create_ensure(31, pool);
-  p++;
+  start = ++p;
   while (*p && *p != ' ')
     {
-      svn_stringbuf_appendbyte(range, *p);
       p++;
     }
+
   if (*p != ' ')
     /* No no no... */
     return FALSE;
 
+  svn_stringbuf_appendbytes(range, start, p - start);
+
   /* Try to parse the first range. */
   if (! parse_range(&hunk->original_start, &hunk->original_length, range->data))
     return FALSE;
@@ -223,16 +226,17 @@ parse_hunk_header(const char *header, sv
     /* Eeek! */
     return FALSE;
   /* OK, this may be worth copying... */
-  p++;
+  start = ++p;
   while (*p && *p != ' ')
     {
-      svn_stringbuf_appendbyte(range, *p);
       p++;
     }
   if (*p != ' ')
     /* No no no... */
     return FALSE;
 
+  svn_stringbuf_appendbytes(range, start, p - start);
+
   /* Check for trailing @@ */
   p++;
   if (! starts_with(p, atat))

Modified: subversion/branches/issue-3668-3669/subversion/libsvn_subr/subst.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_subr/subst.c?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_subr/subst.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_subr/subst.c Fri Nov  5 13:23:00 2010
@@ -798,6 +798,10 @@ struct translation_baton
   /* Length of the EOL style string found in the chunk-source,
      or zero if none encountered yet */
   apr_size_t src_format_len;
+
+  /* If this is svn_tristate_false, translate_newline() will be called
+     for every newline in the file */
+  svn_tristate_t nl_translation_skippable;
 };
 
 
@@ -828,6 +832,7 @@ create_translation_baton(const char *eol
   b->newline_off = 0;
   b->keyword_off = 0;
   b->src_format_len = 0;
+  b->nl_translation_skippable = svn_tristate_unknown;
 
   /* Most characters don't start translation actions.
    * Mark those that do depending on the parameters we got. */
@@ -843,6 +848,38 @@ create_translation_baton(const char *eol
   return b;
 }
 
+/* Return TRUE if the EOL starting at BUF matches the eol_str member of B.
+ * Be aware of special cases like "\n\r\n" and "\n\n\r". For sequences like
+ * "\n$" (an EOL followed by a keyword), the result will be FALSE since it is
+ * more efficient to handle that special case implicitly in the calling code
+ * by exiting the quick scan loop.
+ * The caller must ensure that buf[0] and buf[1] refer to valid memory
+ * locations.
+ */
+static APR_INLINE svn_boolean_t
+eol_unchanged(struct translation_baton *b,
+              const char *buf)
+{
+  /* If the first byte doesn't match, the whole EOL won't.
+   * This does also handle the (certainly invalid) case that 
+   * eol_str would be an empty string.
+   */
+  if (buf[0] != b->eol_str[0])
+    return FALSE;
+
+  /* two-char EOLs must be a full match */
+  if (b->eol_str_len == 2)
+    return buf[1] == b->eol_str[1];
+
+  /* The first char matches the required 1-byte EOL. 
+   * But maybe, buf[] contains a 2-byte EOL?
+   * In that case, the second byte will be interesting
+   * and not be another EOL of its own.
+   */
+  return !b->interesting[(unsigned char)buf[1]] || buf[0] == buf[1];
+}
+
+
 /* Translate eols and keywords of a 'chunk' of characters BUF of size BUFLEN
  * according to the settings and state stored in baton B.
  *
@@ -948,19 +985,72 @@ translate_chunk(svn_stream_t *dst,
               continue;
             }
 
-          /* We're in the boring state; look for interest characters. */
-          len = 0;
+          /* translate_newline will modify the baton for src_format_len==0
+             or may return an error if b->repair is FALSE.  In all other
+             cases, we can skip the newline translation as long as source
+             EOL format and actual EOL format match.  If there is a 
+             mismatch, translate_newline will be called regardless of 
+             nl_translation_skippable. 
+           */
+          if (b->nl_translation_skippable == svn_tristate_unknown &&
+              b->src_format_len > 0)
+            {
+              /* test whether translate_newline may return an error */
+              if (b->eol_str_len == b->src_format_len &&
+                  strncmp(b->eol_str, b->src_format, b->eol_str_len) == 0)
+                b->nl_translation_skippable = svn_tristate_true;
+              else if (b->repair) 
+                b->nl_translation_skippable = svn_tristate_true;
+              else
+                b->nl_translation_skippable = svn_tristate_false;
+            }
+
+          /* We're in the boring state; look for interesting characters.
+             Offset len such that it will become 0 in the first iteration. 
+           */
+          len = 0 - b->eol_str_len;
+
+          /* Look for the next EOL (or $) that actually needs translation.
+             Stop there or at EOF, whichever is encountered first.
+           */
+          do
+            {
+              /* skip current EOL */
+              len += b->eol_str_len;
+
+              /* Check 4 bytes at once to allow for efficient pipelining
+                 and to reduce loop condition overhead. */
+              while ((p + len + 4) <= end)
+                {
+                  char sum = interesting[(unsigned char)p[len]]
+                           | interesting[(unsigned char)p[len+1]]
+                           | interesting[(unsigned char)p[len+2]]
+                           | interesting[(unsigned char)p[len+3]];
+
+                  if (sum != 0)
+                    break;
+
+                  len += 4;
+                }
+
+               /* Found an interesting char or EOF in the next 4 bytes. 
+                  Find its exact position. */
+               while ((p + len) < end && !interesting[(unsigned char)p[len]])
+                 ++len;
+            }
+          while (b->nl_translation_skippable ==
+                   svn_tristate_true &&       /* can potentially skip EOLs */
+                 p + len + 2 < end &&         /* not too close to EOF */
+                 eol_unchanged (b, p + len)); /* EOL format already ok */
 
-          /* We wanted memcspn(), but lacking that, the loop below has
-             the same effect. Also, skip NUL characters.
-          */
           while ((p + len) < end && !interesting[(unsigned char)p[len]])
             len++;
 
           if (len)
-            SVN_ERR(translate_write(dst, p, len));
-
-          p += len;
+            {
+              SVN_ERR(translate_write(dst, p, len));
+              p += len;
+            }
 
           /* Set up state according to the interesting character, if any. */
           if (p < end)

Modified: subversion/branches/issue-3668-3669/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_wc/adm_ops.c?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_wc/adm_ops.c Fri Nov  5 13:23:00 2010
@@ -1156,33 +1156,6 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
 }
 
 svn_error_t *
-svn_wc__integrate_nested_wc_as_copy(svn_wc_context_t *wc_ctx,
-                                    const char *local_abspath,
-                                    apr_pool_t *scratch_pool)
-{
-  svn_wc__db_t *db = wc_ctx->db;
-  svn_boolean_t is_wc_root;
-
-  /* Precondition: LOCAL_ABSPATH is the root of a separate WC. */
-  SVN_ERR(svn_wc__check_wc_root(&is_wc_root, NULL, NULL,
-                                db, local_abspath, scratch_pool));
-  if (! is_wc_root)
-    return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
-                             _("'%s' is not a WC root"),
-                             svn_dirent_local_style(local_abspath,
-                                                    scratch_pool));
-
-  /* Precondition: parent(LOCAL_ABSPATH) is a versioned directory in an
-   * acceptable state. */
-  SVN_ERR(check_can_add_to_parent(NULL, NULL, wc_ctx, local_abspath,
-                                  scratch_pool, scratch_pool));
-
-  SVN_ERR(integrate_nested_wc_as_copy(wc_ctx, local_abspath, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
 svn_wc_add_from_disk(svn_wc_context_t *wc_ctx,
                      const char *local_abspath,
                      svn_wc_notify_func2_t notify_func,

Modified: subversion/branches/issue-3668-3669/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_wc/update_editor.c?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_wc/update_editor.c Fri Nov  5 13:23:00 2010
@@ -2452,14 +2452,10 @@ add_directory(const char *path,
 
   SVN_ERR(svn_wc__ensure_directory(db->local_abspath, pool));
 
-  /* If PATH is within a locally deleted tree then make it also
-     scheduled for deletion.  We should do this at the same time as
-     setting the dir incomplete otherwise the db is temporarily
-     invalid. */
-  if (pb->in_deleted_and_tree_conflicted_subtree)
-    {
-      SVN_ERR(svn_wc__db_temp_op_delete(eb->db, db->local_abspath, pool));
-    }
+  if (!pb->in_deleted_and_tree_conflicted_subtree
+      && status == svn_wc__db_status_added)
+    /* If there is no conflict we take over any added directory */
+    SVN_ERR(svn_wc__db_temp_op_remove_working(eb->db, db->local_abspath, pool));
 
   /* If this add was obstructed by dir scheduled for addition without
      history let close_file() handle the notification because there
@@ -4527,14 +4523,6 @@ close_file(void *file_baton,
 
   /* Deal with the WORKING tree, based on updates to the BASE tree.  */
 
-  /* An ancestor was locally-deleted. This file is being added within
-     that tree. We need to schedule this file for deletion.  This
-     should happen at the same time as svn_wc__db_base_add_file.  */
-  if (fb->dir_baton->in_deleted_and_tree_conflicted_subtree && fb->adding_file)
-    {
-      SVN_ERR(svn_wc__db_temp_op_delete(eb->db, fb->local_abspath, 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 (fb->add_existed && fb->adding_file)
@@ -5468,6 +5456,18 @@ svn_wc__strictly_is_wc_root(svn_boolean_
 
 
 svn_error_t *
+svn_wc_get_wc_root(const char **wcroot_abspath,
+                   svn_wc_context_t *wc_ctx,
+                   const char *local_abspath,
+                   apr_pool_t *scratch_pool,
+                   apr_pool_t *result_pool)
+{
+  return svn_wc__db_get_wcroot(wcroot_abspath, wc_ctx->db,
+                               local_abspath, scratch_pool, result_pool);
+}
+
+
+svn_error_t *
 svn_wc_get_actual_target2(const char **anchor,
                           const char **target,
                           svn_wc_context_t *wc_ctx,

Modified: subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc-queries.sql?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc-queries.sql Fri Nov  5 13:23:00 2010
@@ -72,6 +72,13 @@ WHERE wc_id = ?1 AND local_relpath = ?2 
 ORDER BY op_depth DESC
 LIMIT 1;
 
+-- STMT_SELECT_LOWEST_WORKING_NODE
+SELECT op_depth, presence
+FROM nodes
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > 0
+ORDER BY op_depth
+LIMIT 1;
+
 -- STMT_SELECT_ACTUAL_NODE
 SELECT prop_reject, changelist, conflict_old, conflict_new,
 conflict_working, tree_conflict_data, properties, conflict_data
@@ -473,7 +480,7 @@ VALUES (?1, ?2, 0,
         ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16);
 
 -- STMT_INSERT_WORKING_NODE_FROM_BASE
-INSERT INTO nodes (
+INSERT OR REPLACE INTO nodes (
     wc_id, local_relpath, op_depth, parent_relpath, presence, kind, checksum,
     changed_revision, changed_date, changed_author, depth, symlink_target,
     translated_size, last_mod_time, properties)

Modified: subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc_db.c?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/issue-3668-3669/subversion/libsvn_wc/wc_db.c Fri Nov  5 13:23:00 2010
@@ -710,6 +710,84 @@ blank_ibb(insert_base_baton_t *pibb)
 }
 
 
+/* Extend any delete of the parent of LOCAL_RELPATH to LOCAL_RELPATH.
+
+   Given a wc:
+
+              0         1         2         3         4
+              normal
+   A          normal          
+   A/B        normal              normal
+   A/B/C                          not-pres  normal
+   A/B/C/D                                            normal
+
+   That is checkout, delete A/B, copy a replacement A/B, delete copied
+   child A/B/C, add replacement A/B/C, add A/B/C/D.
+
+   Now an update that adds base nodes for A/B/C, A/B/C/D and A/B/C/D/E
+   must extend the A/B deletion:
+   
+              0         1         2         3         4
+              normal
+   A          normal
+   A/B        normal              normal
+   A/B/C      normal              not-pres  normal
+   A/B/C/D    normal              base-del            normal
+   A/B/C/D/E  normal              base-del
+
+   When adding a base node if the parent has a working node then the
+   parent base is deleted and this must be extended to cover new base
+   node.
+
+   In the example above A/B/C/D and A/B/C/D/E are the nodes that get
+   the extended delete, A/B/C is already deleted.
+ */
+static svn_error_t *
+extend_parent_delete(svn_sqlite__db_t *sdb,
+                     apr_int64_t wc_id,
+                     const char *local_relpath,
+                     apr_pool_t *scratch_pool)
+{
+  svn_boolean_t have_row;
+  svn_sqlite__stmt_t *stmt;
+  apr_int64_t parent_op_depth;
+  const char *parent_relpath = svn_relpath_dirname(local_relpath, scratch_pool);
+
+  SVN_ERR_ASSERT(local_relpath[0]);
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                    STMT_SELECT_LOWEST_WORKING_NODE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, parent_relpath));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+  if (have_row)
+    parent_op_depth = svn_sqlite__column_int64(stmt, 0);
+  SVN_ERR(svn_sqlite__reset(stmt));
+  if (have_row)
+    {
+      apr_int64_t op_depth;
+
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+      if (have_row)
+        op_depth = svn_sqlite__column_int64(stmt, 0);
+      SVN_ERR(svn_sqlite__reset(stmt));
+      if (!have_row || parent_op_depth < op_depth)
+        {
+          SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                          STMT_INSERT_WORKING_NODE_FROM_BASE));
+          SVN_ERR(svn_sqlite__bindf(stmt, "isit", wc_id,
+                                    local_relpath, parent_op_depth,
+                                    presence_map,
+                                    svn_wc__db_status_base_deleted));
+          SVN_ERR(svn_sqlite__update(NULL, stmt));
+        }
+    }
+
+  return SVN_NO_ERROR;
+}
+
+
+
 /* */
 static svn_error_t *
 insert_base_node(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
@@ -773,6 +851,10 @@ insert_base_node(void *baton, svn_sqlite
                                        0 /* BASE */,
                                        scratch_pool));
 
+  if (parent_relpath)
+    SVN_ERR(extend_parent_delete(sdb, pibb->wc_id, pibb->local_relpath,
+                                 scratch_pool));
+
   SVN_ERR(add_work_items(sdb, pibb->work_items, scratch_pool));
 
   return SVN_NO_ERROR;
@@ -8005,24 +8087,46 @@ svn_wc__db_read_kind(svn_wc__db_kind_t *
                      svn_boolean_t allow_missing,
                      apr_pool_t *scratch_pool)
 {
-  svn_error_t *err;
+  svn_wc__db_pdh_t *pdh;
+  const char *local_relpath;
+  svn_sqlite__stmt_t *stmt_info;
+  svn_boolean_t have_info;
 
-  err = svn_wc__db_read_info(NULL, kind, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL,
-                             db, local_abspath, scratch_pool, scratch_pool);
-  if (!err)
-    return SVN_NO_ERROR;
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
+  SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&pdh, &local_relpath, db,
+                              local_abspath, svn_sqlite__mode_readonly,
+                              scratch_pool, scratch_pool));
+  VERIFY_USABLE_PDH(pdh);
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt_info, pdh->wcroot->sdb,
+                                    STMT_SELECT_NODE_INFO));
+  SVN_ERR(svn_sqlite__bindf(stmt_info, "is",
+                            pdh->wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step(&have_info, stmt_info));
 
-  if (allow_missing && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+  if (!have_info)
     {
-      svn_error_clear(err);
-      *kind = svn_wc__db_kind_unknown;
-      return SVN_NO_ERROR;
+      if (allow_missing)
+        {
+          *kind = svn_wc__db_kind_unknown;
+          SVN_ERR(svn_sqlite__reset(stmt_info));
+          return SVN_NO_ERROR;
+        }
+      else
+        {
+          SVN_ERR(svn_sqlite__reset(stmt_info));
+          return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                                   _("The node '%s' was not found."),
+                                   path_for_error_message(pdh->wcroot,
+                                                          local_relpath,
+                                                          scratch_pool));
+        }
     }
 
-  return svn_error_return(err);
+  *kind = svn_sqlite__column_token(stmt_info, 4, kind_map);
+
+  return svn_error_return(svn_sqlite__reset(stmt_info));
 }
 
 
@@ -9435,14 +9539,6 @@ set_new_dir_to_incomplete_txn(void *bato
   SVN_ERR(create_repos_id(&repos_id, dtb->repos_root_url, dtb->repos_uuid,
                           sdb, scratch_pool));
 
-  /* Delete the base and working node data */
-  SVN_ERR(svn_sqlite__get_statement(&stmt, dtb->pdh->wcroot->sdb,
-                                    STMT_DELETE_NODES));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", dtb->pdh->wcroot->wc_id,
-                            dtb->local_relpath));
-  SVN_ERR(svn_sqlite__step_done(stmt));
-
-  /* Insert the incomplete base node */
   SVN_ERR(svn_sqlite__get_statement(&stmt, dtb->pdh->wcroot->sdb,
                                     STMT_INSERT_NODE));
 
@@ -9464,6 +9560,10 @@ set_new_dir_to_incomplete_txn(void *bato
 
   SVN_ERR(svn_sqlite__step_done(stmt));
 
+  if (parent_relpath)
+    SVN_ERR(extend_parent_delete(dtb->pdh->wcroot->sdb, dtb->pdh->wcroot->wc_id,
+                                 dtb->local_relpath, scratch_pool));
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/issue-3668-3669/subversion/svn/info-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/svn/info-cmd.c?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/svn/info-cmd.c (original)
+++ subversion/branches/issue-3668-3669/subversion/svn/info-cmd.c Fri Nov  5 13:23:00 2010
@@ -126,6 +126,11 @@ print_info_xml(void *baton,
       /* "<wc-info>" */
       svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "wc-info", NULL);
 
+      /* "<wcroot-abspath> xx </wcroot-abspath>" */
+      if (info->wcroot_abspath)
+        svn_cl__xml_tagged_cdata(&sb, pool, "wcroot-abspath",
+                                 info->wcroot_abspath);
+
       /* "<schedule> xx </schedule>" */
       svn_cl__xml_tagged_cdata(&sb, pool, "schedule",
                                schedule_str(info->schedule));
@@ -256,6 +261,11 @@ print_info(void *baton,
     SVN_ERR(svn_cmdline_printf(pool, _("Name: %s\n"),
                                svn_dirent_basename(target, pool)));
 
+  if (info->wcroot_abspath)
+    SVN_ERR(svn_cmdline_printf(pool, _("Working Copy Root Path: %s\n"),
+                               svn_dirent_local_style(info->wcroot_abspath,
+                                                      pool)));
+
   if (info->URL)
     SVN_ERR(svn_cmdline_printf(pool, _("URL: %s\n"), info->URL));
 

Modified: subversion/branches/issue-3668-3669/subversion/svn/schema/info.rnc
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/svn/schema/info.rnc?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/svn/schema/info.rnc (original)
+++ subversion/branches/issue-3668-3669/subversion/svn/schema/info.rnc Fri Nov  5 13:23:00 2010
@@ -53,6 +53,7 @@ uuid = element uuid { uuid.type }
 ## Info in the working copy entry.
 wc-info =
   element wc-info {
+    wcroot-abspath?,
     schedule?,
     changelist?,
     copy-from-url?,
@@ -63,6 +64,8 @@ wc-info =
     checksum?
   }
 
+wcroot-abspath = element wcroot-abspath { string }
+
 schedule =
   element schedule { "normal" | "add" | "delete" | "replace" | "none" }
 

Modified: subversion/branches/issue-3668-3669/subversion/svn/status-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/svn/status-cmd.c?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/svn/status-cmd.c (original)
+++ subversion/branches/issue-3668-3669/subversion/svn/status-cmd.c Fri Nov  5 13:23:00 2010
@@ -249,6 +249,18 @@ svn_cl__status(apr_getopt_t *os,
   /* Add "." if user passed 0 arguments */
   svn_opt_push_implicit_dot_target(targets, scratch_pool);
 
+  /* URLs are invalid input. */
+  for (i = 0; i < targets->nelts; i++)
+    {
+      const char *target = APR_ARRAY_IDX(targets, i, const char *);
+
+      if (svn_path_is_url(target))
+        return svn_error_return(svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR,
+                                                  NULL,
+                                                  _("'%s' is not a local path"),
+                                                  target));
+    }
+
   /* We want our -u statuses to be against HEAD. */
   rev.kind = svn_opt_revision_head;
 

Modified: subversion/branches/issue-3668-3669/subversion/tests/cmdline/blame_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/tests/cmdline/blame_tests.py?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/tests/cmdline/blame_tests.py (original)
+++ subversion/branches/issue-3668-3669/subversion/tests/cmdline/blame_tests.py Fri Nov  5 13:23:00 2010
@@ -462,10 +462,10 @@ def blame_merge_info(sbox):
 
   wc_dir = sbox.wc_dir
   iota_path = os.path.join(wc_dir, 'trunk', 'iota')
+  mu_path = os.path.join(wc_dir, 'trunk', 'A', 'mu')
 
   exit_code, output, error = svntest.actions.run_and_verify_svn(
-    None, None, [],
-    'blame', '-g', iota_path)
+    None, None, [], 'blame', '-g', iota_path)
 
   expected_blame = [
       { 'revision' : 2,
@@ -481,6 +481,45 @@ def blame_merge_info(sbox):
     ]
   parse_and_verify_blame(output, expected_blame, 1)
 
+  exit_code, output, error = svntest.actions.run_and_verify_svn(
+    None, None, [], 'blame', '-g', '-r10:11', iota_path)
+
+  expected_blame = [
+      { 'revision' : None,
+        'author' : None,
+        'text' : "This is the file 'iota'.\n",
+        'merged' : 0,
+      },
+      { 'revision' : None,
+        'author' : None,
+        'text' : "'A' has changed a bit.\n",
+        'merged' : 0,
+      },
+    ]
+  parse_and_verify_blame(output, expected_blame, 1)
+
+  exit_code, output, error = svntest.actions.run_and_verify_svn(
+    None, None, [], 'blame', '-g', '-r16:17', mu_path)
+
+  expected_blame = [
+      { 'revision' : None,
+        'author' : None,
+        'text' : "This is the file 'mu'.\n",
+        'merged' : 0,
+      },
+      { 'revision' : 16,
+        'author' : 'jrandom',
+        'text' : "Don't forget to look at 'upsilon', as well.\n",
+        'merged' : 1,
+      },
+      { 'revision' : 16,
+        'author' : 'jrandom',
+        'text' : "This is yet more content in 'mu'.\n",
+        'merged' : 1,
+      },
+    ]
+  parse_and_verify_blame(output, expected_blame, 1)
+
 
 def blame_merge_out_of_range(sbox):
   "don't look for merged files out of range"

Modified: subversion/branches/issue-3668-3669/subversion/tests/cmdline/copy_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/tests/cmdline/copy_tests.py?rev=1031554&r1=1031553&r2=1031554&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/tests/cmdline/copy_tests.py (original)
+++ subversion/branches/issue-3668-3669/subversion/tests/cmdline/copy_tests.py Fri Nov  5 13:23:00 2010
@@ -4835,6 +4835,92 @@ def delete_replace_delete(sbox):
   # Currently fails because pi, rho, tau get left behind
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
+A_B_children = ['A/B/lambda', 'A/B/F', 'A/B/E/alpha', 'A/B/E/beta', 'A/B/E']
+A_D_children = ['A/D/gamma', 'A/D/G', 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau',
+                'A/D/H', 'A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega']
+
+def copy_repos_over_deleted_same_kind(sbox):
+  "copy repos node over deleted node, same kind"
+  sbox.build(read_only = True)
+
+  expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 1)
+  main.run_svn(None, 'rm', os.path.join(sbox.wc_dir, 'iota'),
+                           os.path.join(sbox.wc_dir, 'A/B'))
+  for path in ['iota', 'A/B'] + A_B_children:
+    expected_status.tweak(path, status='D ')
+  main.run_svn(None, 'cp', sbox.repo_url + '/A/mu',
+               os.path.join(sbox.wc_dir, 'iota'))
+  expected_status.tweak('iota', status='R ', wc_rev='-', copied='+')
+  main.run_svn(None, 'cp', sbox.repo_url + '/A/D',
+               os.path.join(sbox.wc_dir, 'A/B'))
+  expected_status.tweak('A/B', status='R ', wc_rev='-', copied='+')
+  for child in A_D_children:
+    expected_status.add({ child.replace('A/D', 'A/B'):
+                          Item(status='  ', wc_rev='-', copied='+')})
+  svntest.actions.run_and_verify_status(sbox.wc_dir, expected_status)
+
+def copy_repos_over_deleted_other_kind(sbox):
+  "copy repos node over deleted node, other kind"
+  sbox.build(read_only = True)
+
+  expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 1)
+  main.run_svn(None, 'rm', os.path.join(sbox.wc_dir, 'iota'),
+                           os.path.join(sbox.wc_dir, 'A/B'))
+  for path in ['iota', 'A/B'] + A_B_children:
+    expected_status.tweak(path, status='D ')
+  main.run_svn(None, 'cp', sbox.repo_url + '/iota',
+               os.path.join(sbox.wc_dir, 'A/B'))
+  expected_status.tweak('A/B', status='R ', wc_rev='-', copied='+')
+  expected_status.remove(*A_B_children)
+  main.run_svn(None, 'cp', sbox.repo_url + '/A/B',
+               os.path.join(sbox.wc_dir, 'iota'))
+  expected_status.tweak('iota', status='R ', wc_rev='-', copied='+')
+  for child in A_B_children:
+    expected_status.add({ child.replace('A/B', 'iota'):
+                          Item(status='  ', wc_rev='-', copied='+')})
+  svntest.actions.run_and_verify_status(sbox.wc_dir, expected_status)
+
+def copy_wc_over_deleted_same_kind(sbox):
+  "copy WC node over a deleted node, same kind"
+  sbox.build(read_only = True)
+
+  expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 1)
+  main.run_svn(None, 'rm', os.path.join(sbox.wc_dir, 'iota'),
+                           os.path.join(sbox.wc_dir, 'A/B'))
+  for path in ['iota', 'A/B'] + A_B_children:
+    expected_status.tweak(path, status='D ')
+  main.run_svn(None, 'cp', os.path.join(sbox.wc_dir, 'A/mu'),
+               os.path.join(sbox.wc_dir, 'iota'))
+  expected_status.tweak('iota', status='R ', wc_rev='-', copied='+')
+  main.run_svn(None, 'cp', os.path.join(sbox.wc_dir, 'A/D'),
+               os.path.join(sbox.wc_dir, 'A/B'))
+  expected_status.tweak('A/B', status='R ', wc_rev='-', copied='+')
+  for child in A_D_children:
+    expected_status.add({ child.replace('A/D', 'A/B'):
+                          Item(status='  ', wc_rev='-', copied='+')})
+  svntest.actions.run_and_verify_status(sbox.wc_dir, expected_status)
+
+def copy_wc_over_deleted_other_kind(sbox):
+  "copy WC node over deleted node, other kind"
+  sbox.build(read_only = True)
+
+  expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 1)
+  main.run_svn(None, 'rm', os.path.join(sbox.wc_dir, 'iota'),
+                           os.path.join(sbox.wc_dir, 'A/B'))
+  for path in ['iota', 'A/B'] + A_B_children:
+    expected_status.tweak(path, status='D ')
+  main.run_svn(None, 'cp', os.path.join(sbox.wc_dir, 'A/mu'),
+               os.path.join(sbox.wc_dir, 'A/B'))
+  expected_status.tweak('A/B', status='R ', wc_rev='-', copied='+')
+  expected_status.remove(*A_B_children)
+  main.run_svn(None, 'cp', os.path.join(sbox.wc_dir, 'A/D'),
+               os.path.join(sbox.wc_dir, 'iota'))
+  expected_status.tweak('iota', status='R ', wc_rev='-', copied='+')
+  for child in A_D_children:
+    expected_status.add({ child.replace('A/D', 'iota'):
+                          Item(status='  ', wc_rev='-', copied='+')})
+  svntest.actions.run_and_verify_status(sbox.wc_dir, expected_status)
+
 
 ########################################################################
 # Run the tests
@@ -4934,6 +5020,10 @@ test_list = [ None,
               copy_delete_delete,
               XFail(copy_delete_revert),
               delete_replace_delete,
+              copy_repos_over_deleted_same_kind,
+              XFail(copy_repos_over_deleted_other_kind),
+              copy_wc_over_deleted_same_kind,
+              copy_wc_over_deleted_other_kind,
              ]
 
 if __name__ == '__main__':