Return-Path: X-Original-To: apmail-subversion-commits-archive@minotaur.apache.org Delivered-To: apmail-subversion-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 8F0398DD8 for ; Wed, 24 Aug 2011 14:46:30 +0000 (UTC) Received: (qmail 42001 invoked by uid 500); 24 Aug 2011 14:46:30 -0000 Delivered-To: apmail-subversion-commits-archive@subversion.apache.org Received: (qmail 41941 invoked by uid 500); 24 Aug 2011 14:46:29 -0000 Mailing-List: contact commits-help@subversion.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@subversion.apache.org Delivered-To: mailing list commits@subversion.apache.org Received: (qmail 41934 invoked by uid 99); 24 Aug 2011 14:46:29 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 24 Aug 2011 14:46:29 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 24 Aug 2011 14:46:19 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 18854238888F for ; Wed, 24 Aug 2011 14:45:57 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1161134 [1/2] - in /subversion/branches/fs-py: ./ notes/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/include/ subversion/include/private/ subversion/libsvn_client/ subversion/l... Date: Wed, 24 Aug 2011 14:45:55 -0000 To: commits@subversion.apache.org From: hwright@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110824144557.18854238888F@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: hwright Date: Wed Aug 24 14:45:54 2011 New Revision: 1161134 URL: http://svn.apache.org/viewvc?rev=1161134&view=rev Log: On the fs-py branch: Bring up-to-date with trunk, in order to pick up an improve fs-pack test. Added: subversion/branches/fs-py/notes/diff-data-flows.txt - copied unchanged from r1161132, subversion/trunk/notes/diff-data-flows.txt subversion/branches/fs-py/subversion/tests/cmdline/upgrade_tests_data/upgrade_locked.tar.bz2 - copied unchanged from r1161132, subversion/trunk/subversion/tests/cmdline/upgrade_tests_data/upgrade_locked.tar.bz2 Modified: subversion/branches/fs-py/ (props changed) subversion/branches/fs-py/CHANGES subversion/branches/fs-py/subversion/bindings/javahl/native/CreateJ.cpp subversion/branches/fs-py/subversion/bindings/javahl/src/org/apache/subversion/javahl/CommitInfo.java subversion/branches/fs-py/subversion/include/private/svn_sqlite.h subversion/branches/fs-py/subversion/include/svn_wc.h subversion/branches/fs-py/subversion/libsvn_client/diff.c subversion/branches/fs-py/subversion/libsvn_client/merge.c subversion/branches/fs-py/subversion/libsvn_client/repos_diff.c subversion/branches/fs-py/subversion/libsvn_client/status.c subversion/branches/fs-py/subversion/libsvn_ra_svn/cyrus_auth.c subversion/branches/fs-py/subversion/libsvn_subr/cmdline.c subversion/branches/fs-py/subversion/libsvn_subr/magic.c subversion/branches/fs-py/subversion/libsvn_subr/svn_cache_config.c subversion/branches/fs-py/subversion/libsvn_subr/utf.c subversion/branches/fs-py/subversion/libsvn_wc/diff_local.c subversion/branches/fs-py/subversion/libsvn_wc/update_editor.c subversion/branches/fs-py/subversion/libsvn_wc/upgrade.c subversion/branches/fs-py/subversion/libsvn_wc/wc-queries.sql subversion/branches/fs-py/subversion/libsvn_wc/wc_db.c subversion/branches/fs-py/subversion/libsvn_wc/wc_db.h subversion/branches/fs-py/subversion/tests/cmdline/merge_authz_tests.py subversion/branches/fs-py/subversion/tests/cmdline/merge_reintegrate_tests.py subversion/branches/fs-py/subversion/tests/cmdline/merge_tests.py subversion/branches/fs-py/subversion/tests/cmdline/tree_conflict_tests.py subversion/branches/fs-py/subversion/tests/cmdline/upgrade_tests.py subversion/branches/fs-py/subversion/tests/libsvn_fs_fs/fs-pack-test.c subversion/branches/fs-py/tools/client-side/svnmucc/svnmucc.c Propchange: subversion/branches/fs-py/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Wed Aug 24 14:45:54 2011 @@ -32,6 +32,7 @@ /subversion/branches/issue-3242-dev:879653-896436 /subversion/branches/issue-3334-dirs:875156-875867 /subversion/branches/issue-3668-3669:1031000-1035744 +/subversion/branches/issue-3975:1152931-1160746 /subversion/branches/kwallet:870785-871314 /subversion/branches/log-g-performance:870941-871032 /subversion/branches/merge-skips-obstructions:874525-874615 @@ -54,4 +55,4 @@ /subversion/branches/tree-conflicts:868291-873154 /subversion/branches/tree-conflicts-notify:873926-874008 /subversion/branches/uris-as-urls:1060426-1064427 -/subversion/trunk:1154223-1160298 +/subversion/trunk:1154223-1161132 Modified: subversion/branches/fs-py/CHANGES URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/CHANGES?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/CHANGES (original) +++ subversion/branches/fs-py/CHANGES Wed Aug 24 14:45:54 2011 @@ -3,7 +3,6 @@ Version 1.8.0 http://svn.apache.org/repos/asf/subversion/tags/1.8.0 User-visible changes: - * don't leave unversioned files when reverting copies (issue #3101) Developer-visible changes: - API changes: @@ -29,7 +28,6 @@ the 1.6 release: http://subversion.apac - Minor new features and improvements: * Better handling of HTTP redirects (issue #2779) - * make Serf the default DAV access method, if available (r875974) * Improved and much more consistent path handling (issue #2028, and others) * 'svnadmin load' rewrites changed revnums in mergeinfo (issue #3020) * Error message and help text improvements @@ -54,6 +52,7 @@ the 1.6 release: http://subversion.apac * make server-side network data compression rate configurable (r1072288) * added support for auto-detecting mime-types with libmagic (r1131120) * 'svn rm url1 url2 url3' uses single txn per repo (issue #1199) + * don't leave unversioned files when reverting copies (issue #3101) - Client-side bugfixes: * 'svn cp A B; svn mv B C' is equivalent to 'svn cp A C' (issue #756) Modified: subversion/branches/fs-py/subversion/bindings/javahl/native/CreateJ.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/bindings/javahl/native/CreateJ.cpp?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/bindings/javahl/native/CreateJ.cpp (original) +++ subversion/branches/fs-py/subversion/bindings/javahl/native/CreateJ.cpp Wed Aug 24 14:45:54 2011 @@ -871,7 +871,8 @@ CreateJ::CommitInfo(const svn_commit_inf if (midCT == 0) { midCT = env->GetMethodID(clazz, "", - "(JLjava/lang/String;Ljava/lang/String;)V"); + "(JLjava/lang/String;Ljava/lang/String;" + "Ljava/lang/String;Ljava/lang/String;)V"); if (JNIUtil::isJavaExceptionThrown() || midCT == 0) POP_AND_RETURN_NULL; } @@ -886,8 +887,18 @@ CreateJ::CommitInfo(const svn_commit_inf jlong jRevision = commit_info->revision; + jstring jPostCommitError = JNIUtil::makeJString( + commit_info->post_commit_err); + if (JNIUtil::isJavaExceptionThrown()) + POP_AND_RETURN_NULL; + + jstring jReposRoot = JNIUtil::makeJString(commit_info->repos_root); + if (JNIUtil::isJavaExceptionThrown()) + POP_AND_RETURN_NULL; + // call the Java method - jobject jInfo = env->NewObject(clazz, midCT, jRevision, jDate, jAuthor); + jobject jInfo = env->NewObject(clazz, midCT, jRevision, jDate, jAuthor, + jPostCommitError, jReposRoot); if (JNIUtil::isJavaExceptionThrown()) POP_AND_RETURN_NULL; Modified: subversion/branches/fs-py/subversion/bindings/javahl/src/org/apache/subversion/javahl/CommitInfo.java URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/bindings/javahl/src/org/apache/subversion/javahl/CommitInfo.java?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/bindings/javahl/src/org/apache/subversion/javahl/CommitInfo.java (original) +++ subversion/branches/fs-py/subversion/bindings/javahl/src/org/apache/subversion/javahl/CommitInfo.java Wed Aug 24 14:45:54 2011 @@ -50,13 +50,21 @@ public class CommitInfo implements java. /** the author of the revision */ String author; + /** post commit error (or NULL) */ + String postCommitError; + + /** repos root (or NULL) */ + String reposRoot; + /** This constructor will be only called from the jni code. */ - public CommitInfo(long rev, String d, String a) + public CommitInfo(long rev, String d, String a, String pce, String rr) throws java.text.ParseException { revision = rev; date = (new LogDate(d)).getDate(); author = a; + postCommitError = pce; + reposRoot = rr; } /** @@ -82,4 +90,20 @@ public class CommitInfo implements java. { return author; } + + /** + * return any post commit error for the commit + */ + public String getPostCommitError() + { + return postCommitError; + } + + /** + * return the repos root + */ + public String getReposRoot() + { + return reposRoot; + } } Modified: subversion/branches/fs-py/subversion/include/private/svn_sqlite.h URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/include/private/svn_sqlite.h?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/include/private/svn_sqlite.h (original) +++ subversion/branches/fs-py/subversion/include/private/svn_sqlite.h Wed Aug 24 14:45:54 2011 @@ -373,13 +373,12 @@ svn_sqlite__with_immediate_transaction(s /* Helper function to handle several SQLite operations inside a shared lock. This callback is similar to svn_sqlite__with_transaction(), but can be - nested (even with a transaction) and changes in the callback are always - committed when this function returns. + nested (even with a transaction). - For SQLite 3.6.8 and later using this function as a wrapper around a group - of operations can give a *huge* performance boost as the shared-read lock - will be shared over multiple statements, instead of being reobtained - everytime, which requires disk and/or network io. + Using this function as a wrapper around a group of operations can give a + *huge* performance boost as the shared-read lock will be shared over + multiple statements, instead of being reobtained every time, which may + require disk and/or network io, depending on SQLite's locking strategy. SCRATCH_POOL will be passed to the callback (NULL is valid). Modified: subversion/branches/fs-py/subversion/include/svn_wc.h URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/include/svn_wc.h?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/include/svn_wc.h (original) +++ subversion/branches/fs-py/subversion/include/svn_wc.h Wed Aug 24 14:45:54 2011 @@ -2060,7 +2060,7 @@ svn_wc_create_conflict_result(svn_wc_con * * The values #svn_wc_conflict_choose_mine_conflict and * #svn_wc_conflict_choose_theirs_conflict are not legal for conflicts - * in binary files or properties. + * in binary files or binary properties. * * Implementations of this callback are free to present the conflict * using any user interface. This may include simple contextual Modified: subversion/branches/fs-py/subversion/libsvn_client/diff.c URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/diff.c?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/libsvn_client/diff.c (original) +++ subversion/branches/fs-py/subversion/libsvn_client/diff.c Wed Aug 24 14:45:54 2011 @@ -820,10 +820,9 @@ diff_props_changed(svn_wc_notify_state_t svn_boolean_t dir_was_added, const apr_array_header_t *propchanges, apr_hash_t *original_props, - void *diff_baton, + struct diff_cmd_baton *diff_cmd_baton, apr_pool_t *scratch_pool) { - struct diff_cmd_baton *diff_cmd_baton = diff_baton; apr_array_header_t *props; svn_boolean_t show_diff_header; @@ -891,7 +890,7 @@ diff_dir_props_changed(svn_wc_notify_sta dir_was_added, propchanges, original_props, - diff_baton, + diff_cmd_baton, scratch_pool)); } @@ -911,9 +910,8 @@ diff_content_changed(const char *path, svn_diff_operation_kind_t operation, const char *copyfrom_path, svn_revnum_t copyfrom_rev, - void *diff_baton) + struct diff_cmd_baton *diff_cmd_baton) { - struct diff_cmd_baton *diff_cmd_baton = diff_baton; int exitcode; apr_pool_t *subpool = svn_pool_create(diff_cmd_baton->pool); svn_stream_t *os; @@ -1105,6 +1103,7 @@ diff_file_changed(svn_wc_notify_state_t apr_pool_t *scratch_pool) { struct diff_cmd_baton *diff_cmd_baton = diff_baton; + if (diff_cmd_baton->anchor) path = svn_dirent_join(diff_cmd_baton->anchor, path, scratch_pool); if (tmpfile1) @@ -1112,11 +1111,11 @@ diff_file_changed(svn_wc_notify_state_t tmpfile1, tmpfile2, rev1, rev2, mimetype1, mimetype2, svn_diff_op_modified, NULL, - SVN_INVALID_REVNUM, diff_baton)); + SVN_INVALID_REVNUM, diff_cmd_baton)); if (prop_changes->nelts > 0) SVN_ERR(diff_props_changed(prop_state, tree_conflicted, path, FALSE, prop_changes, - original_props, diff_baton, scratch_pool)); + original_props, diff_cmd_baton, scratch_pool)); if (content_state) *content_state = svn_wc_notify_state_unknown; if (prop_state) @@ -1166,17 +1165,17 @@ diff_file_added(svn_wc_notify_state_t *c tmpfile1, tmpfile2, rev1, rev2, mimetype1, mimetype2, svn_diff_op_copied, copyfrom_path, - copyfrom_revision, diff_baton)); + copyfrom_revision, diff_cmd_baton)); else if (tmpfile1) SVN_ERR(diff_content_changed(path, tmpfile1, tmpfile2, rev1, rev2, mimetype1, mimetype2, svn_diff_op_added, NULL, SVN_INVALID_REVNUM, - diff_baton)); + diff_cmd_baton)); if (prop_changes->nelts > 0) SVN_ERR(diff_props_changed(prop_state, tree_conflicted, path, FALSE, prop_changes, - original_props, diff_baton, scratch_pool)); + original_props, diff_cmd_baton, scratch_pool)); if (content_state) *content_state = svn_wc_notify_state_unknown; if (prop_state) @@ -1224,7 +1223,7 @@ diff_file_deleted(svn_wc_notify_state_t diff_cmd_baton->revnum2, mimetype1, mimetype2, svn_diff_op_deleted, NULL, - SVN_INVALID_REVNUM, diff_baton)); + SVN_INVALID_REVNUM, diff_cmd_baton)); } /* We don't list all the deleted properties. */ Modified: subversion/branches/fs-py/subversion/libsvn_client/merge.c URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/merge.c?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/libsvn_client/merge.c (original) +++ subversion/branches/fs-py/subversion/libsvn_client/merge.c Wed Aug 24 14:45:54 2011 @@ -1346,6 +1346,67 @@ merge_file_opened(svn_boolean_t *tree_co return SVN_NO_ERROR; } + +/* Indicate in *MOVED_AWAY whether the node at LOCAL_ABSPATH was + * moved away locally. Do not raise an error if the node at LOCAL_ABSPATH + * does not exist. */ +static svn_error_t * +check_moved_away(svn_boolean_t *moved_away, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *scratch_pool) +{ + const char *moved_to_abspath; + svn_error_t *err; + + *moved_away = FALSE; + + err = svn_wc__node_was_moved_away(&moved_to_abspath, NULL, + wc_ctx, local_abspath, + scratch_pool, scratch_pool); + if (err) + { + if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND) + svn_error_clear(err); + else + return svn_error_trace(err); + } + else if (moved_to_abspath) + *moved_away = TRUE; + + return SVN_NO_ERROR; +} + +/* Indicate in *MOVED_HERE whether the node at LOCAL_ABSPATH was + * moved here locally. Do not raise an error if the node at LOCAL_ABSPATH + * does not exist. */ +static svn_error_t * +check_moved_here(svn_boolean_t *moved_here, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *scratch_pool) +{ + const char *moved_from_abspath; + svn_error_t *err; + + *moved_here = FALSE; + + err = svn_wc__node_was_moved_here(&moved_from_abspath, NULL, + wc_ctx, local_abspath, + scratch_pool, scratch_pool); + if (err) + { + if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND) + svn_error_clear(err); + else + return svn_error_trace(err); + } + else if (moved_from_abspath) + *moved_here = TRUE; + + return SVN_NO_ERROR; +} + /* An svn_wc_diff_callbacks4_t function. */ static svn_error_t * merge_file_changed(svn_wc_notify_state_t *content_state, @@ -1399,6 +1460,9 @@ merge_file_changed(svn_wc_notify_state_t way svn_wc_merge4() can do the merge. */ if (wc_kind != svn_node_file || is_deleted) { + svn_boolean_t moved_away; + svn_wc_conflict_reason_t reason; + /* Maybe the node is excluded via depth filtering? */ if (wc_kind == svn_node_none) @@ -1427,9 +1491,16 @@ merge_file_changed(svn_wc_notify_state_t /* This is use case 4 described in the paper attached to issue * #2282. See also notes/tree-conflicts/detection.txt */ + SVN_ERR(check_moved_away(&moved_away, merge_b->ctx->wc_ctx, + mine_abspath, scratch_pool)); + if (moved_away) + reason = svn_wc_conflict_reason_moved_away; + else if (is_deleted) + reason = svn_wc_conflict_reason_deleted; + else + reason = svn_wc_conflict_reason_missing; SVN_ERR(tree_conflict(merge_b, mine_abspath, svn_node_file, - svn_wc_conflict_action_edit, - svn_wc_conflict_reason_missing)); + svn_wc_conflict_action_edit, reason)); if (tree_conflicted) *tree_conflicted = TRUE; if (content_state) @@ -1696,14 +1767,21 @@ merge_file_added(svn_wc_notify_state_t * merge_b->pool)); if (existing_conflict) { + svn_boolean_t moved_here; + svn_wc_conflict_reason_t reason; + /* Possibly collapse the existing conflict into a 'replace' * tree conflict. The conflict reason is 'added' because * the now-deleted tree conflict victim must have been * added in the history of the merge target. */ + SVN_ERR(check_moved_here(&moved_here, merge_b->ctx->wc_ctx, + mine_abspath, scratch_pool)); + reason = moved_here ? svn_wc_conflict_reason_moved_here + : svn_wc_conflict_reason_added; SVN_ERR(tree_conflict_on_add(merge_b, mine_abspath, svn_node_file, svn_wc_conflict_action_add, - svn_wc_conflict_reason_added)); + reason)); if (tree_conflicted) *tree_conflicted = TRUE; } @@ -1769,14 +1847,20 @@ merge_file_added(svn_wc_notify_state_t * } else { + svn_boolean_t moved_here; + svn_wc_conflict_reason_t reason; + /* The file add the merge wants to carry out is obstructed by * a versioned file. This file must have been added in the * history of the merge target, hence we flag a tree conflict * with reason 'added'. */ + SVN_ERR(check_moved_here(&moved_here, merge_b->ctx->wc_ctx, + mine_abspath, scratch_pool)); + reason = moved_here ? svn_wc_conflict_reason_moved_here + : svn_wc_conflict_reason_added; SVN_ERR(tree_conflict_on_add( merge_b, mine_abspath, svn_node_file, - svn_wc_conflict_action_add, - svn_wc_conflict_reason_added)); + svn_wc_conflict_action_add, reason)); if (tree_conflicted) *tree_conflicted = TRUE; @@ -1883,6 +1967,8 @@ merge_file_deleted(svn_wc_notify_state_t { merge_cmd_baton_t *merge_b = baton; svn_node_kind_t kind; + svn_boolean_t moved_away; + svn_wc_conflict_reason_t reason; if (merge_b->dry_run) { @@ -1975,9 +2061,12 @@ merge_file_deleted(svn_wc_notify_state_t * This is use case 6 described in the paper attached to issue * #2282. See also notes/tree-conflicts/detection.txt */ + SVN_ERR(check_moved_away(&moved_away, merge_b->ctx->wc_ctx, + mine_abspath, scratch_pool)); + reason = moved_away ? svn_wc_conflict_reason_moved_away + : svn_wc_conflict_reason_deleted; SVN_ERR(tree_conflict(merge_b, mine_abspath, svn_node_file, - svn_wc_conflict_action_delete, - svn_wc_conflict_reason_deleted)); + svn_wc_conflict_action_delete, reason)); if (tree_conflicted) *tree_conflicted = TRUE; if (state) @@ -2142,11 +2231,18 @@ merge_dir_added(svn_wc_notify_state_t *s } else { + svn_boolean_t moved_here; + svn_wc_conflict_reason_t reason; + /* This is a tree conflict. */ + SVN_ERR(check_moved_here(&moved_here, merge_b->ctx->wc_ctx, + local_abspath, scratch_pool)); + reason = moved_here ? svn_wc_conflict_reason_moved_here + : svn_wc_conflict_reason_added; SVN_ERR(tree_conflict_on_add(merge_b, local_abspath, svn_node_dir, svn_wc_conflict_action_add, - svn_wc_conflict_reason_added)); + reason)); if (tree_conflicted) *tree_conflicted = TRUE; if (state) @@ -2202,6 +2298,9 @@ merge_dir_deleted(svn_wc_notify_state_t svn_error_t *err; svn_boolean_t is_versioned; svn_boolean_t is_deleted; + svn_boolean_t moved_away; + svn_wc_conflict_reason_t reason; + /* Easy out: We are only applying mergeinfo differences. */ if (merge_b->record_only) @@ -2286,9 +2385,12 @@ merge_dir_deleted(svn_wc_notify_state_t { /* Dir is already not under version control at this path. */ /* Raise a tree conflict. */ + SVN_ERR(check_moved_away(&moved_away, merge_b->ctx->wc_ctx, + local_abspath, scratch_pool)); + reason = moved_away ? svn_wc_conflict_reason_moved_away + : svn_wc_conflict_reason_deleted; SVN_ERR(tree_conflict(merge_b, local_abspath, svn_node_dir, - svn_wc_conflict_action_delete, - svn_wc_conflict_reason_deleted)); + svn_wc_conflict_action_delete, reason)); if (tree_conflicted) *tree_conflicted = TRUE; } @@ -2302,9 +2404,12 @@ merge_dir_deleted(svn_wc_notify_state_t /* Dir is already non-existent. This is use case 6 as described in * notes/tree-conflicts/detection.txt. * This case was formerly treated as no-op. */ + SVN_ERR(check_moved_away(&moved_away, merge_b->ctx->wc_ctx, + local_abspath, scratch_pool)); + reason = moved_away ? svn_wc_conflict_reason_moved_away + : svn_wc_conflict_reason_deleted; SVN_ERR(tree_conflict(merge_b, local_abspath, svn_node_dir, - svn_wc_conflict_action_delete, - svn_wc_conflict_reason_deleted)); + svn_wc_conflict_action_delete, reason)); if (tree_conflicted) *tree_conflicted = TRUE; if (state) @@ -2399,9 +2504,15 @@ merge_dir_opened(svn_boolean_t *tree_con * forcing the user to sanity-check the merge result. */ else if (is_deleted || wc_kind == svn_node_none) { + svn_boolean_t moved_away; + svn_wc_conflict_reason_t reason; + + SVN_ERR(check_moved_away(&moved_away, merge_b->ctx->wc_ctx, + local_abspath, scratch_pool)); + reason = moved_away ? svn_wc_conflict_reason_moved_away + : svn_wc_conflict_reason_deleted; SVN_ERR(tree_conflict(merge_b, local_abspath, svn_node_dir, - svn_wc_conflict_action_edit, - svn_wc_conflict_reason_deleted)); + svn_wc_conflict_action_edit, reason)); if (tree_conflicted) *tree_conflicted = TRUE; } @@ -4480,7 +4591,8 @@ populate_remaining_ranges(apr_array_head /* Helper for record_mergeinfo_for_dir_merge(). Adjust, in place, the inheritability of the ranges in RANGELIST to - describe a merge of RANGELIST into WC_WCPATH at depth DEPTH. + describe a merge of RANGELIST into WC_WCPATH at depth DEPTH. Set + *RANGELIST_INHERITANCE to the inheritability set. WC_PATH_IS_MERGE_TARGET is true if WC_PATH is the target of the merge, otherwise WC_PATH is a subtree. @@ -4492,6 +4604,7 @@ populate_remaining_ranges(apr_array_head Perform any temporary allocations in SCRATCH_POOL. */ static svn_error_t * calculate_merge_inheritance(apr_array_header_t *rangelist, + svn_boolean_t *rangelist_inheritance, const char *local_abspath, svn_boolean_t wc_path_is_merge_target, svn_boolean_t wc_path_has_missing_child, @@ -4503,6 +4616,10 @@ calculate_merge_inheritance(apr_array_he SVN_ERR(svn_wc_read_kind(&path_kind, wc_ctx, local_abspath, FALSE, scratch_pool)); + + /* Starting assumption. */ + *rangelist_inheritance = TRUE; + if (path_kind == svn_node_file) { /* Files *never* have non-inheritable mergeinfo. */ @@ -4515,17 +4632,27 @@ calculate_merge_inheritance(apr_array_he if (wc_path_has_missing_child || depth == svn_depth_files || depth == svn_depth_empty) - svn_rangelist__set_inheritance(rangelist, FALSE); + { + svn_rangelist__set_inheritance(rangelist, FALSE); + *rangelist_inheritance = FALSE; + } else /* depth == svn_depth_files || depth == svn_depth_empty */ - svn_rangelist__set_inheritance(rangelist, TRUE); + { + svn_rangelist__set_inheritance(rangelist, TRUE); + } } else /* WC_PATH is a directory subtree of the target. */ { if (wc_path_has_missing_child || depth == svn_depth_immediates) - svn_rangelist__set_inheritance(rangelist, FALSE); + { + svn_rangelist__set_inheritance(rangelist, FALSE); + *rangelist_inheritance = FALSE; + } else /* depth == infinity */ - svn_rangelist__set_inheritance(rangelist, TRUE); + { + svn_rangelist__set_inheritance(rangelist, TRUE); + } } } return SVN_NO_ERROR; @@ -7600,6 +7727,7 @@ record_mergeinfo_for_dir_merge(svn_merge else /* Record mergeinfo on CHILD. */ { svn_boolean_t child_is_deleted; + svn_boolean_t rangelist_inheritance; /* If CHILD is deleted we don't need to set mergeinfo on it. */ SVN_ERR(svn_wc__node_is_status_deleted(&child_is_deleted, @@ -7662,6 +7790,7 @@ record_mergeinfo_for_dir_merge(svn_merge continue; SVN_ERR(calculate_merge_inheritance(child_merge_rangelist, + &rangelist_inheritance, child->abspath, i == 0, child->missing_child, @@ -7695,6 +7824,66 @@ record_mergeinfo_for_dir_merge(svn_merge } child_merges = apr_hash_make(iterpool); + + /* If CHILD is the merge target we then know that the mergeinfo + described by MERGE_SOURCE_PATH:MERGED_RANGE->START- + MERGED_RANGE->END describes existent path-revs in the repository, + see normalize_merge_sources() and the global comment + 'MERGEINFO MERGE SOURCE NORMALIZATION'. + + If CHILD is a subtree of the merge target however, then no such + guarantee holds. The mergeinfo described by + (MERGE_SOURCE_PATH + CHILD_REPOS_PATH):MERGED_RANGE->START- + MERGED_RANGE->END might contain merge sources which don't + exist or refer to unrelated lines of history. */ + if (i > 0 + && (!merge_b->record_only || merge_b->reintegrate_merge) + && (!is_rollback)) + { + svn_opt_revision_t peg_revision; + svn_mergeinfo_t subtree_history_as_mergeinfo; + apr_array_header_t *child_merge_src_rangelist; + const char *old_session_url; + const char *subtree_mergeinfo_url = + svn_path_url_add_component2(merge_b->repos_root_url, + child_merge_src_canon_path + 1, + iterpool); + + /* Confirm that the naive mergeinfo we want to set on + CHILD->ABSPATH both exists and is part of + (MERGE_SOURCE_PATH+CHILD_REPOS_PATH)@MERGED_RANGE->END's + history. */ + peg_revision.kind = svn_opt_revision_number; + + /* We know MERGED_RANGE->END is younger than MERGE_RANGE->START + because we only do this for forward merges. */ + peg_revision.value.number = merged_range->end; + SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url, + merge_b->ra_session2, + subtree_mergeinfo_url, + iterpool)); + SVN_ERR(svn_client__get_history_as_mergeinfo( + &subtree_history_as_mergeinfo, NULL, + subtree_mergeinfo_url, &peg_revision, + MAX(merged_range->start, merged_range->end), + MIN(merged_range->start, merged_range->end), + merge_b->ra_session2, merge_b->ctx, iterpool)); + + if (old_session_url) + SVN_ERR(svn_ra_reparent(merge_b->ra_session2, + old_session_url, iterpool)); + child_merge_src_rangelist = apr_hash_get( + subtree_history_as_mergeinfo, + child_merge_src_canon_path, + APR_HASH_KEY_STRING); + SVN_ERR(svn_rangelist_intersect(&child_merge_rangelist, + child_merge_rangelist, + child_merge_src_rangelist, + FALSE, iterpool)); + if (!rangelist_inheritance) + svn_rangelist__set_inheritance(child_merge_rangelist, FALSE); + } + apr_hash_set(child_merges, child->abspath, APR_HASH_KEY_STRING, child_merge_rangelist); SVN_ERR(update_wc_mergeinfo(result_catalog, @@ -7750,8 +7939,9 @@ record_mergeinfo_for_dir_merge(svn_merge Record mergeinfo describing a merge of MERGED_RANGE->START:MERGED_RANGE->END from the repository relative path - MERGEINFO_PATH to each path in NOTIFY_B->ADDED_ABSPATHS which is the - immediate child of a parent with explicit non-inheritable mergeinfo. + MERGEINFO_PATH to each path in NOTIFY_B->ADDED_ABSPATHS which has explicit + mergeinfo or is the immediate child of a parent with explicit + non-inheritable mergeinfo. DEPTH, NOTIFY_B, MERGE_B, and SQUELCH_MERGEINFO_NOTIFICATIONS, are cascaded from do_directory_merge's arguments of the same names. @@ -7785,34 +7975,48 @@ record_mergeinfo_for_added_subtrees( const char *added_abspath = svn__apr_hash_index_key(hi); const char *dir_abspath; svn_mergeinfo_t parent_mergeinfo; + svn_mergeinfo_t added_path_mergeinfo; svn_boolean_t inherited; /* used multiple times, but ignored */ apr_pool_clear(iterpool); dir_abspath = svn_dirent_dirname(added_abspath, iterpool); - /* Does ADDED_ABSPATH's immediate parent have non-inheritable - mergeinfo? */ - SVN_ERR(svn_client__get_wc_mergeinfo(&parent_mergeinfo, &inherited, + /* Grab the added path's explicit mergeinfo. */ + SVN_ERR(svn_client__get_wc_mergeinfo(&added_path_mergeinfo, &inherited, svn_mergeinfo_explicit, - dir_abspath, NULL, NULL, FALSE, - merge_b->ctx, - iterpool, iterpool)); - if (svn_mergeinfo__is_noninheritable(parent_mergeinfo, iterpool)) + added_abspath, NULL, NULL, FALSE, + merge_b->ctx, iterpool, iterpool)); + + /* If the added path doesn't have explicit mergeinfo, does its immediate + parent have non-inheritable mergeinfo? */ + if (!added_path_mergeinfo) + SVN_ERR(svn_client__get_wc_mergeinfo(&parent_mergeinfo, &inherited, + svn_mergeinfo_explicit, + dir_abspath, NULL, NULL, FALSE, + merge_b->ctx, + iterpool, iterpool)); + + if (added_path_mergeinfo + || svn_mergeinfo__is_noninheritable(parent_mergeinfo, iterpool)) { svn_client__merge_path_t *target_merge_path = APR_ARRAY_IDX(notify_b->children_with_mergeinfo, 0, svn_client__merge_path_t *); svn_merge_range_t *rng; svn_node_kind_t added_path_kind; - svn_mergeinfo_t merge_mergeinfo, added_path_mergeinfo; + svn_mergeinfo_t merge_mergeinfo; + svn_mergeinfo_t adds_history_as_mergeinfo; apr_array_header_t *rangelist; const char *rel_added_path; const char *added_path_mergeinfo_path; + const char *old_session_url; + const char *added_path_mergeinfo_url; + svn_opt_revision_t peg_revision; SVN_ERR(svn_wc_read_kind(&added_path_kind, merge_b->ctx->wc_ctx, added_abspath, FALSE, iterpool)); - /* Calculate the mergeinfo resulting from this merge. */ + /* Calculate the naive mergeinfo describing the merge. */ merge_mergeinfo = apr_hash_make(iterpool); rangelist = apr_array_make(iterpool, 1, sizeof(svn_merge_range_t *)); rng = svn_merge_range_dup(merged_range, iterpool); @@ -7839,14 +8043,46 @@ record_mergeinfo_for_added_subtrees( apr_hash_set(merge_mergeinfo, added_path_mergeinfo_path, APR_HASH_KEY_STRING, rangelist); - /* Get any explicit mergeinfo the added path has. */ - SVN_ERR(svn_client__get_wc_mergeinfo( - &added_path_mergeinfo, &inherited, - svn_mergeinfo_explicit, added_abspath, - NULL, NULL, FALSE, merge_b->ctx, iterpool, iterpool)); + /* Don't add new mergeinfo to describe the merge if that mergeinfo + contains non-existent merge sources. + + We know that MERGEINFO_PATH/rel_added_path's history does not + span MERGED_RANGE->START:MERGED_RANGE->END but rather that it + was added at some revions greater than MERGED_RANGE->START + (assuming this is a forward merge). It may have been added, + deleted, and re-added many times. The point is that we cannot + blindly apply the naive mergeinfo calculated above because it + will describe non-existent merge sources. To avoid this we get + take the intersection of the naive mergeinfo with + MERGEINFO_PATH/rel_added_path's history. */ + added_path_mergeinfo_url = + svn_path_url_add_component2(merge_b->repos_root_url, + added_path_mergeinfo_path + 1, + iterpool); + peg_revision.kind = svn_opt_revision_number; + peg_revision.value.number = MAX(merged_range->start, + merged_range->end); + SVN_ERR(svn_client__ensure_ra_session_url( + &old_session_url, merge_b->ra_session2, + added_path_mergeinfo_url, iterpool)); + SVN_ERR(svn_client__get_history_as_mergeinfo( + &adds_history_as_mergeinfo, NULL, + added_path_mergeinfo_url, &peg_revision, + MAX(merged_range->start, merged_range->end), + MIN(merged_range->start, merged_range->end), + merge_b->ra_session2, merge_b->ctx, iterpool)); + + if (old_session_url) + SVN_ERR(svn_ra_reparent(merge_b->ra_session2, + old_session_url, iterpool)); + + SVN_ERR(svn_mergeinfo_intersect2(&merge_mergeinfo, + merge_mergeinfo, + adds_history_as_mergeinfo, + FALSE, iterpool, iterpool)); /* Combine the explict mergeinfo on the added path (if any) - with the mergeinfo for this merge. */ + with the mergeinfo describing this merge. */ if (added_path_mergeinfo) SVN_ERR(svn_mergeinfo_merge(merge_mergeinfo, added_path_mergeinfo, iterpool)); Modified: subversion/branches/fs-py/subversion/libsvn_client/repos_diff.c URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/repos_diff.c?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/libsvn_client/repos_diff.c (original) +++ subversion/branches/fs-py/subversion/libsvn_client/repos_diff.c Wed Aug 24 14:45:54 2011 @@ -486,9 +486,6 @@ open_root(void *edit_baton, struct edit_baton *eb = edit_baton; struct dir_baton *b = make_dir_baton("", NULL, eb, FALSE, pool); - /* Override the wcpath in our baton. */ - b->wcpath = apr_pstrdup(pool, eb->target); - SVN_ERR(get_dirprops_from_ra(b, base_revision)); *root_baton = b; Modified: subversion/branches/fs-py/subversion/libsvn_client/status.c URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/status.c?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/libsvn_client/status.c (original) +++ subversion/branches/fs-py/subversion/libsvn_client/status.c Wed Aug 24 14:45:54 2011 @@ -85,6 +85,7 @@ tweak_status(void *baton, /* If the status item has an entry, but doesn't belong to one of the changelists our caller is interested in, we filter out this status transmission. */ + /* ### duplicated in ../libsvn_wc/diff_local.c */ if (sb->changelist_hash) { if (status->changelist) Modified: subversion/branches/fs-py/subversion/libsvn_ra_svn/cyrus_auth.c URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_svn/cyrus_auth.c?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/libsvn_ra_svn/cyrus_auth.c (original) +++ subversion/branches/fs-py/subversion/libsvn_ra_svn/cyrus_auth.c Wed Aug 24 14:45:54 2011 @@ -28,7 +28,6 @@ #include #include #include -#include #include #include Modified: subversion/branches/fs-py/subversion/libsvn_subr/cmdline.c URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/cmdline.c?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/libsvn_subr/cmdline.c (original) +++ subversion/branches/fs-py/subversion/libsvn_subr/cmdline.c Wed Aug 24 14:45:54 2011 @@ -37,7 +37,6 @@ #include /* for apr_strerror */ #include /* for apr_initialize/apr_terminate */ -#include /* for apr_atomic_init */ #include /* for apr_snprintf */ #include Modified: subversion/branches/fs-py/subversion/libsvn_subr/magic.c URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/magic.c?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/libsvn_subr/magic.c (original) +++ subversion/branches/fs-py/subversion/libsvn_subr/magic.c Wed Aug 24 14:45:54 2011 @@ -45,8 +45,9 @@ struct svn_magic__cookie_t { #ifdef SVN_HAVE_LIBMAGIC magic_t magic; -#endif +#else char dummy; +#endif }; #ifdef SVN_HAVE_LIBMAGIC Modified: subversion/branches/fs-py/subversion/libsvn_subr/svn_cache_config.c URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/svn_cache_config.c?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/libsvn_subr/svn_cache_config.c (original) +++ subversion/branches/fs-py/subversion/libsvn_subr/svn_cache_config.c Wed Aug 24 14:45:54 2011 @@ -147,6 +147,9 @@ svn_cache__get_global_membuffer_cache(vo /* Handle race condition: if we are the first to create a * cache object, make it our global singleton. Otherwise, * discard the new cache and keep the existing one. + * + * Cast is necessary because of APR bug: + * https://issues.apache.org/bugzilla/show_bug.cgi?id=50731 */ old_cache = apr_atomic_casptr((volatile void **)&cache, new_cache, NULL); if (old_cache != NULL) Modified: subversion/branches/fs-py/subversion/libsvn_subr/utf.c URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_subr/utf.c?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/libsvn_subr/utf.c (original) +++ subversion/branches/fs-py/subversion/libsvn_subr/utf.c Wed Aug 24 14:45:54 2011 @@ -90,8 +90,8 @@ static apr_hash_t *xlate_handle_hash = N * using atomic xchange ops, i.e. without further thread synchronization. * If the respective item is NULL, fallback to hash lookup. */ -static volatile void *xlat_ntou_static_handle = NULL; -static volatile void *xlat_uton_static_handle = NULL; +static void * volatile xlat_ntou_static_handle = NULL; +static void * volatile xlat_uton_static_handle = NULL; /* Clean up the xlate handle cache. */ static apr_status_t @@ -182,11 +182,13 @@ get_xlate_key(const char *topage, * the caller. */ static APR_INLINE void* -atomic_swap(volatile void **mem, void *new_value) +atomic_swap(void * volatile * mem, void *new_value) { #if APR_HAS_THREADS #if APR_VERSION_AT_LEAST(1,3,0) - return apr_atomic_xchgptr(mem, new_value); + /* Cast is necessary because of APR bug: + https://issues.apache.org/bugzilla/show_bug.cgi?id=50731 */ + return apr_atomic_xchgptr((volatile void **)mem, new_value); #else /* old APRs don't support atomic swaps. Simply return the * input to the caller for further proccessing. */ Modified: subversion/branches/fs-py/subversion/libsvn_wc/diff_local.c URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_wc/diff_local.c?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/libsvn_wc/diff_local.c (original) +++ subversion/branches/fs-py/subversion/libsvn_wc/diff_local.c Wed Aug 24 14:45:54 2011 @@ -445,11 +445,25 @@ diff_status_callback(void *baton, break; /* Go check other conditions */ } - if (eb->changelist_hash != NULL - && (!status->changelist - || ! apr_hash_get(eb->changelist_hash, status->changelist, - APR_HASH_KEY_STRING))) - return SVN_NO_ERROR; /* Filtered via changelist */ + /* Filter items by changelist. */ + /* ### duplicated in ../libsvn_client/status.c */ + if (eb->changelist_hash) + { + if (status->changelist) + { + /* Skip unless the caller requested this changelist. */ + if (! apr_hash_get(eb->changelist_hash, status->changelist, + APR_HASH_KEY_STRING)) + return SVN_NO_ERROR; + } + else + { + /* Skip unless the caller requested changelist-lacking items. */ + if (! apr_hash_get(eb->changelist_hash, "", + APR_HASH_KEY_STRING)) + return SVN_NO_ERROR; + } + } /* ### The following checks should probably be reversed as it should decide when *not* to show a diff, because generally all changed nodes should Modified: subversion/branches/fs-py/subversion/libsvn_wc/update_editor.c URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_wc/update_editor.c?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/libsvn_wc/update_editor.c (original) +++ subversion/branches/fs-py/subversion/libsvn_wc/update_editor.c Wed Aug 24 14:45:54 2011 @@ -699,6 +699,10 @@ struct file_baton /* Absolute path to this file */ const char *local_abspath; + /* Absolute path to the new location of the file if it was moved away. + * If the file was not moved away, this is NULL. */ + const char *moved_to_abspath; + /* The repository relative path this file will correspond to. */ const char *new_relpath; @@ -775,7 +779,6 @@ make_file_baton(struct file_baton **f_p, { struct edit_baton *eb = pb->edit_baton; apr_pool_t *file_pool = svn_pool_create(pb->pool); - struct file_baton *f = apr_pcalloc(file_pool, sizeof(*f)); SVN_ERR_ASSERT(path); @@ -1454,6 +1457,7 @@ check_tree_conflict(svn_wc_conflict_desc svn_wc_conflict_action_t action, svn_node_kind_t their_node_kind, const char *their_relpath, + const char *moved_to_abspath, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { @@ -1521,20 +1525,8 @@ check_tree_conflict(svn_wc_conflict_desc case svn_wc__db_status_deleted: - { - const char *moved_to_abspath; - - /* The node is locally deleted. Check if it was moved away. - * ### should scan_deletion return status_moved_away, like - * ### scan_addition returns status_moved_here? */ - SVN_ERR(svn_wc__db_scan_deletion(NULL, &moved_to_abspath, NULL, - NULL, eb->db, local_abspath, - scratch_pool, scratch_pool)); - if (moved_to_abspath) - reason = svn_wc_conflict_reason_moved_away; - else - reason = svn_wc_conflict_reason_deleted; - } + if (!moved_to_abspath) + reason = svn_wc_conflict_reason_deleted; break; case svn_wc__db_status_incomplete: @@ -1825,7 +1817,7 @@ delete_entry(const char *path, SVN_ERR(check_tree_conflict(&tree_conflict, eb, local_abspath, status, kind, TRUE, svn_wc_conflict_action_delete, svn_node_none, - repos_relpath, pb->pool, scratch_pool)); + repos_relpath, NULL, pb->pool, scratch_pool)); } if (tree_conflict != NULL) @@ -2183,7 +2175,7 @@ add_directory(const char *path, status, wc_kind, FALSE, svn_wc_conflict_action_add, svn_node_dir, db->new_relpath, - pool, pool)); + NULL, pool, pool)); } if (tree_conflict == NULL) @@ -2375,7 +2367,7 @@ open_directory(const char *path, SVN_ERR(check_tree_conflict(&tree_conflict, eb, db->local_abspath, status, wc_kind, TRUE, svn_wc_conflict_action_edit, svn_node_dir, - db->new_relpath, db->pool, pool)); + db->new_relpath, NULL, db->pool, pool)); /* Remember the roots of any locally deleted trees. */ if (tree_conflict != NULL) @@ -3209,7 +3201,7 @@ add_file(const char *path, fb->local_abspath, status, wc_kind, FALSE, svn_wc_conflict_action_add, - svn_node_file, fb->new_relpath, + svn_node_file, fb->new_relpath, NULL, scratch_pool, scratch_pool)); } @@ -3342,6 +3334,12 @@ open_file(const char *path, eb->db, fb->local_abspath, fb->pool, scratch_pool)); + /* If the file has moved locally look up its new location. */ + if (status == svn_wc__db_status_deleted) + SVN_ERR(svn_wc__db_scan_deletion(NULL, &fb->moved_to_abspath, NULL, NULL, + eb->db, fb->local_abspath, + fb->pool, scratch_pool)); + /* Is this path a conflict victim? */ if (conflicted) SVN_ERR(node_already_conflicted(&conflicted, eb->db, @@ -3369,7 +3367,8 @@ open_file(const char *path, SVN_ERR(check_tree_conflict(&tree_conflict, eb, fb->local_abspath, status, wc_kind, TRUE, svn_wc_conflict_action_edit, svn_node_file, - fb->new_relpath, fb->pool, scratch_pool)); + fb->new_relpath, fb->moved_to_abspath, + fb->pool, scratch_pool)); /* Is this path the victim of a newly-discovered tree conflict? */ if (tree_conflict != NULL) @@ -3714,6 +3713,8 @@ merge_file(svn_skel_t **work_items, svn_boolean_t is_locally_modified; enum svn_wc_merge_outcome_t merge_outcome = svn_wc_merge_unchanged; svn_skel_t *work_item; + const char *working_abspath = fb->moved_to_abspath ? fb->moved_to_abspath + : fb->local_abspath; SVN_ERR_ASSERT(! fb->shadowed && !fb->obstruction_found); @@ -3758,7 +3759,7 @@ merge_file(svn_skel_t **work_items, files that do not exist and for directories. */ SVN_ERR(svn_wc__internal_file_modified_p(&is_locally_modified, - eb->db, fb->local_abspath, + eb->db, working_abspath, FALSE /* exact_comparison */, scratch_pool)); } @@ -3802,7 +3803,7 @@ merge_file(svn_skel_t **work_items, SVN_ERR(svn_wc__perform_file_merge(work_items, &merge_outcome, eb->db, - fb->local_abspath, + working_abspath, pb->local_abspath, fb->new_text_base_sha1_checksum, fb->add_existed @@ -3834,7 +3835,7 @@ merge_file(svn_skel_t **work_items, SVN_ERR(svn_wc__get_translate_info(NULL, NULL, &keywords, NULL, - eb->db, fb->local_abspath, + eb->db, working_abspath, actual_props, TRUE, scratch_pool, scratch_pool)); if (magic_props_changed || keywords) @@ -3854,7 +3855,7 @@ merge_file(svn_skel_t **work_items, /* Copy and DEtranslate the working file to a temp text-base. Note that detranslation is done according to the old props. */ SVN_ERR(svn_wc__internal_translated_file( - &tmptext, fb->local_abspath, eb->db, fb->local_abspath, + &tmptext, working_abspath, eb->db, working_abspath, SVN_WC_TRANSLATE_TO_NF | SVN_WC_TRANSLATE_NO_OUTPUT_CLEANUP, eb->cancel_func, eb->cancel_baton, @@ -3896,7 +3897,7 @@ merge_file(svn_skel_t **work_items, } SVN_ERR(svn_wc__wq_build_record_fileinfo(&work_item, - eb->db, fb->local_abspath, + eb->db, working_abspath, set_date, result_pool, scratch_pool)); *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool); @@ -3951,6 +3952,9 @@ close_file(void *file_baton, svn_skel_t *work_item; apr_pool_t *scratch_pool = fb->pool; /* Destroyed at function exit */ svn_boolean_t keep_recorded_info = FALSE; + const svn_checksum_t *new_checksum; + const char *working_abspath = fb->moved_to_abspath ? fb->moved_to_abspath + : fb->local_abspath; if (fb->skip_this) { @@ -4041,7 +4045,7 @@ close_file(void *file_baton, if ((!fb->adding_file || fb->add_existed) && !fb->shadowed) SVN_ERR(svn_wc__get_actual_props(&local_actual_props, - eb->db, fb->local_abspath, + eb->db, working_abspath, scratch_pool, scratch_pool)); if (local_actual_props == NULL) local_actual_props = apr_hash_make(scratch_pool); @@ -4119,7 +4123,7 @@ close_file(void *file_baton, svn_wc__db_status_added, svn_wc__db_kind_file, TRUE, svn_wc_conflict_action_add, - svn_node_file, fb->new_relpath, + svn_node_file, fb->new_relpath, NULL, scratch_pool, scratch_pool)); SVN_ERR_ASSERT(tree_conflict != NULL); SVN_ERR(svn_wc__db_op_set_tree_conflict(eb->db, @@ -4149,7 +4153,7 @@ close_file(void *file_baton, &new_base_props, &new_actual_props, eb->db, - fb->local_abspath, + working_abspath, svn_wc__db_kind_file, NULL /* left_version */, NULL /* right_version */, @@ -4181,7 +4185,7 @@ close_file(void *file_baton, if (eb->notify_func) { svn_wc_notify_t *notify =svn_wc_create_notify( - fb->local_abspath, + working_abspath, svn_wc_notify_update_skip_access_denied, scratch_pool); @@ -4228,7 +4232,7 @@ close_file(void *file_baton, SVN_ERR(svn_wc__wq_build_file_install(&work_item, eb->db, - fb->local_abspath, + working_abspath, install_from, eb->use_commit_times, record_fileinfo, @@ -4244,7 +4248,7 @@ close_file(void *file_baton, Note: this will also update the executable flag, but ... meh. */ SVN_ERR(svn_wc__wq_build_sync_file_flags(&work_item, eb->db, - fb->local_abspath, + working_abspath, scratch_pool, scratch_pool)); all_work_items = svn_wc__wq_merge(all_work_items, work_item, scratch_pool); @@ -4262,7 +4266,7 @@ close_file(void *file_baton, /* Remove the INSTALL_FROM file, as long as it doesn't refer to the working file. */ if (install_from != NULL - && strcmp(install_from, fb->local_abspath) != 0) + && strcmp(install_from, working_abspath) != 0) { SVN_ERR(svn_wc__wq_build_file_remove(&work_item, eb->db, install_from, @@ -4313,43 +4317,62 @@ close_file(void *file_baton, } /* Insert/replace the BASE node with all of the new metadata. */ - { - /* Set the 'checksum' column of the file's BASE_NODE row to - * NEW_TEXT_BASE_SHA1_CHECKSUM. The pristine text identified by that - * checksum is already in the pristine store. */ - const svn_checksum_t *new_checksum = fb->new_text_base_sha1_checksum; - - /* If we don't have a NEW checksum, then the base must not have changed. - Just carry over the old checksum. */ - if (new_checksum == NULL) - new_checksum = fb->original_checksum; - - SVN_ERR(svn_wc__db_base_add_file(eb->db, fb->local_abspath, - eb->wcroot_abspath, - fb->new_relpath, - eb->repos_root, eb->repos_uuid, - *eb->target_revision, - new_base_props, - fb->changed_rev, - fb->changed_date, - fb->changed_author, - new_checksum, - (dav_prop_changes->nelts > 0) - ? svn_prop_array_to_hash( - dav_prop_changes, - scratch_pool) - : NULL, - NULL /* conflict */, - (! fb->shadowed) && new_base_props, - new_actual_props, - keep_recorded_info, - (fb->shadowed && fb->obstruction_found), - all_work_items, - scratch_pool)); - } + + /* Set the 'checksum' column of the file's BASE_NODE row to + * NEW_TEXT_BASE_SHA1_CHECKSUM. The pristine text identified by that + * checksum is already in the pristine store. */ + new_checksum = fb->new_text_base_sha1_checksum; + + /* If we don't have a NEW checksum, then the base must not have changed. + Just carry over the old checksum. */ + if (new_checksum == NULL) + new_checksum = fb->original_checksum; + + SVN_ERR(svn_wc__db_base_add_file(eb->db, fb->local_abspath, + eb->wcroot_abspath, + fb->new_relpath, + eb->repos_root, eb->repos_uuid, + *eb->target_revision, + new_base_props, + fb->changed_rev, + fb->changed_date, + fb->changed_author, + new_checksum, + (dav_prop_changes->nelts > 0) + ? svn_prop_array_to_hash( + dav_prop_changes, + scratch_pool) + : NULL, + NULL /* conflict */, + (! fb->shadowed) && new_base_props, + new_actual_props, + keep_recorded_info, + (fb->shadowed && fb->obstruction_found), + all_work_items, + scratch_pool)); /* Deal with the WORKING tree, based on updates to the BASE tree. */ + if (fb->moved_to_abspath) + { + /* Perform another in-DB move of the file to sync meta-data + * of the moved-away node with the new BASE node. */ + SVN_ERR(svn_wc__db_op_copy_file(eb->db, fb->moved_to_abspath, + new_actual_props, + fb->changed_rev, + fb->changed_date, + fb->changed_author, + fb->new_relpath, + eb->repos_root, + eb->repos_uuid, + *eb->target_revision, + new_checksum, + TRUE /* is_move */, + NULL /* conflict */, + NULL, /* no work, just modify DB */ + scratch_pool)); + } + /* If this file was locally-added and is now being added by the update, we can toss the local-add, turning this into a local-edit. If the local file is replaced, we don't want to touch ACTUAL. */ @@ -4383,7 +4406,10 @@ close_file(void *file_baton, action = svn_wc_notify_update_add; } - notify = svn_wc_create_notify(fb->local_abspath, action, scratch_pool); + /* If the file was moved-away, notify for the moved-away node. + * The original location only had its BASE info changed and + * we don't usually notify about such changes. */ + notify = svn_wc_create_notify(working_abspath, action, scratch_pool); notify->kind = svn_node_file; notify->content_state = content_state; notify->prop_state = prop_state; @@ -5459,6 +5485,7 @@ svn_wc_add_repos_file4(svn_wc_context_t original_uuid, copyfrom_rev, new_text_base_sha1_checksum, + FALSE /* is_move */, NULL /* conflict */, NULL /* work_items */, pool)); Modified: subversion/branches/fs-py/subversion/libsvn_wc/upgrade.c URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_wc/upgrade.c?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/libsvn_wc/upgrade.c (original) +++ subversion/branches/fs-py/subversion/libsvn_wc/upgrade.c Wed Aug 24 14:45:54 2011 @@ -1914,12 +1914,12 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx, scratch_pool)); SVN_ERR(svn_wc__ensure_directory(root_adm_abspath, scratch_pool)); - /* Create an empty sqlite database for this directory. */ + /* Create an empty sqlite database for this directory and store it in DB. */ SVN_ERR(svn_wc__db_upgrade_begin(&data.sdb, &data.repos_id, &data.wc_id, - data.root_abspath, + db, data.root_abspath, this_dir->repos, this_dir->uuid, - scratch_pool, scratch_pool)); + scratch_pool)); /* Migrate the entries over to the new database. ### We need to think about atomicity here. @@ -1964,7 +1964,6 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx, SVN_ERR(svn_wc__db_wq_add(db, data.root_abspath, work_items, scratch_pool)); SVN_ERR(svn_wc__db_wclock_release(db, data.root_abspath, scratch_pool)); - SVN_ERR(svn_sqlite__close(data.sdb)); SVN_ERR(svn_wc__db_close(db)); /* Renaming the db file is what makes the pre-wcng into a wcng */ Modified: subversion/branches/fs-py/subversion/libsvn_wc/wc-queries.sql URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_wc/wc-queries.sql?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/libsvn_wc/wc-queries.sql (original) +++ subversion/branches/fs-py/subversion/libsvn_wc/wc-queries.sql Wed Aug 24 14:45:54 2011 @@ -166,9 +166,9 @@ INSERT OR REPLACE INTO nodes ( wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path, revision, presence, depth, kind, changed_revision, changed_date, changed_author, checksum, properties, translated_size, last_mod_time, - dav_cache, symlink_target, file_external, moved_to) + dav_cache, symlink_target, file_external, moved_to, moved_here) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, - ?15, ?16, ?17, ?18, ?19, ?20, ?21) + ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22) -- STMT_SELECT_OP_DEPTH_CHILDREN SELECT local_relpath FROM nodes Modified: subversion/branches/fs-py/subversion/libsvn_wc/wc_db.c URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_wc/wc_db.c?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/libsvn_wc/wc_db.c (original) +++ subversion/branches/fs-py/subversion/libsvn_wc/wc_db.c Wed Aug 24 14:45:54 2011 @@ -1018,7 +1018,7 @@ insert_working_node(void *baton, SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_INSERT_NODE)); SVN_ERR(svn_sqlite__bindf(stmt, "isisnnntstrisn" "nnnn" /* properties translated_size last_mod_time dav_cache */ - "s", + "snni", /* symlink_target, file_external, moved_to, moved_here */ wcroot->wc_id, local_relpath, piwb->op_depth, parent_relpath, @@ -1031,7 +1031,8 @@ insert_working_node(void *baton, piwb->changed_author, /* Note: incomplete nodes may have a NULL target. */ (piwb->kind == svn_wc__db_kind_symlink) - ? piwb->target : NULL)); + ? piwb->target : NULL, + (apr_int64_t)piwb->moved_here)); if (piwb->kind == svn_wc__db_kind_file) { @@ -4250,6 +4251,7 @@ svn_wc__db_op_copy_file(svn_wc__db_t *db const char *original_uuid, svn_revnum_t original_revision, const svn_checksum_t *checksum, + svn_boolean_t is_move, const svn_skel_t *conflict, const svn_skel_t *work_items, apr_pool_t *scratch_pool) @@ -4282,7 +4284,7 @@ svn_wc__db_op_copy_file(svn_wc__db_t *db iwb.changed_rev = changed_rev; iwb.changed_date = changed_date; iwb.changed_author = changed_author; - iwb.moved_here = FALSE; + iwb.moved_here = is_move; if (original_root_url != NULL) { @@ -5303,7 +5305,6 @@ op_revert_txn(void *baton, STMT_CLEAR_MOVED_TO_RELPATH)); SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath)); SVN_ERR(svn_sqlite__step_done(stmt)); - SVN_ERR(svn_sqlite__reset(stmt)); } SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, @@ -5414,13 +5415,20 @@ op_revert_recursive_txn(void *baton, while (have_row) { const char *moved_here_child_relpath; + svn_error_t *err; svn_pool_clear(iterpool); moved_here_child_relpath = svn_sqlite__column_text(stmt, 0, iterpool); - SVN_ERR(clear_moved_to(moved_here_child_relpath, wcroot, iterpool)); + err = clear_moved_to(moved_here_child_relpath, wcroot, iterpool); + if (err) + return svn_error_trace(svn_error_compose_create( + err, + svn_sqlite__reset(stmt))); + SVN_ERR(svn_sqlite__step(&have_row, stmt)); } + SVN_ERR(svn_sqlite__reset(stmt)); svn_pool_destroy(iterpool); /* Clear potential moved-to pointing at the target node itself. */ @@ -5433,7 +5441,6 @@ op_revert_recursive_txn(void *baton, STMT_CLEAR_MOVED_TO_RELPATH_RECURSIVE)); SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath)); SVN_ERR(svn_sqlite__step_done(stmt)); - SVN_ERR(svn_sqlite__reset(stmt)); return SVN_NO_ERROR; } @@ -6191,6 +6198,27 @@ info_below_working(svn_boolean_t *have_b return SVN_NO_ERROR; } +/* Helper function for op_delete_txn */ +static svn_error_t * +delete_update_movedto(svn_wc__db_wcroot_t *wcroot, + const char *child_moved_from_relpath, + const char *new_moved_to_relpath, + apr_pool_t *scratch_pool) +{ + svn_sqlite__stmt_t *stmt; + + SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, + STMT_UPDATE_MOVED_TO_RELPATH)); + + SVN_ERR(svn_sqlite__bindf(stmt, "iss", + wcroot->wc_id, + child_moved_from_relpath, + new_moved_to_relpath)); + SVN_ERR(svn_sqlite__step_done(stmt)); + + return SVN_NO_ERROR; +} + struct op_delete_baton_t { apr_int64_t delete_depth; /* op-depth for root of delete */ @@ -6267,7 +6295,6 @@ op_delete_txn(void *baton, SVN_ERR(svn_sqlite__bindf(stmt, "iss", wcroot->wc_id, moved_from_relpath, b->moved_to_relpath)); SVN_ERR(svn_sqlite__step_done(stmt)); - SVN_ERR(svn_sqlite__reset(stmt)); } /* If a subtree is being moved-away, we need to update moved-to @@ -6332,7 +6359,6 @@ op_delete_txn(void *baton, { const char *child_subtree_relpath; const char *new_moved_to_relpath; - svn_sqlite__stmt_t *moved_to_stmt; /* Compute the new moved-to path for this child... */ child_subtree_relpath = @@ -6344,15 +6370,14 @@ op_delete_txn(void *baton, svn_relpath_join(b->moved_to_relpath, child_subtree_relpath, iterpool); /* ... and update the BASE moved-to record. */ - SVN_ERR(svn_sqlite__get_statement( - &moved_to_stmt, wcroot->sdb, - STMT_UPDATE_MOVED_TO_RELPATH)); - SVN_ERR(svn_sqlite__bindf(moved_to_stmt, "iss", - wcroot->wc_id, - child_moved_from_relpath, - new_moved_to_relpath)); - SVN_ERR(svn_sqlite__step(&have_row, moved_to_stmt)); - SVN_ERR(svn_sqlite__reset(moved_to_stmt)); + err = delete_update_movedto(wcroot, child_moved_from_relpath, + new_moved_to_relpath, + scratch_pool); + + if (err) + return svn_error_trace(svn_error_compose_create( + err, + svn_sqlite__reset(stmt))); } SVN_ERR(svn_sqlite__step(&have_row, stmt)); @@ -10128,16 +10153,30 @@ svn_error_t * svn_wc__db_upgrade_begin(svn_sqlite__db_t **sdb, apr_int64_t *repos_id, apr_int64_t *wc_id, + svn_wc__db_t *wc_db, const char *dir_abspath, const char *repos_root_url, const char *repos_uuid, - apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - return svn_error_trace(create_db(sdb, repos_id, wc_id, dir_abspath, - repos_root_url, repos_uuid, - SDB_FILE, - result_pool, scratch_pool)); + svn_wc__db_wcroot_t *wcroot; + SVN_ERR(create_db(sdb, repos_id, wc_id, dir_abspath, + repos_root_url, repos_uuid, + SDB_FILE, + wc_db->state_pool, scratch_pool)); + + SVN_ERR(svn_wc__db_pdh_create_wcroot(&wcroot, + apr_pstrdup(wc_db->state_pool, + dir_abspath), + *sdb, *wc_id, FORMAT_FROM_SDB, + FALSE /* auto-upgrade */, + FALSE /* enforce_empty_wq */, + wc_db->state_pool, scratch_pool)); + + /* The WCROOT is complete. Stash it into DB. */ + apr_hash_set(wc_db->dir_data, wcroot->abspath, APR_HASH_KEY_STRING, wcroot); + + return SVN_NO_ERROR; } Modified: subversion/branches/fs-py/subversion/libsvn_wc/wc_db.h URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_wc/wc_db.h?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/libsvn_wc/wc_db.h (original) +++ subversion/branches/fs-py/subversion/libsvn_wc/wc_db.h Wed Aug 24 14:45:54 2011 @@ -1281,6 +1281,7 @@ svn_wc__db_op_copy_file(svn_wc__db_t *db const char *original_uuid, svn_revnum_t original_revision, const svn_checksum_t *checksum, + svn_boolean_t is_move, const svn_skel_t *conflict, const svn_skel_t *work_items, apr_pool_t *scratch_pool); @@ -2605,14 +2606,20 @@ svn_wc__db_scan_deletion(const char **ba @{ */ +/* Create a new wc.db file for LOCAL_DIR_ABSPATH, which is going to be a + working copy for the repository REPOS_ROOT_URL with uuid REPOS_UUID. + Return the raw sqlite handle, repository id and working copy id + and store the database in WC_DB. + + Perform temporary allocations in SCRATCH_POOL. */ svn_error_t * svn_wc__db_upgrade_begin(svn_sqlite__db_t **sdb, apr_int64_t *repos_id, apr_int64_t *wc_id, + svn_wc__db_t *wc_db, const char *local_dir_abspath, const char *repos_root_url, const char *repos_uuid, - apr_pool_t *result_pool, apr_pool_t *scratch_pool); Modified: subversion/branches/fs-py/subversion/tests/cmdline/merge_authz_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/cmdline/merge_authz_tests.py?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/tests/cmdline/merge_authz_tests.py (original) +++ subversion/branches/fs-py/subversion/tests/cmdline/merge_authz_tests.py Wed Aug 24 14:45:54 2011 @@ -420,7 +420,7 @@ def mergeinfo_and_skipped_paths(sbox): props={SVN_PROP_MERGEINFO : '/A/D/H/omega:8-9'}), 'chi' : Item("This is the file 'chi'.\n"), 'zeta' : Item("This is the file 'zeta'.\n", - props={SVN_PROP_MERGEINFO : '/A/D/H/zeta:8-9'}), + props={SVN_PROP_MERGEINFO : '/A/D/H/zeta:9'}), }) expected_skip = wc.State(A_COPY_2_H_path, {}) svntest.actions.run_and_verify_merge(A_COPY_2_H_path, '7', '9', Modified: subversion/branches/fs-py/subversion/tests/cmdline/merge_reintegrate_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/cmdline/merge_reintegrate_tests.py?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/tests/cmdline/merge_reintegrate_tests.py (original) +++ subversion/branches/fs-py/subversion/tests/cmdline/merge_reintegrate_tests.py Wed Aug 24 14:45:54 2011 @@ -486,22 +486,9 @@ def reintegrate_with_rename(sbox): "" : Item(status=' M', wc_rev=9), }) k_expected_disk.tweak('', props={SVN_PROP_MERGEINFO : '/A_COPY:2-9'}) - - # Why do we expect mergeinfo of '/A_COPY/D/G/tauprime:2-9' on - # A/D/G/tauprime? Because this --reintegrate merge is effectively a - # two URL merge of %URL%/A@9 %URL%/A_COPY@9 to 'A'. Since %URL%/A@9 and - # %URL%/A_COPY@9 have a common ancestor in %URL%/A@1 we expect this 2-URL - # merge to record mergeinfo and a component of that mergeinfo describes - # the merge of %URL%/A_COPY@2 to %URL%/A_COPY@9. We see that above on - # A. But we also get it on A's subtrees with explicit mergeinfo, namely - # A/D/G/tauprime. Now I know what you are thinking, "'A_COPY/D/G/tauprime' - # doesn't even exist until r9!", and you are quite right. But this - # inheritance of bogus mergeinfo is a known problem, see - # http://subversion.tigris.org/issues/show_bug.cgi?id=3157#desc8, - # and is not what this test is about, so we won't fail because of it. k_expected_disk.add({ 'D/G/tauprime' : Item(props={SVN_PROP_MERGEINFO : - '/A/D/G/tau:2-7\n/A_COPY/D/G/tauprime:2-9'}, + '/A/D/G/tau:2-7\n/A_COPY/D/G/tauprime:9'}, contents="This is the file 'tau'.\n") }) expected_skip = wc.State(A_path, {}) @@ -1269,7 +1256,8 @@ def reintegrate_with_subtree_mergeinfo(s 'A ' + gamma_moved_COPY_path + '\n', 'D ' + gamma_COPY_path + '\n', ' U ' + A_COPY_path + '\n', - ' U ' + D_COPY_path + '\n',]), + ' U ' + D_COPY_path + '\n', + ' U ' + gamma_moved_COPY_path + '\n']), [], 'merge', sbox.repo_url + '/A', A_COPY_path) expected_output = wc.State( wc_dir, @@ -1339,7 +1327,7 @@ def reintegrate_with_subtree_mergeinfo(s '' : Item(status=' U'), 'mu' : Item(status=' G'), 'D' : Item(status=' U'), - 'D/gamma_moved' : Item(status=' G'), + 'D/gamma_moved' : Item(status=' U'), }) expected_elision_output = wc.State(A_path, { }) @@ -1385,8 +1373,7 @@ def reintegrate_with_subtree_mergeinfo(s 'D/G/tau' : Item("This is the file 'tau'.\n"), 'D/gamma_moved' : Item( "Even newer content", props={SVN_PROP_MERGEINFO : - '/A/D/gamma_moved:2-15\n' - '/A_COPY/D/gamma_moved:2-19\n' + '/A_COPY/D/gamma_moved:17-19\n' '/A_COPY_3/D/gamma:9'}), 'D/H' : Item(), 'D/H/chi' : Item("This is the file 'chi'.\n"), @@ -2024,7 +2011,7 @@ def added_subtrees_with_mergeinfo_break_ 'C' : Item(), 'C/nu' : Item("Trunk work on nu.\n", props={SVN_PROP_MERGEINFO : - '/A_COPY/C/nu:16-18\n' + '/A_COPY/C/nu:13,16-18\n' '/A_COPY_2/C/nu:10'}), # <-- From cyclic # merge in r11 'D' : Item(), Modified: subversion/branches/fs-py/subversion/tests/cmdline/merge_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/tests/cmdline/merge_tests.py?rev=1161134&r1=1161133&r2=1161134&view=diff ============================================================================== --- subversion/branches/fs-py/subversion/tests/cmdline/merge_tests.py (original) +++ subversion/branches/fs-py/subversion/tests/cmdline/merge_tests.py Wed Aug 24 14:45:54 2011 @@ -7681,7 +7681,7 @@ def merge_away_subtrees_noninheritable_r expected_output = svntest.verify.UnorderedOutput( [A_COPY_path + ' - /A:2-13*\n', mu_COPY_path + ' - /A/mu:2-13\n', - nu_COPY_path + ' - /A/nu:2-13\n',]) + nu_COPY_path + ' - /A/nu:10-13\n',]) svntest.actions.run_and_verify_svn(None, expected_output, [], 'pg', SVN_PROP_MERGEINFO, @@ -11582,24 +11582,7 @@ def dont_explicitly_record_implicit_merg svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir) wc_status.tweak(wc_rev=10) - # Now do a cherry harvest merge to 'A_copy'. We should pick up the - # change to 'A_copy/D/H/nu' from r10, the mergeinfo on 'A_copy' should - # reflect the entire eligible revision range from 'A', r2-10. - # 'A_copy/D/H/nu' should have get the equivalent mergeinfo to 'A_copy' - # which should elide to the latter, leaving no explicit mergeinfo... - # - # ...or should it? For the mergeinfo on ' A_copy/D/H/nu' to elide, it - # needs mergeinfo '/A/D/H/nu:2-10', but 'A/D/H/nu' doesn't exist prior to - # r6...Anyhow, regardless of what the mergeinfo on ' A_copy/D/H/nu' should - # be prior to elision, if we have the following conditions: - # - # 1) A uniform working revision merge target. - # - # 2) Explicit mergeinfo on the target/subtrees from the same - # source ('A' in this case). - # - # Then a cherry harvest from the same source should leave explicit - # mergeinfo *only* on the merge target no? + # Now do a cherry harvest merge to 'A_copy'. expected_output = wc.State(A_copy_path, { 'D/H/nu' : Item(status='U '), }) @@ -11608,7 +11591,6 @@ def dont_explicitly_record_implicit_merg 'D/H/nu' : Item(status=' U'), }) expected_elision_output = wc.State(A_copy_path, { - 'D/H/nu' : Item(status=' U'), }) expected_A_copy_status = wc.State(A_copy_path, { '' : Item(status=' M', wc_rev=10), @@ -11652,7 +11634,8 @@ def dont_explicitly_record_implicit_merg 'D/H/chi' : Item("This is the file 'chi'.\n"), 'D/H/psi' : Item("This is the file 'psi'.\n"), 'D/H/omega' : Item("This is the file 'omega'.\n"), - 'D/H/nu' : Item("Even nuer content"), + 'D/H/nu' : Item("Even nuer content", + props={SVN_PROP_MERGEINFO : '/A/D/H/nu:6-10'}), }) expected_A_copy_skip = wc.State(A_copy_path, {}) svntest.actions.run_and_verify_merge(A_copy_path, None, None, @@ -13957,7 +13940,7 @@ def no_self_referential_filtering_on_add 'B/E/beta' : Item("New content"), 'B/lambda' : Item("This is the file 'lambda'.\n"), 'B/F' : Item(), - 'C_MOVED' : Item(props={SVN_PROP_MERGEINFO : '/A/C_MOVED:3-10\n' + + 'C_MOVED' : Item(props={SVN_PROP_MERGEINFO : '/A/C_MOVED:10\n' + '/A_COPY/C:8\n' + '/A_COPY/C_MOVED:8', 'propname' : 'propval'}), @@ -16711,7 +16694,6 @@ def foreign_repos_prop_conflict(sbox): #---------------------------------------------------------------------- # Test for issue #3975 'adds with explicit mergeinfo don't get mergeinfo # describing merge which added them' -@XFail() @Issue(3975) @SkipUnless(server_has_mergeinfo) def merge_adds_subtree_with_mergeinfo(sbox): @@ -16767,7 +16749,8 @@ def merge_adds_subtree_with_mergeinfo(sb '' : Item(status=' U'), }) expected_mergeinfo_output = wc.State(A_COPY2_path, { - '' : Item(status=' G'), + '' : Item(status=' G'), + 'C/nu' : Item(status=' U'), }) expected_elision_output = wc.State(A_COPY2_path, { }) @@ -16805,15 +16788,11 @@ def merge_adds_subtree_with_mergeinfo(sb 'B/lambda' : Item("This is the file 'lambda'.\n"), 'B/F' : Item(), 'C' : Item(), - # Currently this test fails because A_COPY_2/C/nu gets no - # mergeinfo set on it to describe the merge, it only has - # the explicit mergeinfo from its copy source (i.e. /A_COPY/C/nu:10 - # from ^/A/C/nu@11. 'C/nu' : Item("This is the file 'nu'.\n" \ "More work on the A_COPY branch.\n" \ "A faux conflict resolution.\n", props={SVN_PROP_MERGEINFO : - '\/A/C/nu:9-11n/A_COPY/C/nu:10'}), + '/A/C/nu:9-11\n/A_COPY/C/nu:10'}), 'D' : Item(), 'D/G' : Item(), 'D/G/pi' : Item("This is the file 'pi'.\n"),