You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2010/10/30 16:20:18 UTC
svn commit: r1029078 [1/5] - in /subversion/branches/performance: ./
build/ac-macros/ subversion/bindings/javahl/native/
subversion/bindings/javahl/src/org/apache/subversion/javahl/
subversion/bindings/javahl/src/org/tigris/subversion/javahl/ subversio...
Author: stefan2
Date: Sat Oct 30 14:20:17 2010
New Revision: 1029078
URL: http://svn.apache.org/viewvc?rev=1029078&view=rev
Log:
On the performance branch:
Bring up-to-date with trunk.
Modified:
subversion/branches/performance/ (props changed)
subversion/branches/performance/build/ac-macros/java.m4
subversion/branches/performance/subversion/bindings/javahl/native/SVNClient.cpp
subversion/branches/performance/subversion/bindings/javahl/native/SVNClient.h
subversion/branches/performance/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
subversion/branches/performance/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
subversion/branches/performance/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
subversion/branches/performance/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java
subversion/branches/performance/subversion/include/svn_client.h
subversion/branches/performance/subversion/include/svn_wc.h
subversion/branches/performance/subversion/libsvn_client/deprecated.c
subversion/branches/performance/subversion/libsvn_client/externals.c
subversion/branches/performance/subversion/libsvn_client/merge.c
subversion/branches/performance/subversion/libsvn_client/patch.c
subversion/branches/performance/subversion/libsvn_client/relocate.c
subversion/branches/performance/subversion/libsvn_diff/parse-diff.c
subversion/branches/performance/subversion/libsvn_repos/log.c
subversion/branches/performance/subversion/libsvn_wc/adm_crawler.c
subversion/branches/performance/subversion/libsvn_wc/conflicts.c
subversion/branches/performance/subversion/libsvn_wc/copy.c
subversion/branches/performance/subversion/libsvn_wc/props.c
subversion/branches/performance/subversion/libsvn_wc/wc-queries.sql
subversion/branches/performance/subversion/libsvn_wc/wc_db.c
subversion/branches/performance/subversion/libsvn_wc/wc_db.h
subversion/branches/performance/subversion/libsvn_wc/workqueue.c
subversion/branches/performance/subversion/libsvn_wc/workqueue.h
subversion/branches/performance/subversion/svn/cl.h
subversion/branches/performance/subversion/svn/log-cmd.c
subversion/branches/performance/subversion/svn/main.c
subversion/branches/performance/subversion/svn/merge-cmd.c
subversion/branches/performance/subversion/svn/patch-cmd.c
subversion/branches/performance/subversion/svn/relocate-cmd.c
subversion/branches/performance/subversion/svn/status-cmd.c
subversion/branches/performance/subversion/svn/status.c
subversion/branches/performance/subversion/svn/switch-cmd.c
subversion/branches/performance/subversion/tests/cmdline/authz_tests.py
subversion/branches/performance/subversion/tests/cmdline/copy_tests.py
subversion/branches/performance/subversion/tests/cmdline/export_tests.py
subversion/branches/performance/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout
subversion/branches/performance/subversion/tests/cmdline/log_tests.py
subversion/branches/performance/subversion/tests/cmdline/merge_reintegrate_tests.py
subversion/branches/performance/subversion/tests/cmdline/merge_tests.py
subversion/branches/performance/subversion/tests/cmdline/merge_tree_conflict_tests.py
subversion/branches/performance/subversion/tests/cmdline/mergeinfo_tests.py
subversion/branches/performance/subversion/tests/cmdline/patch_tests.py
subversion/branches/performance/subversion/tests/cmdline/resolve_tests.py
subversion/branches/performance/subversion/tests/cmdline/special_tests.py
subversion/branches/performance/subversion/tests/cmdline/stat_tests.py
subversion/branches/performance/subversion/tests/cmdline/switch_tests.py
subversion/branches/performance/subversion/tests/cmdline/tree_conflict_tests.py
subversion/branches/performance/subversion/tests/libsvn_client/client-test.c
subversion/branches/performance/subversion/tests/libsvn_fs_base/strings-reps-test.c
subversion/branches/performance/subversion/tests/libsvn_subr/string-test.c
subversion/branches/performance/subversion/tests/libsvn_wc/db-test.c
subversion/branches/performance/subversion/tests/libsvn_wc/entries-compat.c
subversion/branches/performance/subversion/tests/libsvn_wc/op-depth-test.c
subversion/branches/performance/tools/diff/diff.c
subversion/branches/performance/tools/hook-scripts/svnperms.conf.example
subversion/branches/performance/tools/hook-scripts/svnperms.py
subversion/branches/performance/win-tests.py
Propchange: subversion/branches/performance/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Oct 30 14:20:17 2010
@@ -37,4 +37,4 @@
/subversion/branches/tc_url_rev:874351-874483
/subversion/branches/tree-conflicts:868291-873154
/subversion/branches/tree-conflicts-notify:873926-874008
-/subversion/trunk:962911-1027198
+/subversion/trunk:962911-1028883
Modified: subversion/branches/performance/build/ac-macros/java.m4
URL: http://svn.apache.org/viewvc/subversion/branches/performance/build/ac-macros/java.m4?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/build/ac-macros/java.m4 (original)
+++ subversion/branches/performance/build/ac-macros/java.m4 Sat Oct 30 14:20:17 2010
@@ -82,20 +82,48 @@ AC_DEFUN(SVN_FIND_JDK,
dnl /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Commands
dnl See http://developer.apple.com/qa/qa2001/qa1170.html
os_arch="`uname`"
+ if test "$os_arch" = "Darwin"; then
+ OSX_VER=`/usr/bin/sw_vers | grep ProductVersion | cut -f2 | cut -d"." -f1,2`
+
+ if test "$OSX_VER" = "10.4"; then
+ dnl For OS X 10.4, the SDK version is 10.4u instead of 10.4.
+ OSX_VER = "$OSX_VERu"
+ fi
+
+ OSX_SYS_JAVA_FRAMEWORK="/System/Library/Frameworks/JavaVM.framework"
+ OSX_SDK_JAVA_FRAMEWORK="/Developer/SDKs/MacOSX$OSX_VER.sdk/System/Library"
+ OSX_SDK_JAVA_FRAMEWORK="$OSX_SDK_JAVA_FRAMEWORK/Frameworks/JavaVM.framework"
+ fi
+
if test "$os_arch" = "Darwin" && test "$JDK" = "/usr" &&
test -d "/Library/Java/Home"; then
- JDK="/Library/Java/Home"
+ JDK="/Library/Java/Home"
fi
+
if test "$os_arch" = "Darwin" && test "$JDK" = "/Library/Java/Home"; then
- JRE_LIB_DIR="/System/Library/Frameworks/JavaVM.framework/Classes"
+ JRE_LIB_DIR="$OSX_SYS_JAVA_FRAMEWORK/Classes"
else
- JRE_LIB_DIR="$JDK/jre/lib"
+ JRE_LIB_DIR="$JDK/jre/lib"
fi
if test -f "$JDK/include/jni.h"; then
dnl This *must* be fully expanded, or we'll have problems later in find.
JNI_INCLUDEDIR="$JDK/include"
JDK_SUITABLE=yes
+ elif test "$os_arch" = "Darwin" && test -e "$JDK/Headers/jni.h"; then
+ dnl Search the Headers directory in the JDK
+ JNI_INCLUDEDIR="$JDK/Headers"
+ JDK_SUITABLE=yes
+ elif test "$os_arch" = "Darwin" &&
+ test -e "$OSX_SYS_JAVA_FRAMEWORK/Headers/jni.h"; then
+ dnl Search the System framework's Headers directory
+ JNI_INCLUDEDIR="$OSX_SYS_JAVA_FRAMEWORK/Headers"
+ JDK_SUITABLE=yes
+ elif test "$os_arch" = "Darwin" &&
+ test -e "$OSX_SDK_JAVA_FRAMEWORK/Headers/jni.h"; then
+ dnl Search the SDK's System framework's Headers directory
+ JNI_INCLUDEDIR="$OSX_SDK_JAVA_FRAMEWORK/Headers"
+ JDK_SUITABLE=yes
else
AC_MSG_WARN([no JNI header files found.])
if test "$os_arch" = "Darwin"; then
@@ -103,7 +131,7 @@ AC_DEFUN(SVN_FIND_JDK,
fi
JDK_SUITABLE=no
fi
- AC_MSG_RESULT([$JDK_SUITABLE])
+ AC_MSG_RESULT([$JNI_INCLUDEDIR/jni.h])
if test "$JDK_SUITABLE" = "yes"; then
JAVA_BIN='$(JDK)/bin'
Modified: subversion/branches/performance/subversion/bindings/javahl/native/SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/bindings/javahl/native/SVNClient.cpp?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/bindings/javahl/native/SVNClient.cpp (original)
+++ subversion/branches/performance/subversion/bindings/javahl/native/SVNClient.cpp Sat Oct 30 14:20:17 2010
@@ -1151,7 +1151,8 @@ jbyteArray SVNClient::revProperty(const
return JNIUtil::makeJByteArray((const signed char *)propval->data,
propval->len);
}
-void SVNClient::relocate(const char *from, const char *to, const char *path)
+void SVNClient::relocate(const char *from, const char *to, const char *path,
+ bool ignoreExternals)
{
SVN::Pool requestPool;
SVN_JNI_NULL_PTR_EX(path, "path", );
@@ -1171,7 +1172,7 @@ void SVNClient::relocate(const char *fro
return;
SVN_JNI_ERR(svn_client_relocate2(intPath.c_str(), intFrom.c_str(),
- intTo.c_str(), ctx,
+ intTo.c_str(), ignoreExternals, ctx,
requestPool.pool()), );
}
@@ -1460,7 +1461,7 @@ SVNClient::patch(const char *patchPath,
// Should parameterize the following, instead of defaulting to FALSE
SVN_JNI_ERR(svn_client_patch(checkedPatchPath.c_str(),
checkedTargetPath.c_str(),
- dryRun, stripCount, FALSE, reverse,
+ dryRun, stripCount, reverse,
ignoreWhitespace, removeTempfiles,
PatchCallback::callback, callback,
ctx, requestPool.pool(),
Modified: subversion/branches/performance/subversion/bindings/javahl/native/SVNClient.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/bindings/javahl/native/SVNClient.h?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/bindings/javahl/native/SVNClient.h (original)
+++ subversion/branches/performance/subversion/bindings/javahl/native/SVNClient.h Sat Oct 30 14:20:17 2010
@@ -74,7 +74,8 @@ class SVNClient :public SVNBase
Revision &revisionStart, Revision &revisionEnd,
bool ignoreMimeType, bool includeMergedRevisions,
BlameCallback *callback);
- void relocate(const char *from, const char *to, const char *path);
+ void relocate(const char *from, const char *to, const char *path,
+ bool ignoreExternals);
void streamFileContent(const char *path, Revision &revision,
Revision &pegRevision, OutputStream &outputStream);
void propertySet(const char *path, const char *name, const char *value,
Modified: subversion/branches/performance/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp (original)
+++ subversion/branches/performance/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp Sat Oct 30 14:20:17 2010
@@ -1422,7 +1422,8 @@ Java_org_apache_subversion_javahl_SVNCli
JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNClient_relocate
-(JNIEnv *env, jobject jthis, jstring jfrom, jstring jto, jstring jpath)
+(JNIEnv *env, jobject jthis, jstring jfrom, jstring jto, jstring jpath,
+ jboolean jignoreExternals)
{
JNIEntry(SVNClient, relocate);
SVNClient *cl = SVNClient::getCppObject(jthis);
@@ -1443,7 +1444,7 @@ Java_org_apache_subversion_javahl_SVNCli
if (JNIUtil::isExceptionThrown())
return;
- cl->relocate(from, to, path);
+ cl->relocate(from, to, path, jignoreExternals ? true : false);
return;
}
Modified: subversion/branches/performance/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java (original)
+++ subversion/branches/performance/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java Sat Oct 30 14:20:17 2010
@@ -798,10 +798,11 @@ public interface ISVNClient
* @param from old url
* @param to new url
* @param path working copy path
+ * @param ignoreExternals if externals are ignored during relocate
* @throws ClientException
* @since 1.0
*/
- void relocate(String from, String to, String path)
+ void relocate(String from, String to, String path, boolean ignoreExternals)
throws ClientException;
/**
Modified: subversion/branches/performance/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java (original)
+++ subversion/branches/performance/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java Sat Oct 30 14:20:17 2010
@@ -495,7 +495,8 @@ public class SVNClient implements ISVNCl
/**
* @since 1.0
*/
- public native void relocate(String from, String to, String path)
+ public native void relocate(String from, String to, String path,
+ boolean ignoreExternals)
throws ClientException;
/**
Modified: subversion/branches/performance/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java (original)
+++ subversion/branches/performance/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java Sat Oct 30 14:20:17 2010
@@ -2125,7 +2125,7 @@ public class SVNClient implements SVNCli
try
{
- aSVNClient.relocate(from, to, path);
+ aSVNClient.relocate(from, to, path, true);
}
catch (org.apache.subversion.javahl.ClientException ex)
{
Modified: subversion/branches/performance/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/include/svn_client.h?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/include/svn_client.h (original)
+++ subversion/branches/performance/subversion/include/svn_client.h Sat Oct 30 14:20:17 2010
@@ -3068,9 +3068,39 @@ svn_client_diff_summarize_peg(const char
* If @a dry_run is TRUE, the merge is carried out, and full notification
* feedback is provided, but the working copy is not modified.
*
+ * If allow_mixed_rev is @c FALSE, and @a merge_target is a mixed-revision
+ * working copy, raise @c SVN_ERR_CLIENT_NOT_READY_TO_MERGE.
+ * Because users rarely intend to merge into mixed-revision working copies,
+ * it is recommended to set this parameter to FALSE by default unless the
+ * user has explicitly requested a merge into a mixed-revision working copy.
+ *
* The authentication baton cached in @a ctx is used to communicate with the
* repository.
*
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_client_merge4(const char *source1,
+ const svn_opt_revision_t *revision1,
+ const char *source2,
+ const svn_opt_revision_t *revision2,
+ const char *target_wcpath,
+ svn_depth_t depth,
+ svn_boolean_t ignore_ancestry,
+ svn_boolean_t force,
+ svn_boolean_t record_only,
+ svn_boolean_t dry_run,
+ svn_boolean_t allow_mixed_rev,
+ const apr_array_header_t *merge_options,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool);
+
+/**
+ * Similar to svn_client_merge4(), but with @a allow_mixed_rev set to
+ * @c TRUE.
+ *
+ * @deprecated Provided for backward compatibility with the 1.6 API.
+ *
* @since New in 1.5.
*/
svn_error_t *
@@ -3172,7 +3202,30 @@ svn_client_merge_reintegrate(const char
* list of provided ranges has an `unspecified' or unrecognized
* `kind', return #SVN_ERR_CLIENT_BAD_REVISION.
*
- * All other options are handled identically to svn_client_merge3().
+ * All other options are handled identically to svn_client_merge4().
+ *
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_client_merge_peg4(const char *source,
+ const apr_array_header_t *ranges_to_merge,
+ const svn_opt_revision_t *peg_revision,
+ const char *target_wcpath,
+ svn_depth_t depth,
+ svn_boolean_t ignore_ancestry,
+ svn_boolean_t force,
+ svn_boolean_t record_only,
+ svn_boolean_t dry_run,
+ svn_boolean_t allow_mixed_rev,
+ const apr_array_header_t *merge_options,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool);
+
+/**
+ * Similar to svn_client_merge_peg4(), but with @a allow_mixed_rev set to
+ * @c TRUE.
+ *
+ * @deprecated Provided for backward compatibility with the 1.6 API.
*
* @since New in 1.5.
*/
@@ -3423,6 +3476,8 @@ svn_client_upgrade(const char *dir,
* @param wcroot_dir Working copy root directory
* @param from Original URL
* @param to 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
* @param pool The pool from which to perform memory allocations
*
@@ -3432,11 +3487,13 @@ svn_error_t *
svn_client_relocate2(const char *wcroot_dir,
const char *from,
const char *to,
+ svn_boolean_t ignore_externals,
svn_client_ctx_t *ctx,
apr_pool_t *pool);
/**
- * Similar to svn_client_relocate2().
+ * Similar to svn_client_relocate2(), but with @a ignore_externals
+ * always TRUE.
*
* @note As of the 1.7 API, @a dir is required to be a working copy
* root directory, and @a recurse is required to be TRUE.
@@ -5258,15 +5315,6 @@ typedef svn_error_t *(*svn_client_patch_
* stripped from paths obtained from the patch. It is an error if a
* negative strip count is passed.
*
- * If @a old_patch_target_names is @c TRUE, use target names from the old
- * side of the patch, rather than using target names from the new side of
- * the patch. For instance, if a unidiff header contains
- * --- foo.c
- * +++ foo.c.new
- * and @a old_patch_target_names is @c TRUE, the name "foo.c" will be used
- * for the target, and if @a old_patch_target_names is @c FALSE, the target
- * name "foo.c.new" will be used.
- *
* If @a reverse is @c TRUE, apply patches in reverse, deleting lines
* the patch would add and adding lines the patch would delete.
* This is useful when applying a unidiff which was created with the
@@ -5298,7 +5346,6 @@ svn_client_patch(const char *patch_abspa
const char *local_abspath,
svn_boolean_t dry_run,
int strip_count,
- svn_boolean_t old_patch_target_names,
svn_boolean_t reverse,
svn_boolean_t ignore_whitespace,
svn_boolean_t remove_tempfiles,
Modified: subversion/branches/performance/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/include/svn_wc.h?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/include/svn_wc.h (original)
+++ subversion/branches/performance/subversion/include/svn_wc.h Sat Oct 30 14:20:17 2010
@@ -3796,9 +3796,11 @@ typedef void (*svn_wc_status_func_t)(voi
* If @a cancel_func is non-NULL, call it with @a cancel_baton while walking
* to determine if the client has cancelled the operation.
*
- * If @a external_func is non-NULL, call it with @a external_baton if an
- * external definition is found while walking @a local_abspath.
- * ### call it with what other parameters?
+ * If @a external_func is non-NULL and an external definition is found
+ * while walking @a local_abspath, call @a external_func with @a
+ * external_baton, with the local abspath on which the definition was
+ * found, and with the current external definition provided as both
+ * the @a old_val and @a new_val parameters of the callback function.
*
* This function uses @a scratch_pool for temporary allocations.
*
Modified: subversion/branches/performance/subversion/libsvn_client/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/deprecated.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/deprecated.c (original)
+++ subversion/branches/performance/subversion/libsvn_client/deprecated.c Sat Oct 30 14:20:17 2010
@@ -1338,6 +1338,27 @@ svn_client_log(const apr_array_header_t
/*** From merge.c ***/
svn_error_t *
+svn_client_merge3(const char *source1,
+ const svn_opt_revision_t *revision1,
+ const char *source2,
+ const svn_opt_revision_t *revision2,
+ const char *target_wcpath,
+ svn_depth_t depth,
+ svn_boolean_t ignore_ancestry,
+ svn_boolean_t force,
+ svn_boolean_t record_only,
+ svn_boolean_t dry_run,
+ const apr_array_header_t *merge_options,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ return svn_client_merge4(source1, revision1, source2, revision2,
+ target_wcpath, depth, ignore_ancestry, force,
+ record_only, dry_run, TRUE, merge_options,
+ ctx, pool);
+}
+
+svn_error_t *
svn_client_merge2(const char *source1,
const svn_opt_revision_t *revision1,
const char *source2,
@@ -1376,7 +1397,25 @@ svn_client_merge(const char *source1,
dry_run, NULL, ctx, pool);
}
-
+svn_error_t *
+svn_client_merge_peg3(const char *source,
+ const apr_array_header_t *ranges_to_merge,
+ const svn_opt_revision_t *peg_revision,
+ const char *target_wcpath,
+ svn_depth_t depth,
+ svn_boolean_t ignore_ancestry,
+ svn_boolean_t force,
+ svn_boolean_t record_only,
+ svn_boolean_t dry_run,
+ const apr_array_header_t *merge_options,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ return svn_client_merge_peg4(source, ranges_to_merge, peg_revision,
+ target_wcpath, depth, ignore_ancestry, force,
+ record_only, dry_run, TRUE, merge_options,
+ ctx, pool);
+}
svn_error_t *
svn_client_merge_peg2(const char *source,
@@ -2053,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, ctx, pool);
+ return svn_client_relocate2(path, from, to, TRUE, ctx, pool);
}
Modified: subversion/branches/performance/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/externals.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/externals.c (original)
+++ subversion/branches/performance/subversion/libsvn_client/externals.c Sat Oct 30 14:20:17 2010
@@ -230,7 +230,7 @@ switch_dir_external(const char *path,
subpool));
err = svn_client_relocate2(path, repos_root_url, repos_root,
- ctx, subpool);
+ FALSE, ctx, subpool);
/* If the relocation failed because the new URL points
to another repository, then we need to relegate and
check out a new WC. */
Modified: subversion/branches/performance/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/merge.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/performance/subversion/libsvn_client/merge.c Sat Oct 30 14:20:17 2010
@@ -8862,6 +8862,73 @@ merge_cousins_and_supplement_mergeinfo(c
return SVN_NO_ERROR;
}
+/* Perform checks to determine whether of the working copy at TARGET_ABSPATH
+ * can safely be used as a merge target. Checks are performed according to
+ * the ALLOW_MIXED_REV, ALLOW_LOCAL_MODS, and ALLOW_SWITCHED_SUBTREES
+ * parameters. If any checks fail, raise SVN_ERR_CLIENT_NOT_READY_TO_MERGE.
+ *
+ * E.g. if all the ALLOW_* parameters are FALSE, TARGET_ABSPATH must
+ * be a single-revision, pristine, unswitched working copy.
+ * In other words, it must reflect a subtree of the repostiory as found
+ * at single revision -- although sparse checkouts are permitted. */
+static svn_error_t *
+ensure_wc_is_suitable_merge_target(const char *target_abspath,
+ svn_client_ctx_t *ctx,
+ svn_boolean_t allow_mixed_rev,
+ svn_boolean_t allow_local_mods,
+ svn_boolean_t allow_switched_subtrees,
+ apr_pool_t *scratch_pool)
+{
+ svn_wc_revision_status_t *wc_stat;
+
+ /* Avoid the following status crawl if we don't need it. */
+ if (allow_mixed_rev && allow_local_mods && allow_switched_subtrees)
+ return SVN_NO_ERROR;
+
+ /* Get a WC summary with min/max revisions set to the BASE revision. */
+ SVN_ERR(svn_wc_revision_status2(&wc_stat, ctx->wc_ctx, target_abspath, NULL,
+ FALSE, ctx->cancel_func, ctx->cancel_baton,
+ scratch_pool, scratch_pool));
+
+ if (! allow_switched_subtrees && wc_stat->switched)
+ return svn_error_create(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
+ _("Cannot merge into a working copy "
+ "with a switched subtree"));
+
+ if (! allow_local_mods && wc_stat->modified)
+ return svn_error_create(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
+ _("Cannot merge into a working copy "
+ "that has local modifications"));
+
+ if (! allow_mixed_rev)
+ {
+ if (! (SVN_IS_VALID_REVNUM(wc_stat->min_rev)
+ && SVN_IS_VALID_REVNUM(wc_stat->max_rev)))
+ {
+ svn_boolean_t is_added;
+
+ /* Allow merge into added nodes. */
+ SVN_ERR(svn_wc__node_is_added(&is_added, ctx->wc_ctx, target_abspath,
+ scratch_pool));
+ if (is_added)
+ return SVN_NO_ERROR;
+ else
+ return svn_error_create(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
+ _("Cannot determine revision of working "
+ "copy"));
+ }
+
+ if (wc_stat->min_rev != wc_stat->max_rev)
+ return svn_error_createf(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
+ _("Cannot merge into mixed-revision working "
+ "copy [%lu:%lu]; try updating first"),
+ wc_stat->min_rev, wc_stat->max_rev);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
/*-----------------------------------------------------------------------*/
/*** Public APIs ***/
@@ -8877,6 +8944,7 @@ merge_locked(const char *source1,
svn_boolean_t force,
svn_boolean_t record_only,
svn_boolean_t dry_run,
+ svn_boolean_t allow_mixed_rev,
const apr_array_header_t *merge_options,
svn_client_ctx_t *ctx,
apr_pool_t *scratch_pool)
@@ -8952,6 +9020,12 @@ merge_locked(const char *source1,
_("Merge target '%s' does not exist in the "
"working copy"), target_abspath));
+
+ /* Do not allow merges into mixed-revision working copies. */
+ SVN_ERR(ensure_wc_is_suitable_merge_target(target_abspath, ctx,
+ allow_mixed_rev, TRUE, TRUE,
+ scratch_pool));
+
/* Determine the working copy target's repository root URL. */
working_rev.kind = svn_opt_revision_working;
SVN_ERR(svn_client__get_repos_root(&wc_repos_root, target_abspath,
@@ -9150,6 +9224,7 @@ struct merge_baton {
svn_boolean_t force;
svn_boolean_t record_only;
svn_boolean_t dry_run;
+ svn_boolean_t allow_mixed_rev;
const apr_array_header_t *merge_options;
svn_client_ctx_t *ctx;
};
@@ -9163,7 +9238,8 @@ merge_cb(void *baton, apr_pool_t *result
SVN_ERR(merge_locked(b->source1, b->revision1, b->source2, b->revision2,
b->target_abspath, b->depth, b->ignore_ancestry,
b->force, b->record_only, b->dry_run,
- b->merge_options, b->ctx, scratch_pool));
+ b->allow_mixed_rev, b->merge_options, b->ctx,
+ scratch_pool));
return SVN_NO_ERROR;
}
@@ -9191,7 +9267,7 @@ get_target_and_lock_abspath(const char *
}
svn_error_t *
-svn_client_merge3(const char *source1,
+svn_client_merge4(const char *source1,
const svn_opt_revision_t *revision1,
const char *source2,
const svn_opt_revision_t *revision2,
@@ -9201,6 +9277,7 @@ svn_client_merge3(const char *source1,
svn_boolean_t force,
svn_boolean_t record_only,
svn_boolean_t dry_run,
+ svn_boolean_t allow_mixed_rev,
const apr_array_header_t *merge_options,
svn_client_ctx_t *ctx,
apr_pool_t *pool)
@@ -9221,6 +9298,7 @@ svn_client_merge3(const char *source1,
baton.force = force;
baton.record_only = record_only;
baton.dry_run = dry_run;
+ baton.allow_mixed_rev = allow_mixed_rev;
baton.merge_options = merge_options;
baton.ctx = ctx;
@@ -9235,45 +9313,6 @@ svn_client_merge3(const char *source1,
}
-/* If TARGET_WCPATH does not reflect a single-revision, pristine,
- unswitched working copy -- in other words, a subtree found in a
- single revision (although sparse checkouts are permitted) -- raise
- SVN_ERR_CLIENT_NOT_READY_TO_MERGE. */
-static svn_error_t *
-ensure_wc_reflects_repository_subtree(const char *target_abspath,
- svn_client_ctx_t *ctx,
- apr_pool_t *scratch_pool)
-{
- svn_wc_revision_status_t *wc_stat;
-
- /* Get a WC summary with min/max revisions set to the BASE revision. */
- SVN_ERR(svn_wc_revision_status2(&wc_stat, ctx->wc_ctx, target_abspath, NULL,
- FALSE, ctx->cancel_func, ctx->cancel_baton,
- scratch_pool, scratch_pool));
-
- if (wc_stat->switched)
- return svn_error_create(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
- _("Cannot reintegrate into a working copy "
- "with a switched subtree"));
-
- if (wc_stat->modified)
- return svn_error_create(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
- _("Cannot reintegrate into a working copy "
- "that has local modifications"));
-
- if (! (SVN_IS_VALID_REVNUM(wc_stat->min_rev)
- && SVN_IS_VALID_REVNUM(wc_stat->max_rev)))
- return svn_error_create(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
- _("Cannot determine revision of working copy"));
-
- if (wc_stat->min_rev != wc_stat->max_rev)
- return svn_error_create(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
- _("Cannot reintegrate into mixed-revision "
- "working copy; try updating first"));
-
- return SVN_NO_ERROR;
-}
-
/* Check if mergeinfo for a given path is described explicitly or via
inheritance in a mergeinfo catalog.
@@ -10221,8 +10260,11 @@ merge_reintegrate_locked(const char *sou
svn_dirent_local_style(target_abspath,
scratch_pool));
- SVN_ERR(ensure_wc_reflects_repository_subtree(target_abspath, ctx,
- scratch_pool));
+ /* A reintegrate merge requires the merge target to reflect a subtree
+ * of the repository as found at a single revision. */
+ SVN_ERR(ensure_wc_is_suitable_merge_target(target_abspath, ctx,
+ FALSE, FALSE, FALSE,
+ scratch_pool));
SVN_ERR(svn_wc__node_get_base_rev(&target_base_rev, ctx->wc_ctx,
target_abspath, scratch_pool));
@@ -10438,6 +10480,7 @@ merge_peg_locked(const char *source,
svn_boolean_t force,
svn_boolean_t record_only,
svn_boolean_t dry_run,
+ svn_boolean_t allow_mixed_rev,
const apr_array_header_t *merge_options,
svn_client_ctx_t *ctx,
apr_pool_t *scratch_pool)
@@ -10479,6 +10522,10 @@ merge_peg_locked(const char *source,
_("Merge target '%s' does not exist in the "
"working copy"), target_abspath));
+ SVN_ERR(ensure_wc_is_suitable_merge_target(target_abspath, ctx,
+ allow_mixed_rev, TRUE, TRUE,
+ scratch_pool));
+
/* Determine the working copy target's repository root URL. */
working_rev.kind = svn_opt_revision_working;
SVN_ERR(svn_client__get_repos_root(&wc_repos_root, target_abspath,
@@ -10541,6 +10588,7 @@ struct merge_peg_baton {
svn_boolean_t force;
svn_boolean_t record_only;
svn_boolean_t dry_run;
+ svn_boolean_t allow_mixed_rev;
const apr_array_header_t *merge_options;
svn_client_ctx_t *ctx;
};
@@ -10554,13 +10602,14 @@ merge_peg_cb(void *baton, apr_pool_t *re
SVN_ERR(merge_peg_locked(b->source, b->ranges_to_merge, b->peg_revision,
b->target_abspath, b->depth, b->ignore_ancestry,
b->force, b->record_only, b->dry_run,
- b->merge_options, b->ctx, scratch_pool));
+ b->allow_mixed_rev, b->merge_options, b->ctx,
+ scratch_pool));
return SVN_NO_ERROR;
}
svn_error_t *
-svn_client_merge_peg3(const char *source,
+svn_client_merge_peg4(const char *source,
const apr_array_header_t *ranges_to_merge,
const svn_opt_revision_t *peg_revision,
const char *target_wcpath,
@@ -10569,6 +10618,7 @@ svn_client_merge_peg3(const char *source
svn_boolean_t force,
svn_boolean_t record_only,
svn_boolean_t dry_run,
+ svn_boolean_t allow_mixed_rev,
const apr_array_header_t *merge_options,
svn_client_ctx_t *ctx,
apr_pool_t *pool)
@@ -10592,6 +10642,7 @@ svn_client_merge_peg3(const char *source
baton.force = force;
baton.record_only = record_only;
baton.dry_run = dry_run;
+ baton.allow_mixed_rev = allow_mixed_rev;
baton.merge_options = merge_options;
baton.ctx = ctx;
Modified: subversion/branches/performance/subversion/libsvn_client/patch.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/patch.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/patch.c (original)
+++ subversion/branches/performance/subversion/libsvn_client/patch.c Sat Oct 30 14:20:17 2010
@@ -346,9 +346,7 @@ resolve_target_path(patch_target_t *targ
target->canon_path_from_patchfile = svn_dirent_internal_style(
path_from_patchfile, result_pool);
- /* We allow properties to be set on the wc root dir.
- * ### Do we need to check for empty paths here, shouldn't the parser
- * ### guarentee that the paths returned are non-empty? */
+ /* We allow properties to be set on the wc root dir. */
if (! prop_changes_only && target->canon_path_from_patchfile[0] == '\0')
{
/* An empty patch target path? What gives? Skip this. */
@@ -498,7 +496,7 @@ init_prop_target(prop_patch_target_t **p
new_prop_target->content_info = content_info;
err = svn_wc_prop_get2(&value, wc_ctx, local_abspath, prop_name,
- result_pool, scratch_pool);
+ result_pool, scratch_pool);
if (err)
{
if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
@@ -528,12 +526,40 @@ init_prop_target(prop_patch_target_t **p
return SVN_NO_ERROR;
}
+/* Return a suitable filename for the target of PATCH.
+ * Examine the ``old'' and ``new'' file names, and choose the file name
+ * with the fewest path components, the shortest basename, and the shortest
+ * total file name length (in that order). In case of a tie, return the new
+ * filename. This heuristic is also used by Larry Wall's UNIX patch (except
+ * that it prompts for a filename in case of a tie). */
+static const char *
+choose_target_filename(const svn_patch_t *patch)
+{
+ apr_size_t old;
+ apr_size_t new;
+
+ old = svn_path_component_count(patch->old_filename);
+ new = svn_path_component_count(patch->new_filename);
+
+ if (old == new)
+ {
+ old = strlen(svn_dirent_basename(patch->old_filename, NULL));
+ new = strlen(svn_dirent_basename(patch->new_filename, NULL));
+
+ if (old == new)
+ {
+ old = strlen(patch->old_filename);
+ new = strlen(patch->new_filename);
+ }
+ }
+
+ return (old < new) ? patch->old_filename : patch->new_filename;
+}
+
/* Attempt to initialize a *PATCH_TARGET structure for a target file
* described by PATCH. Use working copy context WC_CTX.
* STRIP_COUNT specifies the number of leading path components
* which should be stripped from target paths in the patch.
- * OLD_PATCH_TARGET_NAMES indicates whether the old target's name parsed
- * from the patch file should be preferred over the new target's name.
* The patch target structure is allocated in RESULT_POOL, but if the target
* should be skipped, PATCH_TARGET->SKIPPED is set and the target should be
* treated as not fully initialized, e.g. the caller should not not do any
@@ -545,9 +571,7 @@ static svn_error_t *
init_patch_target(patch_target_t **patch_target,
const svn_patch_t *patch,
const char *base_dir,
- svn_wc_context_t *wc_ctx,
- int strip_count,
- svn_boolean_t old_patch_target_names,
+ svn_wc_context_t *wc_ctx, int strip_count,
svn_boolean_t remove_tempfiles,
apr_pool_t *result_pool, apr_pool_t *scratch_pool)
{
@@ -593,8 +617,7 @@ init_patch_target(patch_target_t **patch
target->prop_targets = apr_hash_make(result_pool);
target->pool = result_pool;
- SVN_ERR(resolve_target_path(target, old_patch_target_names ?
- patch->old_filename : patch->new_filename,
+ SVN_ERR(resolve_target_path(target, choose_target_filename(patch),
base_dir, strip_count, prop_changes_only,
wc_ctx, result_pool, scratch_pool));
if (! target->skipped)
@@ -1270,12 +1293,13 @@ copy_lines_to_target(target_content_info
return SVN_NO_ERROR;
}
-/* Write the diff text of the hunk described by HI to the
- * reject stream of CONTENT_INFO, and mark TARGET as having had rejects.
+/* Write the diff text of HUNK to the reject stream of CONTENT_INFO,
+ * and mark TARGET as having had rejects.
* Do temporary allocations in POOL. */
static svn_error_t *
reject_hunk(patch_target_t *target, target_content_info_t *content_info,
- hunk_info_t *hi, const char *prop_name, apr_pool_t *pool)
+ const svn_diff_hunk_t *hunk, const char *prop_name,
+ apr_pool_t *pool)
{
const char *hunk_header;
apr_size_t len;
@@ -1296,18 +1320,18 @@ reject_hunk(patch_target_t *target, targ
/* ### What about just setting a variable to either "@@" or "##",
* ### and merging with the else clause below? */
hunk_header = apr_psprintf(pool, "## -%lu,%lu +%lu,%lu ##%s",
- svn_diff_hunk_get_original_start(hi->hunk),
- svn_diff_hunk_get_original_length(hi->hunk),
- svn_diff_hunk_get_modified_start(hi->hunk),
- svn_diff_hunk_get_modified_length(hi->hunk),
+ svn_diff_hunk_get_original_start(hunk),
+ svn_diff_hunk_get_original_length(hunk),
+ svn_diff_hunk_get_modified_start(hunk),
+ svn_diff_hunk_get_modified_length(hunk),
APR_EOL_STR);
}
else
hunk_header = apr_psprintf(pool, "@@ -%lu,%lu +%lu,%lu @@%s",
- svn_diff_hunk_get_original_start(hi->hunk),
- svn_diff_hunk_get_original_length(hi->hunk),
- svn_diff_hunk_get_modified_start(hi->hunk),
- svn_diff_hunk_get_modified_length(hi->hunk),
+ svn_diff_hunk_get_original_start(hunk),
+ svn_diff_hunk_get_original_length(hunk),
+ svn_diff_hunk_get_modified_start(hunk),
+ svn_diff_hunk_get_modified_length(hunk),
APR_EOL_STR);
len = strlen(hunk_header);
SVN_ERR(svn_stream_write(content_info->reject, hunk_header, &len));
@@ -1320,7 +1344,7 @@ reject_hunk(patch_target_t *target, targ
svn_pool_clear(iterpool);
- SVN_ERR(svn_diff_hunk_readline_diff_text(hi->hunk, &hunk_line, &eol_str,
+ SVN_ERR(svn_diff_hunk_readline_diff_text(hunk, &hunk_line, &eol_str,
&eof, iterpool, iterpool));
if (! eof)
{
@@ -1384,7 +1408,7 @@ apply_hunk(patch_target_t *target, targe
{
/* Seek failed, reject this hunk. */
hi->rejected = TRUE;
- SVN_ERR(reject_hunk(target, content_info, hi, prop_name, pool));
+ SVN_ERR(reject_hunk(target, content_info, hi->hunk, prop_name, pool));
return SVN_NO_ERROR;
}
}
@@ -1595,31 +1619,30 @@ close_target_streams(const patch_target_
apr_hash_index_t *hi;
target_content_info_t *prop_content_info;
- /* First the streams belonging to properties .. */
- for (hi = apr_hash_first(pool, target->prop_targets);
- hi;
- hi = apr_hash_next(hi))
- {
- prop_patch_target_t *prop_target;
- prop_target = svn__apr_hash_index_val(hi);
- prop_content_info = prop_target->content_info;
-
- /* ### If the prop did not exist pre-patching we'll not have a
- * ### stream to read from. Find a better way to store info on
- * ### the existence of the target prop. */
- if (prop_content_info->stream)
- SVN_ERR(svn_stream_close(prop_content_info->stream));
+ /* First the streams belonging to properties .. */
+ for (hi = apr_hash_first(pool, target->prop_targets);
+ hi;
+ hi = apr_hash_next(hi))
+ {
+ prop_patch_target_t *prop_target;
+ prop_target = svn__apr_hash_index_val(hi);
+ prop_content_info = prop_target->content_info;
- SVN_ERR(svn_stream_close(prop_content_info->patched));
- }
+ /* ### If the prop did not exist pre-patching we'll not have a
+ * ### stream to read from. Find a better way to store info on
+ * ### the existence of the target prop. */
+ if (prop_content_info->stream)
+ SVN_ERR(svn_stream_close(prop_content_info->stream));
+ SVN_ERR(svn_stream_close(prop_content_info->patched));
+ }
- /* .. And then streams associted with the file. The reject stream is
- * shared between all target_content_info structures. */
+ /* .. and then streams associated with the file.
+ * ### We're not closing the reject stream -- it still needed and
+ * ### will be closed later in write_out_rejected_hunks(). */
if (target->kind_on_disk == svn_node_file)
SVN_ERR(svn_stream_close(target->content_info->stream));
SVN_ERR(svn_stream_close(target->content_info->patched));
- SVN_ERR(svn_stream_close(target->content_info->reject));
return SVN_NO_ERROR;
}
@@ -1630,8 +1653,6 @@ close_target_streams(const patch_target_
* in RESULT_POOL. Use WC_CTX as the working copy context.
* STRIP_COUNT specifies the number of leading path components
* which should be stripped from target paths in the patch.
- * OLD_PATCH_TARGET_NAMES indicates whether the old filename parsed
- * from the patch file should be preferred over the new filename.
* REMOVE_TEMPFILES, PATCH_FUNC, and PATCH_BATON as in svn_client_patch().
* IGNORE_WHITESPACE tells whether whitespace should be considered when
* doing the matching.
@@ -1641,7 +1662,6 @@ static svn_error_t *
apply_one_patch(patch_target_t **patch_target, svn_patch_t *patch,
const char *abs_wc_path, svn_wc_context_t *wc_ctx,
int strip_count,
- svn_boolean_t old_patch_target_names,
svn_boolean_t ignore_whitespace,
svn_boolean_t remove_tempfiles,
svn_client_patch_func_t patch_func,
@@ -1656,8 +1676,7 @@ apply_one_patch(patch_target_t **patch_t
static const int MAX_FUZZ = 2;
apr_hash_index_t *hash_index;
- SVN_ERR(init_patch_target(&target, patch, abs_wc_path, wc_ctx,
- strip_count, old_patch_target_names,
+ SVN_ERR(init_patch_target(&target, patch, abs_wc_path, wc_ctx, strip_count,
remove_tempfiles, result_pool, scratch_pool));
if (target->skipped)
{
@@ -1720,7 +1739,7 @@ apply_one_patch(patch_target_t **patch_t
if (hi->already_applied)
continue;
else if (hi->rejected)
- SVN_ERR(reject_hunk(target, target->content_info, hi,
+ SVN_ERR(reject_hunk(target, target->content_info, hi->hunk,
NULL /* prop_name */,
iterpool));
else
@@ -1809,7 +1828,7 @@ apply_one_patch(patch_target_t **patch_t
if (hi->already_applied)
continue;
else if (hi->rejected)
- SVN_ERR(reject_hunk(target, prop_target->content_info, hi,
+ SVN_ERR(reject_hunk(target, prop_target->content_info, hi->hunk,
prop_target->name,
iterpool));
else
@@ -2129,6 +2148,8 @@ write_out_rejected_hunks(patch_target_t
svn_boolean_t dry_run,
apr_pool_t *pool)
{
+ SVN_ERR(svn_stream_close(target->content_info->reject));
+
if (! dry_run && (target->had_rejects || target->had_prop_rejects))
{
/* Write out rejected hunks, if any. */
@@ -2152,14 +2173,6 @@ install_patched_prop_targets(patch_targe
apr_hash_index_t *hi;
apr_pool_t *iterpool;
- if (dry_run)
- {
- if (! target->has_text_changes && target->kind_on_disk == svn_node_none)
- target->added = TRUE;
-
- return SVN_NO_ERROR;
- }
-
iterpool = svn_pool_create(scratch_pool);
for (hi = apr_hash_first(scratch_pool, target->prop_targets);
@@ -2171,19 +2184,22 @@ install_patched_prop_targets(patch_targe
svn_stream_t *patched_stream;
svn_stringbuf_t *line;
svn_stringbuf_t *prop_content;
+ const svn_string_t *prop_val;
const char *eol_str;
svn_boolean_t eof;
+ svn_error_t *err;
svn_pool_clear(iterpool);
/* For a deleted prop we only set the value to NULL. */
if (prop_target->operation == svn_diff_op_deleted)
{
- SVN_ERR(svn_wc_prop_set4(ctx->wc_ctx, target->local_abspath,
- prop_target->name, NULL,
- TRUE /* skip_checks */,
- NULL, NULL, /* suppress notification */
- iterpool));
+ if (! dry_run)
+ SVN_ERR(svn_wc_prop_set4(ctx->wc_ctx, target->local_abspath,
+ prop_target->name, NULL,
+ TRUE /* skip_checks */,
+ NULL, NULL, /* suppress notification */
+ iterpool));
continue;
}
@@ -2227,28 +2243,72 @@ install_patched_prop_targets(patch_targe
&& target->kind_on_disk == svn_node_none
&& ! target->added)
{
- SVN_ERR(svn_io_file_create(target->local_abspath, "", scratch_pool));
- SVN_ERR(svn_wc_add_from_disk(ctx->wc_ctx, target->local_abspath,
- ctx->cancel_func, ctx->cancel_baton,
- NULL, NULL, /* suppress notification */
- iterpool));
+ if (! dry_run)
+ {
+ SVN_ERR(svn_io_file_create(target->local_abspath, "",
+ scratch_pool));
+ SVN_ERR(svn_wc_add_from_disk(ctx->wc_ctx, target->local_abspath,
+ ctx->cancel_func, ctx->cancel_baton,
+ /* suppress notification */
+ NULL, NULL,
+ iterpool));
+ }
target->added = TRUE;
}
- /* ### How should we handle SVN_ERR_ILLEGAL_TARGET and
- * ### SVN_ERR_BAD_MIME_TYPE?
- *
- * ### stsp: I'd say reject the property hunk.
- * ### We should verify all modified prop hunk texts using
- * ### svn_wc_canonicalize_svn_prop() before starting the
- * ### patching process, to reject them as early as possible. */
- SVN_ERR(svn_wc_prop_set4(ctx->wc_ctx, target->local_abspath,
- prop_target->name,
- svn_string_create_from_buf(prop_content,
- iterpool),
- TRUE /* skip_checks */,
- NULL, NULL,
- iterpool));
+ /* Attempt to set the property, and reject all hunks if this fails. */
+ prop_val = svn_string_create_from_buf(prop_content, iterpool);
+ if (dry_run)
+ {
+ const svn_string_t *canon_propval;
+
+ err = svn_wc_canonicalize_svn_prop(&canon_propval,
+ prop_target->name,
+ prop_val, target->local_abspath,
+ target->db_kind,
+ TRUE, /* ### Skipping checks */
+ NULL, NULL,
+ iterpool);
+ }
+ else
+ {
+ err = (svn_wc_prop_set4(ctx->wc_ctx, target->local_abspath,
+ prop_target->name, prop_val,
+ TRUE, /* ### Skipping checks */
+ NULL, NULL,
+ iterpool));
+ }
+
+ if (err)
+ {
+ /* ### The errors which svn_wc_canonicalize_svn_prop() will
+ * ### return aren't documented. */
+ if (err->apr_err == SVN_ERR_ILLEGAL_TARGET ||
+ err->apr_err == SVN_ERR_NODE_UNEXPECTED_KIND ||
+ err->apr_err == SVN_ERR_IO_UNKNOWN_EOL ||
+ err->apr_err == SVN_ERR_BAD_MIME_TYPE ||
+ err->apr_err == SVN_ERR_CLIENT_INVALID_EXTERNALS_DESCRIPTION)
+ {
+ int i;
+
+ svn_error_clear(err);
+
+ for (i = 0; i < prop_target->content_info->hunks->nelts; i++)
+ {
+ hunk_info_t *hunk_info;
+
+ hunk_info = APR_ARRAY_IDX(prop_target->content_info->hunks,
+ i, hunk_info_t *);
+ hunk_info->rejected = TRUE;
+ SVN_ERR(reject_hunk(target, prop_target->content_info,
+ hunk_info->hunk, prop_target->name,
+ iterpool));
+ }
+ }
+ else
+ return svn_error_return(err);
+ }
+
}
svn_pool_destroy(iterpool);
@@ -2535,9 +2595,6 @@ typedef struct {
/* Number of leading components to strip from patch target paths. */
int strip_count;
- /* Whether to use the old path from the patch file instead of the new one. */
- svn_boolean_t old_patch_target_names;
-
/* Whether to apply the patch in reverse. */
svn_boolean_t reverse;
@@ -2603,7 +2660,6 @@ apply_patches(void *baton,
SVN_ERR(apply_one_patch(&target, patch, btn->abs_wc_path,
btn->ctx->wc_ctx, btn->strip_count,
- btn->old_patch_target_names,
btn->ignore_whitespace,
btn->remove_tempfiles,
btn->patch_func, btn->patch_baton,
@@ -2661,7 +2717,6 @@ svn_client_patch(const char *patch_abspa
const char *local_abspath,
svn_boolean_t dry_run,
int strip_count,
- svn_boolean_t old_patch_target_names,
svn_boolean_t reverse,
svn_boolean_t ignore_whitespace,
svn_boolean_t remove_tempfiles,
@@ -2682,7 +2737,6 @@ svn_client_patch(const char *patch_abspa
baton.dry_run = dry_run;
baton.ctx = ctx;
baton.strip_count = strip_count;
- baton.old_patch_target_names = old_patch_target_names;
baton.reverse = reverse;
baton.ignore_whitespace = ignore_whitespace;
baton.remove_tempfiles = remove_tempfiles;
Modified: subversion/branches/performance/subversion/libsvn_client/relocate.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/relocate.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/relocate.c (original)
+++ subversion/branches/performance/subversion/libsvn_client/relocate.c Sat Oct 30 14:20:17 2010
@@ -125,15 +125,122 @@ validator_func(void *baton,
return SVN_NO_ERROR;
}
+
+/* Callback of type svn_wc_external_update_t. Just squirrels away an
+ svn:externals property value into BATON (which is an apr_hash_t *
+ keyed on local absolute path). */
+static svn_error_t *
+externals_update_func(void *baton,
+ const char *local_abspath,
+ const svn_string_t *old_val,
+ const svn_string_t *new_val,
+ svn_depth_t depth,
+ apr_pool_t *scratch_pool)
+{
+ apr_hash_t *externals_hash = baton;
+ apr_pool_t *hash_pool = apr_hash_pool_get(externals_hash);
+
+ apr_hash_set(externals_hash, apr_pstrdup(hash_pool, local_abspath),
+ APR_HASH_KEY_STRING, svn_string_dup(new_val, hash_pool));
+ return SVN_NO_ERROR;
+}
+
+
+/* Callback of type svn_wc_status_func4_t. Does nothing. */
+static svn_error_t *
+status_noop_func(void *baton,
+ const char *local_abspath,
+ const svn_wc_status3_t *status,
+ apr_pool_t *scratch_pool)
+{
+ return SVN_NO_ERROR;
+}
+
+
+/* Examing the array of svn_wc_external_item2_t's EXT_DESC (parsed
+ from the svn:externals property set on LOCAL_ABSPATH) and determine
+ if the external working copies described by such should be
+ relocated as a side-effect of the relocation of their parent
+ working copy (from OLD_PARENT_REPOS_ROOT_URL to
+ NEW_PARENT_REPOS_ROOT_URL). If so, attempt said relocation. */
+static svn_error_t *
+relocate_externals(const char *local_abspath,
+ apr_array_header_t *ext_desc,
+ const char *old_parent_repos_root_url,
+ const char *new_parent_repos_root_url,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ const char *url;
+ apr_pool_t *iterpool;
+ int i;
+
+ SVN_ERR(svn_client_url_from_path2(&url, local_abspath, ctx,
+ scratch_pool, scratch_pool));
+
+ /* Parse an externals definition into an array of external items. */
+
+ iterpool = svn_pool_create(scratch_pool);
+
+ for (i = 0; i < ext_desc->nelts; i++)
+ {
+ svn_wc_external_item2_t *ext_item =
+ APR_ARRAY_IDX(ext_desc, i, svn_wc_external_item2_t *);
+ const char *target_repos_root_url;
+ const char *target_abspath;
+
+ svn_pool_clear(iterpool);
+
+ /* If this external isn't pulled in via a relative URL, ignore
+ it. There's no sense in relocating a working copy only to
+ have the next 'svn update' try to point it back to another
+ location. */
+ if (! ((strncmp("../", ext_item->url, 3) == 0) ||
+ (strncmp("^/", ext_item->url, 2) == 0)))
+ continue;
+
+ /* If the external working copy's not-yet-relocated repos root
+ URL matches the primary working copy's pre-relocated
+ repository root URL, try to relocate that external, too.
+ You might wonder why this check is needed, given that we're
+ already limiting ourselves to externals pulled via URLs
+ relative to their primary working copy. Well, it's because
+ you can use "../" to "crawl up" above one repository's URL
+ space and down into another one. */
+ SVN_ERR(svn_dirent_get_absolute(&target_abspath,
+ svn_dirent_join(local_abspath,
+ ext_item->target_dir,
+ iterpool),
+ iterpool));
+ SVN_ERR(svn_client_root_url_from_path(&target_repos_root_url,
+ target_abspath, ctx, iterpool));
+
+ if (strcmp(target_repos_root_url, old_parent_repos_root_url) == 0)
+ SVN_ERR(svn_client_relocate2(target_abspath,
+ old_parent_repos_root_url,
+ new_parent_repos_root_url,
+ TRUE, ctx, iterpool));
+ }
+
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
+
svn_error_t *
svn_client_relocate2(const char *wcroot_dir,
const char *from,
const char *to,
+ svn_boolean_t ignore_externals,
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
struct validator_baton_t vb;
const char *local_abspath;
+ apr_hash_t *externals_hash = NULL;
+ apr_hash_index_t *hi;
+ apr_pool_t *iterpool = NULL;
+ const char *old_repos_root_url, *new_repos_root_url;
/* Populate our validator callback baton, and call the relocate code. */
vb.ctx = ctx;
@@ -142,8 +249,61 @@ svn_client_relocate2(const char *wcroot_
vb.pool = pool;
SVN_ERR(svn_dirent_get_absolute(&local_abspath, wcroot_dir, pool));
+
+ /* If we're ignoring externals, just relocate and get outta here. */
+ if (ignore_externals)
+ {
+ return svn_error_return(svn_wc_relocate4(ctx->wc_ctx, local_abspath,
+ from, to, validator_func, &vb,
+ pool));
+ }
+
+ /* Fetch our current root URL. */
+ SVN_ERR(svn_client_root_url_from_path(&old_repos_root_url, local_abspath,
+ ctx, pool));
+
+ /* Perform the relocation. */
SVN_ERR(svn_wc_relocate4(ctx->wc_ctx, local_abspath, from, to,
validator_func, &vb, pool));
+ /* Now fetch new current root URL. */
+ SVN_ERR(svn_client_root_url_from_path(&new_repos_root_url, local_abspath,
+ ctx, pool));
+
+ externals_hash = apr_hash_make(pool);
+
+ /* Do a status run just to harvest externals definitions. */
+ SVN_ERR(svn_wc_walk_status(ctx->wc_ctx, local_abspath,
+ svn_depth_infinity, FALSE, FALSE, NULL,
+ status_noop_func, NULL,
+ externals_update_func, externals_hash,
+ ctx->cancel_func, ctx->cancel_baton, pool));
+
+ /* No externals? No problem. We're done here. */
+ if (! apr_hash_count(externals_hash))
+ return SVN_NO_ERROR;
+
+ iterpool = svn_pool_create(pool);
+
+ for (hi = apr_hash_first(pool, externals_hash);
+ hi != NULL;
+ hi = apr_hash_next(hi))
+ {
+ const char *this_abspath = svn__apr_hash_index_key(hi);
+ const svn_string_t *pval = svn__apr_hash_index_val(hi);
+ apr_array_header_t *ext_desc;
+
+ svn_pool_clear(iterpool);
+
+ SVN_ERR(svn_wc_parse_externals_description3(&ext_desc, this_abspath,
+ pval->data, FALSE,
+ iterpool));
+ if (ext_desc->nelts)
+ SVN_ERR(relocate_externals(this_abspath, ext_desc, old_repos_root_url,
+ new_repos_root_url, ctx, iterpool));
+ }
+
+ svn_pool_destroy(iterpool);
+
return SVN_NO_ERROR;
}
Modified: subversion/branches/performance/subversion/libsvn_diff/parse-diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_diff/parse-diff.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_diff/parse-diff.c (original)
+++ subversion/branches/performance/subversion/libsvn_diff/parse-diff.c Sat Oct 30 14:20:17 2010
@@ -28,6 +28,7 @@
#include "svn_error.h"
#include "svn_io.h"
#include "svn_pools.h"
+#include "svn_props.h"
#include "svn_string.h"
#include "svn_utf.h"
#include "svn_dirent_uri.h"
@@ -481,19 +482,24 @@ svn_diff_hunk_readline_diff_text(const s
return SVN_NO_ERROR;
}
-/* Parse PROP_NAME from HEADER as the part after the INDICATOR line. */
+/* Parse *PROP_NAME from HEADER as the part after the INDICATOR line.
+ * Allocate *PROP_NAME in RESULT_POOL.
+ * Set *PROP_NAME to NULL if no valid property name was found. */
static svn_error_t *
parse_prop_name(const char **prop_name, const char *header,
const char *indicator, apr_pool_t *result_pool)
{
- /* ### This can fail if the filename cannot be represented in the current
- * ### locale's encoding. */
SVN_ERR(svn_utf_cstring_to_utf8(prop_name,
header + strlen(indicator),
result_pool));
-
- /* ### Are we guarenteed that there are no trailing or leading
- * ### whitespaces in the name? */
+ if (**prop_name == '\0')
+ *prop_name = NULL;
+ else if (! svn_prop_name_is_valid(*prop_name))
+ {
+ svn_stringbuf_t *buf = svn_stringbuf_create(*prop_name, result_pool);
+ svn_stringbuf_strip_whitespace(buf);
+ *prop_name = (svn_prop_name_is_valid(buf->data) ? buf->data : NULL);
+ }
return SVN_NO_ERROR;
}
@@ -678,20 +684,23 @@ parse_next_hunk(svn_diff_hunk_t **hunk,
else if (starts_with(line->data, "Added: "))
{
SVN_ERR(parse_prop_name(prop_name, line->data, "Added: ",
- result_pool));
- *prop_operation = svn_diff_op_added;
+ result_pool));
+ if (*prop_name)
+ *prop_operation = svn_diff_op_added;
}
else if (starts_with(line->data, "Deleted: "))
{
SVN_ERR(parse_prop_name(prop_name, line->data, "Deleted: ",
result_pool));
- *prop_operation = svn_diff_op_deleted;
+ if (*prop_name)
+ *prop_operation = svn_diff_op_deleted;
}
else if (starts_with(line->data, "Modified: "))
{
SVN_ERR(parse_prop_name(prop_name, line->data, "Modified: ",
result_pool));
- *prop_operation = svn_diff_op_modified;
+ if (*prop_name)
+ *prop_operation = svn_diff_op_modified;
}
else if (starts_with(line->data, minus)
|| starts_with(line->data, "diff --git "))
@@ -1266,6 +1275,8 @@ svn_diff_parse_next_patch(svn_patch_t **
const char *prop_name;
svn_diff_operation_kind_t prop_operation;
+ last_prop_name = NULL;
+
/* Parse hunks. */
(*patch)->hunks = apr_array_make(result_pool, 10,
sizeof(svn_diff_hunk_t *));
Modified: subversion/branches/performance/subversion/libsvn_repos/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_repos/log.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_repos/log.c (original)
+++ subversion/branches/performance/subversion/libsvn_repos/log.c Sat Oct 30 14:20:17 2010
@@ -1034,7 +1034,10 @@ send_log(svn_revnum_t rev,
memory. */
#define MAX_OPEN_HISTORIES 32
-/* Get the histories for PATHS, and store them in *HISTORIES. */
+/* Get the histories for PATHS, and store them in *HISTORIES.
+
+ If IGNORE_MISSING_LOCATIONS is set, don't treat requests for bogus
+ repository locations as fatal -- just ignore them. */
static svn_error_t *
get_path_histories(apr_array_header_t **histories,
svn_fs_t *fs,
@@ -1042,6 +1045,7 @@ get_path_histories(apr_array_header_t **
svn_revnum_t hist_start,
svn_revnum_t hist_end,
svn_boolean_t strict_node_history,
+ svn_boolean_t ignore_missing_locations,
svn_repos_authz_func_t authz_read_func,
void *authz_read_baton,
apr_pool_t *pool)
@@ -1089,7 +1093,18 @@ get_path_histories(apr_array_header_t **
if (i < MAX_OPEN_HISTORIES)
{
- SVN_ERR(svn_fs_node_history(&info->hist, root, this_path, pool));
+ svn_error_t *err;
+ err = svn_fs_node_history(&info->hist, root, this_path, pool);
+ if (err
+ && ignore_missing_locations
+ && (err->apr_err == SVN_ERR_FS_NOT_FOUND ||
+ err->apr_err == SVN_ERR_FS_NOT_DIRECTORY ||
+ err->apr_err == SVN_ERR_FS_NO_SUCH_REVISION))
+ {
+ svn_error_clear(err);
+ continue;
+ }
+ SVN_ERR(err);
info->newpool = svn_pool_create(pool);
info->oldpool = svn_pool_create(pool);
}
@@ -1336,6 +1351,7 @@ do_logs(svn_fs_t *fs,
svn_boolean_t discover_changed_paths,
svn_boolean_t strict_node_history,
svn_boolean_t include_merged_revisions,
+ svn_boolean_t ignore_missing_locations,
const apr_array_header_t *revprops,
svn_boolean_t descending_order,
svn_log_entry_receiver_t receiver,
@@ -1383,24 +1399,15 @@ handle_merged_revisions(svn_revnum_t rev
iterpool = svn_pool_create(pool);
for (i = combined_list->nelts - 1; i >= 0; i--)
{
- svn_error_t *err;
struct path_list_range *pl_range
= APR_ARRAY_IDX(combined_list, i, struct path_list_range *);
svn_pool_clear(iterpool);
- err = do_logs(fs, pl_range->paths, pl_range->range.start,
- pl_range->range.end, 0, discover_changed_paths,
- strict_node_history, TRUE, revprops, TRUE,
- receiver, receiver_baton, authz_read_func,
- authz_read_baton, iterpool);
- if (err && (err->apr_err == SVN_ERR_FS_NOT_FOUND ||
- err->apr_err == SVN_ERR_FS_NOT_DIRECTORY ||
- err->apr_err == SVN_ERR_FS_NO_SUCH_REVISION))
- {
- svn_error_clear(err);
- continue;
- }
- SVN_ERR(err);
+ SVN_ERR(do_logs(fs, pl_range->paths, pl_range->range.start,
+ pl_range->range.end, 0, discover_changed_paths,
+ strict_node_history, TRUE, TRUE, revprops, TRUE,
+ receiver, receiver_baton, authz_read_func,
+ authz_read_baton, iterpool));
}
svn_pool_destroy(iterpool);
@@ -1415,6 +1422,9 @@ handle_merged_revisions(svn_revnum_t rev
the logs back as we find them, else buffer the logs and send them back
in youngest->oldest order.
+ If IGNORE_MISSING_LOCATIONS is set, don't treat requests for bogus
+ repository locations as fatal -- just ignore them.
+
Other parameters are the same as svn_repos_get_logs4().
*/
static svn_error_t *
@@ -1426,6 +1436,7 @@ do_logs(svn_fs_t *fs,
svn_boolean_t discover_changed_paths,
svn_boolean_t strict_node_history,
svn_boolean_t include_merged_revisions,
+ svn_boolean_t ignore_missing_locations,
const apr_array_header_t *revprops,
svn_boolean_t descending_order,
svn_log_entry_receiver_t receiver,
@@ -1448,8 +1459,8 @@ do_logs(svn_fs_t *fs,
one of our paths was changed. So let's go figure out which
revisions contain real changes to at least one of our paths. */
SVN_ERR(get_path_histories(&histories, fs, paths, hist_start, hist_end,
- strict_node_history, authz_read_func,
- authz_read_baton, pool));
+ strict_node_history, ignore_missing_locations,
+ authz_read_func, authz_read_baton, pool));
/* Loop through all the revisions in the range and add any
where a path was changed to the array, or if they wanted
@@ -1686,7 +1697,7 @@ svn_repos_get_logs4(svn_repos_t *repos,
return do_logs(repos->fs, paths, start, end, limit,
discover_changed_paths, strict_node_history,
- include_merged_revisions, revprops, descending_order,
- receiver, receiver_baton,
+ include_merged_revisions, FALSE, revprops,
+ descending_order, receiver, receiver_baton,
authz_read_func, authz_read_baton, pool);
}
Modified: subversion/branches/performance/subversion/libsvn_wc/adm_crawler.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/adm_crawler.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/adm_crawler.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/adm_crawler.c Sat Oct 30 14:20:17 2010
@@ -930,15 +930,6 @@ svn_wc_crawl_revisions5(svn_wc_context_t
if (err)
goto abort_report;
- if (!parent_repos_relpath)
- err = svn_wc__db_scan_base_repos(&parent_repos_relpath, NULL,
- NULL,
- db, parent_abspath,
- scratch_pool, scratch_pool);
-
- if (err)
- goto abort_report;
-
if (strcmp(repos_relpath,
svn_relpath_join(parent_repos_relpath, base,
scratch_pool)) != 0)
Modified: subversion/branches/performance/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/conflicts.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/conflicts.c Sat Oct 30 14:20:17 2010
@@ -166,6 +166,8 @@ attempt_deletion(const char *parent_dir,
### leave, for example, one of the conflict artifact files deleted but
### the entry still referring to it and trying to use it for the next
### attempt at resolving.
+
+ ### Does this still apply in the world of WC-NG? -hkw
*/
static svn_error_t *
resolve_conflict_on_node(svn_wc__db_t *db,
@@ -188,11 +190,7 @@ resolve_conflict_on_node(svn_wc__db_t *d
*did_resolve = FALSE;
- SVN_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, pool, pool));
+ SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, TRUE, pool));
SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, local_abspath,
pool, pool));
Modified: subversion/branches/performance/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/copy.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/copy.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/copy.c Sat Oct 30 14:20:17 2010
@@ -442,10 +442,14 @@ from one valid state to another and must
Several such changes can be batched together in a bigger txn if we don't
want clients to be able to see intermediate states.
-### TODO: This plan doesn't yet provide well for notification of all copied
- paths.
+TODO: We will probably want to notify all copied paths rather than just the
+ root path, some time in the future. It may be difficult to get the list
+ of visited paths directly, because the metadata copying is performed
+ within a single SQL statement. We could walk the destination tree after
+ copying, taking care to include any 'excluded' nodes but ignore any
+ 'deleted' paths that may be left over from a replaced sub-tree.
-copy-versioned_node:
+copy_versioned_node:
# Copy a versioned file/dir SRC_PATH to DST_PATH, recursively.
# This function takes care to copy both the metadata tree and the disk
@@ -475,6 +479,68 @@ copy-versioned_node:
# and so subsume the destination into an existing op? I guess not.
*/
+
+/* Copy a versioned file/dir SRC_PATH to DST_PATH, recursively. */
+static svn_error_t *
+copy_versioned_node(svn_wc__db_t *db,
+ const char *src_abspath,
+ const char *dst_abspath,
+ svn_boolean_t metadata_only,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ svn_wc_notify_func2_t notify_func,
+ void *notify_baton,
+ apr_pool_t *scratch_pool)
+{
+ svn_skel_t *work_item = NULL;
+
+ /* Prepare a copy of the on-disk tree (if it exists, and whatever its kind),
+ * in a temporary location. */
+ if (! metadata_only)
+ {
+ const char *tmpdir_abspath;
+ const char *tmp_dst_abspath;
+ svn_node_kind_t kind;
+
+ SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmpdir_abspath, db, dst_abspath,
+ scratch_pool, scratch_pool));
+
+ SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &kind, src_abspath,
+ tmpdir_abspath,
+ TRUE, /* recursive */
+ cancel_func, cancel_baton,
+ scratch_pool));
+ if (tmp_dst_abspath)
+ {
+ SVN_ERR(svn_wc__wq_build_file_move(&work_item, db,
+ tmp_dst_abspath, dst_abspath,
+ scratch_pool, scratch_pool));
+ }
+ }
+
+ /* Copy single NODES row from src_path@src_op_depth to dst_path@dst_depth. */
+ /* Copy all rows of descendent paths in == src_op_depth to == dst_depth. */
+ /* Copy all rows of descendent paths in > src_depth to > dst_depth,
+ adjusting op_depth by (dst_depth - src_depth). */
+ /* Copy ACTUAL_NODE rows (props and any other actual metadata). */
+ SVN_ERR(svn_wc__db_op_copy_tree(db, src_abspath, dst_abspath,
+ work_item, scratch_pool));
+
+ SVN_ERR(svn_wc__wq_run(db, dst_abspath, cancel_func, cancel_baton,
+ scratch_pool));
+
+ /* Notify */
+ if (notify_func)
+ {
+ svn_wc_notify_t *notify
+ = svn_wc_create_notify(dst_abspath, svn_wc_notify_add,
+ scratch_pool);
+ notify->kind = svn_node_dir;
+ (*notify_func)(notify_baton, notify, scratch_pool);
+ }
+
+ return SVN_NO_ERROR;
+}
#endif
@@ -494,7 +560,7 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
svn_wc__db_t *db = wc_ctx->db;
svn_wc__db_kind_t src_db_kind;
const char *dstdir_abspath;
-
+
SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath));
SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath));
@@ -645,6 +711,17 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
scratch_pool));
}
+#ifdef SVN_WC__OP_DEPTH
+ if (svn_wc__db_same_db(db, src_abspath, dst_abspath, scratch_pool))
+ {
+ SVN_ERR(copy_versioned_node(db, src_abspath, dst_abspath,
+ metadata_only,
+ cancel_func, cancel_baton,
+ notify_func, notify_baton,
+ scratch_pool));
+ }
+ else
+#endif
if (src_db_kind == svn_wc__db_kind_file
|| src_db_kind == svn_wc__db_kind_symlink)
{
Modified: subversion/branches/performance/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/props.c?rev=1029078&r1=1029077&r2=1029078&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/props.c Sat Oct 30 14:20:17 2010
@@ -1577,7 +1577,8 @@ svn_wc__merge_props(svn_wc_notify_state_
SVN_ERR(svn_wc__wq_tmp_build_set_property_conflict_marker(
&work_item,
db, local_abspath,
- svn_dirent_basename(reject_path, NULL),
+ svn_dirent_basename(reject_path,
+ NULL),
scratch_pool, scratch_pool));
SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, scratch_pool));