You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2013/10/30 00:54:26 UTC
svn commit: r1536935 - in /subversion/branches/1.8.x-r1536931: ./
subversion/libsvn_client/commit_util.c
subversion/tests/cmdline/merge_tests.py
subversion/tests/libsvn_wc/op-depth-test.c
Author: rhuijben
Date: Tue Oct 29 23:54:25 2013
New Revision: 1536935
URL: http://svn.apache.org/r1536935
Log:
* Merge r1518942,1536914,1536931 from trunk, resolving ordering problem in op-depth.c
Modified:
subversion/branches/1.8.x-r1536931/ (props changed)
subversion/branches/1.8.x-r1536931/subversion/libsvn_client/commit_util.c
subversion/branches/1.8.x-r1536931/subversion/tests/cmdline/merge_tests.py
subversion/branches/1.8.x-r1536931/subversion/tests/libsvn_wc/op-depth-test.c
Propchange: subversion/branches/1.8.x-r1536931/
------------------------------------------------------------------------------
Merged /subversion/trunk:r1518942,1536914,1536931
Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_client/commit_util.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_client/commit_util.c?rev=1536935&r1=1536934&r2=1536935&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_client/commit_util.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_client/commit_util.c Tue Oct 29 23:54:25 2013
@@ -966,17 +966,19 @@ struct handle_descendants_baton
void *cancel_baton;
svn_client__check_url_kind_t check_url_func;
void *check_url_baton;
+ svn_client__committables_t *committables;
};
/* Helper for the commit harvesters */
static svn_error_t *
handle_descendants(void *baton,
- const void *key, apr_ssize_t klen, void *val,
- apr_pool_t *pool)
+ const void *key, apr_ssize_t klen, void *val,
+ apr_pool_t *pool)
{
struct handle_descendants_baton *hdb = baton;
apr_array_header_t *commit_items = val;
apr_pool_t *iterpool = svn_pool_create(pool);
+ const char *repos_root_url = key;
int i;
for (i = 0; i < commit_items->nelts; i++)
@@ -1002,32 +1004,64 @@ handle_descendants(void *baton,
for (j = 0; j < absent_descendants->nelts; j++)
{
- int k;
- svn_boolean_t found_item = FALSE;
svn_node_kind_t kind;
+ svn_client_commit_item3_t *desc_item;
const char *relpath = APR_ARRAY_IDX(absent_descendants, j,
const char *);
const char *local_abspath = svn_dirent_join(item->path, relpath,
iterpool);
- /* If the path has a commit operation, we do nothing.
- (It will be deleted by the operation) */
- for (k = 0; k < commit_items->nelts; k++)
+ /* ### Need a sub-iterpool? */
+
+
+ /* We found a 'not present' descendant during a copy (at op_depth>0),
+ this is most commonly caused by copying some mixed revision tree.
+
+ In this case not present can imply that the node does not exist
+ in the parent revision, or that the node does. But we want to copy
+ the working copy state in which it does not exist, but might be
+ replaced. */
+
+ desc_item = svn_hash_gets(hdb->committables->by_path, local_abspath);
+
+ /* If the path has a commit operation (possibly at an higher
+ op_depth, we might want to turn an add in a replace. */
+ if (desc_item)
{
- svn_client_commit_item3_t *cmt_item =
- APR_ARRAY_IDX(commit_items, k, svn_client_commit_item3_t *);
+ const char *dir;
+ svn_boolean_t found_intermediate = FALSE;
+
+ if (desc_item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
+ continue; /* We already have a delete or replace */
+ else if (!(desc_item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD))
+ continue; /* Not a copy/add, just a modification */
- if (! strcmp(cmt_item->path, local_abspath))
+ dir = svn_dirent_dirname(local_abspath, iterpool);
+
+ while (strcmp(dir, item->path))
{
- found_item = TRUE;
- break;
+ svn_client_commit_item3_t *i_item;
+
+ i_item = svn_hash_gets(hdb->committables->by_path, dir);
+
+ if (i_item)
+ {
+ if ((i_item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
+ || (i_item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD))
+ {
+ found_intermediate = TRUE;
+ break;
+ }
+ }
+ dir = svn_dirent_dirname(dir, iterpool);
}
- }
- if (found_item)
- continue; /* We have an explicit delete or replace for this path */
+ if (found_intermediate)
+ continue; /* Some intermediate ancestor is an add or delete */
- /* ### Need a sub-iterpool? */
+ /* Fall through to detect if we need to turn the add in a
+ replace. */
+ }
if (hdb->check_url_func)
{
@@ -1045,25 +1079,35 @@ handle_descendants(void *baton,
else
kind = svn_node_unknown; /* 'Ok' for a delete of something */
- {
- /* Add a new commit item that describes the delete */
- apr_pool_t *result_pool = commit_items->pool;
- svn_client_commit_item3_t *new_item
- = svn_client_commit_item3_create(result_pool);
-
- new_item->path = svn_dirent_join(item->path, relpath,
- result_pool);
- new_item->kind = kind;
- new_item->url = svn_path_url_add_component2(item->url, relpath,
- result_pool);
- new_item->revision = SVN_INVALID_REVNUM;
- new_item->state_flags = SVN_CLIENT_COMMIT_ITEM_DELETE;
- new_item->incoming_prop_changes = apr_array_make(result_pool, 1,
- sizeof(svn_prop_t *));
-
- APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *)
- = new_item;
- }
+ if (desc_item)
+ {
+ /* Extend the existing add/copy item to create a replace */
+ desc_item->state_flags |= SVN_CLIENT_COMMIT_ITEM_DELETE;
+ continue;
+ }
+
+ /* Add a new commit item that describes the delete */
+
+ SVN_ERR(add_committable(hdb->committables,
+ svn_dirent_join(item->path, relpath,
+ iterpool),
+ kind,
+ repos_root_url,
+ svn_uri_skip_ancestor(
+ repos_root_url,
+ svn_path_url_add_component2(item->url,
+ relpath,
+ iterpool),
+ iterpool),
+ SVN_INVALID_REVNUM,
+ NULL /* copyfrom_relpath */,
+ SVN_INVALID_REVNUM,
+ NULL /* moved_from_abspath */,
+ SVN_CLIENT_COMMIT_ITEM_DELETE,
+ NULL /* lock tokens */,
+ NULL /* lock */,
+ commit_items->pool,
+ iterpool));
}
}
@@ -1181,6 +1225,7 @@ svn_client__harvest_committables(svn_cli
hdb.cancel_baton = ctx->cancel_baton;
hdb.check_url_func = check_url_func;
hdb.check_url_baton = check_url_baton;
+ hdb.committables = *committables;
SVN_ERR(svn_iter_apr_hash(NULL, (*committables)->by_repository,
handle_descendants, &hdb, iterpool));
@@ -1274,6 +1319,7 @@ harvest_copy_committables(void *baton, v
hdb.cancel_baton = btn->ctx->cancel_baton;
hdb.check_url_func = btn->check_url_func;
hdb.check_url_baton = btn->check_url_baton;
+ hdb.committables = btn->committables;
SVN_ERR(svn_iter_apr_hash(NULL, btn->committables->by_repository,
handle_descendants, &hdb, pool));
Modified: subversion/branches/1.8.x-r1536931/subversion/tests/cmdline/merge_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/tests/cmdline/merge_tests.py?rev=1536935&r1=1536934&r2=1536935&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/tests/cmdline/merge_tests.py (original)
+++ subversion/branches/1.8.x-r1536931/subversion/tests/cmdline/merge_tests.py Tue Oct 29 23:54:25 2013
@@ -2047,7 +2047,7 @@ def merge_binary_with_common_ancestry(sb
# Commit the second branch
expected_output = wc.State(wc_dir, {
'L' : Item(verb='Adding'),
- 'L/theta' : Item(verb='Adding (bin)'),
+ 'L/theta' : Item(verb='Replacing'),
})
expected_status.add({
Modified: subversion/branches/1.8.x-r1536931/subversion/tests/libsvn_wc/op-depth-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/tests/libsvn_wc/op-depth-test.c?rev=1536935&r1=1536934&r2=1536935&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/tests/libsvn_wc/op-depth-test.c Tue Oct 29 23:54:25 2013
@@ -8339,6 +8339,60 @@ move_abspath_more_than_once(const svn_te
return SVN_NO_ERROR;
}
+static svn_error_t *
+copy_mixed_rev_mods(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ svn_test__sandbox_t b;
+
+ SVN_ERR(svn_test__sandbox_create(&b, "copy_mixed_rev_mods", opts,
+ pool));
+
+ SVN_ERR(sbox_wc_mkdir(&b, "A"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B/C"));
+ SVN_ERR(sbox_wc_commit(&b, ""));
+ SVN_ERR(sbox_wc_update(&b, "", 1));
+ SVN_ERR(sbox_wc_update(&b, "A/B", 2));
+ SVN_ERR(sbox_wc_delete(&b, "A/B"));
+ SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+
+ {
+ nodes_row_t nodes[] = {
+ {0, "", "normal", 1, ""},
+ {0, "A", "normal", 1, "A"},
+ {0, "A/B", "normal", 2, "A/B"},
+ {0, "A/B/C", "normal", 2, "A/B/C"},
+ {2, "A/B", "normal", NO_COPY_FROM},
+ {2, "A/B/C", "base-deleted", NO_COPY_FROM},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "", nodes));
+ }
+
+ SVN_ERR(sbox_wc_copy(&b, "A", "X"));
+ {
+ nodes_row_t nodes[] = {
+ {1, "X", "normal", 1, "A"},
+ {1, "X/B", "not-present", 2, "A/B"},
+ {2, "X/B", "normal", NO_COPY_FROM},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "X", nodes));
+ }
+
+ SVN_ERR(sbox_wc_commit(&b, "X"));
+ {
+ nodes_row_t nodes[] = {
+ {0, "X", "normal", 3, "X"},
+ {0, "X/B", "normal", 3, "X/B"},
+ {0}
+ };
+ SVN_ERR(check_db_rows(&b, "X", nodes));
+ }
+
+ return SVN_NO_ERROR;
+}
/* ---------------------------------------------------------------------- */
/* The list of test functions */
@@ -8497,5 +8551,7 @@ struct svn_test_descriptor_t test_funcs[
"move child to parent and revert (issue 4436)"),
SVN_TEST_OPTS_XFAIL(move_abspath_more_than_once,
"move one abspath more than once"),
+ SVN_TEST_OPTS_PASS(copy_mixed_rev_mods,
+ "copy mixed-rev with mods"),
SVN_TEST_NULL
};