Author: julianfoad
Date: Thu Jun 25 16:35:14 2020
New Revision: 1879192
URL: http://svn.apache.org/viewvc?rev=1879192&view=rev
Log:
Fix issue #4859 "Merge removing a folder with non-inheritable mergeinfo ->
E155023: can't set properties: invalid status for updating properties".
The code was attempting to set mergeinfo on a path that is being deleted by
the merge. This happened only in certain unusual cases such as when
deleting a folder that had non-inheritable mergeinfo and had children.
This patch fixes the problem by removing the 'children_with_mergeinfo'
entries for sub-paths of a deleted folder.
* subversion/libsvn_client/merge.c
(merge_cmd_baton_t): Allow modifying 'children_with_mergeinfo'.
(record_update_delete): Remove from 'children_with_mergeinfo' all paths
in the subtree.
* subversion/tests/cmdline/merge_tests.py
(merge_deleted_folder_with_mergeinfo): Remove 'XFail'.
(merge_deleted_folder_with_mergeinfo_2): New test.
(test_list): Add the new test.
Modified:
subversion/trunk/subversion/libsvn_client/merge.c
subversion/trunk/subversion/tests/cmdline/merge_tests.py
Modified: subversion/trunk/subversion/libsvn_client/merge.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/merge.c?rev=1879192&r1=1879191&r2=1879192&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Thu Jun 25 16:35:14 2020
@@ -264,7 +264,7 @@ typedef struct merge_cmd_baton_t {
/* Reference to the one-and-only CHILDREN_WITH_MERGEINFO (see global
comment) or a similar list for single-file-merges */
- const apr_array_header_t *children_with_mergeinfo;
+ apr_array_header_t *children_with_mergeinfo;
svn_client_ctx_t *ctx; /* Client context for callbacks, etc. */
@@ -1545,6 +1545,25 @@ record_update_delete(merge_cmd_baton_t *
svn_node_kind_to_word(kind));
}
+ /* Note in children_with_mergeinfo that all paths in this subtree are
+ * being deleted, to avoid trying to set mergeinfo on them later. */
+ if (merge_b->children_with_mergeinfo)
+ {
+ int i;
+
+ for (i = 0; i < merge_b->children_with_mergeinfo->nelts; i++)
+ {
+ svn_client__merge_path_t *child
+ = APR_ARRAY_IDX(merge_b->children_with_mergeinfo, i,
+ svn_client__merge_path_t *);
+
+ if (svn_dirent_is_ancestor(local_abspath, child->abspath))
+ {
+
SVN_ERR(svn_sort__array_delete2(merge_b->children_with_mergeinfo, i--, 1));
+ }
+ }
+ }
+
return SVN_NO_ERROR;
}
Modified: subversion/trunk/subversion/tests/cmdline/merge_tests.py
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/merge_tests.py?rev=1879192&r1=1879191&r2=1879192&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/merge_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/merge_tests.py Thu Jun 25
16:35:14 2020
@@ -18502,7 +18502,6 @@ def merge_dir_delete_force(sbox):
# Issue #4859: Merge removing a folder with non-inheritable mergeinfo ->
# E155023: can't set properties: invalid status for updating properties
-@XFail()
@Issue(4859)
def merge_deleted_folder_with_mergeinfo(sbox):
"merge deleted folder with mergeinfo"
@@ -18527,6 +18526,55 @@ def merge_deleted_folder_with_mergeinfo(
svntest.actions.run_and_verify_svn(None, [],
'merge', '-c4', '^/branch_A',
sbox.ospath('A'))
+# Issue #4859: Merge removing a folder with non-inheritable mergeinfo ->
+# E155023: can't set properties: invalid status for updating properties
+#
+# In this test we split the merge into two separate operable parts, a
+# delete followed later by an add, to check it will set the mergeinfo on the
+# subtree paths if the deleted folder is later replaced within the same
+# overall merge.
+@Issue(4859)
+def merge_deleted_folder_with_mergeinfo_2(sbox):
+ "merge deleted folder with mergeinfo 2"
+
+ sbox.build()
+
+ # Some non-inheritable mergeinfo
+ sbox.simple_propset('svn:mergeinfo', '/A/C:1*', 'A/D')
+ sbox.simple_commit() # r2
+
+ # Branching
+ sbox.simple_repo_copy('A', 'branch_A') # r3
+ sbox.simple_update()
+
+ # On branch, remove a folder that has non-inheritable mergeinfo
+ sbox.simple_rm('branch_A/D')
+ sbox.simple_commit() # r4
+
+ # A commit that we don't want to merge from the branch, to split the merge
+ # into two separate operable parts.
+ sbox.simple_mkdir('branch_A/IgnoreThis')
+ sbox.simple_commit() # r5
+
+ # On branch, replace the deleted folder with a new one, with mergeinfo,
+ # to check we don't omit setting mergeinfo on this.
+ sbox.simple_mkdir('branch_A/D')
+ sbox.simple_propset('svn:mergeinfo', '/branch_B/C:1*', 'branch_A/D')
+ sbox.simple_mkdir('branch_A/D/G', 'branch_A/D/G2')
+ sbox.simple_propset('svn:mergeinfo', '/branch_B/C/G:1*', 'branch_A/D/G')
+ sbox.simple_propset('svn:mergeinfo', '/branch_B/C/G2:1*', 'branch_A/D/G2')
+ sbox.simple_commit() # r6
+
+ sbox.simple_propset('svn:mergeinfo', '/branch_A:5', 'A')
+ sbox.simple_commit() # r7
+
+ sbox.simple_update()
+
+ # A merge that removes that folder
+ svntest.actions.run_and_verify_svn(None, [],
+ 'merge', '^/branch_A', sbox.ospath('A'))
+ ### TODO: verify that mergeinfo is set/changed on A/D, A/D/G, A/D/G2.
+
########################################################################
# Run the tests
@@ -18675,6 +18723,7 @@ test_list = [ None,
conflict_naming,
merge_dir_delete_force,
merge_deleted_folder_with_mergeinfo,
+ merge_deleted_folder_with_mergeinfo_2,
]
if __name__ == '__main__':