'Daniel Shahaf' wrote on Mon, Mar 28, 2011 at 00:16:49 +0200:
> Bert Huijben wrote on Sun, Mar 27, 2011 at 19:26:50 +0200:
> > and there are easier (and more
> > performant) ways to check if a node is part of a working copy (e.g. helpers
> > to check if a path is switched/a wc root).
>
> Could you elaborate on these please? I looked through the header files
> and amn't sure which helpers you're referring to.
New patch, including your previous feedbacks modulo the above point:
[[[
Resolve issue #3469 (tree conflict under a directory external).
Review by: rhuijben
* subversion/libsvn_client/merge.c
(merge_cmd_baton_t): Add TARGET_WCROOT_ABSPATH member.
(do_merge): Initialize new member.
(merge_file_added):
Skip files that belong to externals or to disjoint working copies.
Exploit knowledge of libsvn_wc implementations details (queries on
directories are faster) to make the check cheaper.
TODO: remove @XFail decorator
(from tree_conflict_tests.py 22)
]]]
[[[
Index: subversion/libsvn_client/merge.c
===================================================================
--- subversion/libsvn_client/merge.c (revision 1086475)
+++ subversion/libsvn_client/merge.c (working copy)
@@ -249,6 +249,8 @@ typedef struct merge_cmd_baton_t {
versioned dir (dry-run only) */
const char *target_abspath; /* Absolute working copy target of
the merge. */
+ const char *target_wcroot_abspath; /* Absolute path to root of wc that
+ TARGET_ABSPATH belongs to. */
/* The left and right URLs and revs. The value of this field changes to
reflect the merge_source_t *currently* being merged by do_merge(). */
@@ -1555,6 +1557,32 @@ merge_file_added(const char *local_dir_abspath,
if (tree_conflicted)
*tree_conflicted = FALSE;
+ /* Easy out: not the same working copy. (So, a disjoint working copy or
+ an external.) */
+ {
+ const char *mine_wcroot_abspath;
+
+ /* ### White-box optimization:
+
+ The code knows that MINE_ABSPATH is not a directory (it's an added
+ file), and we know that internally libsvn_wc queries are faster for
+ directories (this is an implementation detail). Therefore, query for
+ the wcroot of the containing directory of MINE_ABSPATH.
+
+ (We rely on the implementation detail only for performance, not for
+ correctness; under any implementation it would be valid to query for
+ the parent's wcroot.)
+ */
+ SVN_ERR(svn_wc_get_wc_root(&mine_wcroot_abspath, merge_b->ctx->wc_ctx,
+ svn_dirent_dirname(mine_abspath, scratch_pool),
+ scratch_pool, scratch_pool));
+ if (strcmp(mine_wcroot_abspath, merge_b->target_wcroot_abspath))
+ {
+ *content_state = svn_wc_notify_state_obstructed;
+ return SVN_NO_ERROR;
+ }
+ }
+
/* Apply the prop changes to a new hash table. */
file_props = apr_hash_copy(subpool, original_props);
for (i = 0; i < prop_changes->nelts; ++i)
@@ -8653,6 +8685,9 @@ do_merge(apr_hash_t **modified_subtrees,
merge_cmd_baton.target_missing_child = FALSE;
merge_cmd_baton.reintegrate_merge = reintegrate_merge;
merge_cmd_baton.target_abspath = target_abspath;
+ SVN_ERR(svn_wc_get_wc_root(&merge_cmd_baton.target_wcroot_abspath,
+ ctx->wc_ctx, merge_cmd_baton.target_abspath,
+ pool, subpool));
merge_cmd_baton.pool = subpool;
merge_cmd_baton.merge_options = merge_options;
merge_cmd_baton.diff3_cmd = diff3_cmd;
]]]
Received on 2011-03-29 08:02:53 CEST