On Tue, May 24, 2011 at 12:35 PM, <stsp_at_apache.org> wrote:
> Author: stsp
> Date: Tue May 24 16:35:14 2011
> New Revision: 1127134
>
> URL: http://svn.apache.org/viewvc?rev=1127134&view=rev
> Log:
> As part of issue #3779, "actual-only nodes need regression tests",
> make 'svn add' detect tree conflict victims that do not exist on disk
> and prevent adding new nodes at that path with a meaningful error message.
>
> This implies that if users need to add a new node to resolve the conflict
> they need to mark the conflict as resolved first. I think this is safer
> than allowing accidental additions to take place. Since the node is not
> visible on disk the addition might be a mistake.
>
> * subversion/libsvn_wc/adm_ops.c
> (check_can_add_node): Don't allow adding new items on top of nonexistent
> conflicted nodes.
>
> * subversion/libsvn_client/add.c
> (add): As previous.
>
> * subversion/tests/cmdline/tree_conflict_tests.py
> (actual_only_node_behaviour): Adjust test cases for 'add' and 'mkdir'.
>
> Modified:
> subversion/trunk/subversion/libsvn_client/add.c
> subversion/trunk/subversion/libsvn_wc/adm_ops.c
> subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py
>
> Modified: subversion/trunk/subversion/libsvn_client/add.c
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/add.c?rev=1127134&r1=1127133&r2=1127134&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/libsvn_client/add.c (original)
> +++ subversion/trunk/subversion/libsvn_client/add.c Tue May 24 16:35:14 2011
> @@ -537,10 +537,29 @@ add(void *baton, apr_pool_t *result_pool
> else if (kind == svn_node_file)
> err = add_file(b->local_abspath, b->ctx, scratch_pool);
> else if (kind == svn_node_none)
> - return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
> - _("'%s' not found"),
> - svn_dirent_local_style(b->local_abspath,
> - scratch_pool));
> + {
> + svn_boolean_t tree_conflicted;
> +
> + /* Provide a meaningful error message if the node does not exist
> + * on disk but is a tree conflict victim. */
> + err = svn_wc_conflicted_p3(NULL, NULL, &tree_conflicted,
> + b->ctx->wc_ctx, b->local_abspath,
> + scratch_pool);
> + if (err)
> + svn_error_clear(err);
> + else if (tree_conflicted)
> + return svn_error_createf(SVN_ERR_WC_FOUND_CONFLICT, NULL,
> + _("'%s' is an existing item in conflict; "
> + "please mark the conflict as resolved "
> + "before adding a new item here"),
> + svn_dirent_local_style(b->local_abspath,
> + scratch_pool));
> + return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
> + _("'%s' not found"),
> + svn_dirent_local_style(b->local_abspath,
> + scratch_pool));
> + }
> else
> return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
> _("Unsupported node kind for path '%s'"),
>
> Modified: subversion/trunk/subversion/libsvn_wc/adm_ops.c
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_ops.c?rev=1127134&r1=1127133&r2=1127134&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/libsvn_wc/adm_ops.c (original)
> +++ subversion/trunk/subversion/libsvn_wc/adm_ops.c Tue May 24 16:35:14 2011
> @@ -849,10 +849,12 @@ check_can_add_node(svn_node_kind_t *kind
> adding the new node; if not, return an error. */
> {
> svn_wc__db_status_t status;
> + svn_boolean_t conflicted;
> svn_error_t *err
> = svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL,
> NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> - NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> + NULL, NULL, NULL, NULL, NULL, NULL,
> + &conflicted,
> NULL, NULL, NULL, NULL, NULL, NULL,
> db, local_abspath,
> scratch_pool, scratch_pool);
> @@ -870,6 +872,16 @@ check_can_add_node(svn_node_kind_t *kind
> {
> is_wc_root = FALSE;
> exists = TRUE;
> +
> + /* Note that the node may be in conflict even if it does not
> + * exist on disk (certain tree conflict scenarios). */
> + if (conflicted)
> + return svn_error_createf(SVN_ERR_WC_FOUND_CONFLICT, NULL,
> + _("'%s' is an existing item in conflict; "
> + "please mark the conflict as resolved "
> + "before adding a new item here"),
> + svn_dirent_local_style(local_abspath,
> + scratch_pool));
Hi Stefan,
While reviewing some outstanding merge-related issues I noticed that
this change breaks the use-case of incoming replacements on local
deletes. The delete portion of the replacement is handled and a
tree-conflict set by the time the add is done and the above error is
raised.
Here's a quick demonstration starting with a vanilla Greek tree:
### Make a branch:
>svn copy ^^/A ^^/branch -m "Create a branch"
Committed revision 2.
### Replace a directory on the "trunk":
>svn del A\C
D A\C
>svn mkdir A\C
A A\C
>svn ci -m "Replace A/C"
Replacing A\C
Committed revision 3.
### Delete the corresponding directory on the "branch":
>svn del ^^/branch/C -m "Delete branch/C"
Committed revision 4.
>svn up -q
### Now try to merge the replacement onto the deletion; it fails:
>svn merge ^^/A branch
..\..\..\subversion\svn\util.c:913: (apr_err=155015)
..\..\..\subversion\libsvn_client\merge.c:11349: (apr_err=155015)
..\..\..\subversion\libsvn_client\merge.c:11303: (apr_err=155015)
..\..\..\subversion\libsvn_client\merge.c:11303: (apr_err=155015)
..\..\..\subversion\libsvn_client\merge.c:11273: (apr_err=155015)
..\..\..\subversion\libsvn_client\merge.c:9287: (apr_err=155015)
..\..\..\subversion\libsvn_client\merge.c:8870: (apr_err=155015)
..\..\..\subversion\libsvn_client\merge.c:5349: (apr_err=155015)
..\..\..\subversion\libsvn_repos\reporter.c:1430: (apr_err=155015)
..\..\..\subversion\libsvn_client\ra.c:247: (apr_err=155015)
..\..\..\subversion\libsvn_repos\reporter.c:1269: (apr_err=155015)
..\..\..\subversion\libsvn_repos\reporter.c:1205: (apr_err=155015)
..\..\..\subversion\libsvn_repos\reporter.c:920: (apr_err=155015)
..\..\..\subversion\libsvn_delta\cancel.c:120: (apr_err=155015)
..\..\..\subversion\libsvn_delta\cancel.c:120: (apr_err=155015)
..\..\..\subversion\libsvn_client\repos_diff.c:710: (apr_err=155015)
..\..\..\subversion\libsvn_client\merge.c:2234: (apr_err=155015)
..\..\..\subversion\libsvn_wc\adm_ops.c:1069: (apr_err=155015)
..\..\..\subversion\libsvn_wc\adm_ops.c:937: (apr_err=155015)
svn: E155015:
'C:\SVN\src-trunk\Debug\subversion\tests\cmdline\svn-test-work\working_copies\merge_tree_conflict_tests-24\branch\C'
is an existing item in conflict; please mark the conflict as resolved
before adding a new item here
>svn st
? C branch\C
> local delete, incoming delete upon merge
Summary of conflicts:
Tree conflicts: 1
### Prior to r1127134 the merge raised a tree conflict:
trunk_at_1127133>svn merge ^^/A branch
--- Merging r2 through r4 into 'branch':
C branch\C
--- Recording mergeinfo for merge of r2 through r4 into 'branch':
U branch
Summary of conflicts:
Tree conflicts: 1
trunk_at_1127133>svn st
M branch
! C branch\C
> local delete, incoming delete upon merge
Summary of conflicts:
Tree conflicts: 1
Not exactly sure how to fix this...I can look at it further tomorrow,
just wanted to get your thoughts if you have time.
Paul
> switch (status)
> {
> case svn_wc__db_status_not_present:
>
> Modified: subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py?rev=1127134&r1=1127133&r2=1127134&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py (original)
> +++ subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py Tue May 24 16:35:14 2011
> @@ -1134,23 +1134,17 @@ def actual_only_node_behaviour(sbox):
>
> # add
> expected_stdout = None
> - expected_stderr = ".*foo.*not found.*"
> + expected_stderr = ".*foo.*is an existing item in conflict.*"
> run_and_verify_svn(None, expected_stdout, expected_stderr,
> "add", foo_path)
>
> # add (with an existing obstruction of foo)
> - ### this does not error out -- needs review
> svntest.main.file_write(foo_path, "This is an obstruction of foo.\n")
> - expected_stdout = "A.*foo"
> - expected_stderr = []
> + expected_stdout = None
> + expected_stderr = ".*foo.*is an existing item in conflict.*"
> run_and_verify_svn(None, expected_stdout, expected_stderr,
> "add", foo_path)
> - ### for now, ignore the fact that add succeeds, revert the entire
> - ### working copy, and repeat the merge so we can test more commands
> - svntest.main.run_svn(None, "revert", "-R", wc_dir)
> os.remove(foo_path) # remove obstruction
> - svntest.main.run_svn(None, "merge", '-c', '4', A_copy_url,
> - os.path.join(wc_dir, 'A'))
>
> # blame (praise, annotate, ann)
> expected_stdout = None
> @@ -1267,17 +1261,10 @@ def actual_only_node_behaviour(sbox):
> run_and_verify_svn(None, expected_stdout, expected_stderr,
> "mergeinfo", A_copy_url + '/foo', foo_path)
> # mkdir
> - ### this does not error out -- needs review
> expected_stdout = None
> - expected_stderr = []
> + expected_stderr = ".*foo.*is an existing item in conflict.*"
> run_and_verify_svn(None, expected_stdout, expected_stderr,
> "mkdir", foo_path)
> - ### for now, ignore the fact that mkdir succeeds, revert the entire
> - ### working copy, and repeat the merge so we can test more commands
> - svntest.main.run_svn(None, "revert", "-R", wc_dir)
> - os.rmdir(foo_path) # remove obstruction
> - svntest.main.run_svn(None, "merge", '-c', '4', A_copy_url,
> - os.path.join(wc_dir, 'A'))
>
> # move (mv, rename, ren)
> expected_stdout = None
>
>
>
Received on 2011-09-07 00:05:03 CEST