You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pb...@apache.org on 2010/11/15 19:50:41 UTC
svn commit: r1035404 [15/15] - in /subversion/branches/issue-3668-3669: ./
build/ build/generator/ build/generator/templates/ build/win32/
subversion/bindings/javahl/native/
subversion/bindings/javahl/src/org/apache/subversion/javahl/
subversion/bindin...
Modified: subversion/branches/issue-3668-3669/subversion/svn/changelist-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/svn/changelist-cmd.c?rev=1035404&r1=1035403&r2=1035404&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/svn/changelist-cmd.c (original)
+++ subversion/branches/issue-3668-3669/subversion/svn/changelist-cmd.c Mon Nov 15 18:50:38 2010
@@ -55,9 +55,6 @@ svn_cl__changelist(apr_getopt_t *os,
apr_array_header_t *args;
SVN_ERR(svn_opt_parse_num_args(&args, os, 1, pool));
changelist_name = APR_ARRAY_IDX(args, 0, const char *);
- if (changelist_name[0] == '\0')
- return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("Changelist names must not be empty"));
SVN_ERR(svn_utf_cstring_to_utf8(&changelist_name,
changelist_name, pool));
}
Modified: subversion/branches/issue-3668-3669/subversion/svn/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/svn/main.c?rev=1035404&r1=1035403&r2=1035404&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/svn/main.c (original)
+++ subversion/branches/issue-3668-3669/subversion/svn/main.c Mon Nov 15 18:50:38 2010
@@ -367,6 +367,7 @@ const apr_getopt_option_t svn_cl__option
{"iw", opt_ignore_whitespace, 0, NULL},
{"idiff", opt_internal_diff, 0, NULL},
{"keep-locks", opt_no_unlock, 0, NULL},
+ {"keep-cl", opt_keep_changelists, 0, NULL},
{0, 0, 0, 0},
};
@@ -1168,10 +1169,17 @@ const svn_opt_subcommand_desc2_t svn_cl_
" are applied to the obstructing path. Obstructing paths are reported\n"
" in the first column with code 'E'.\n"
"\n"
+ " If the specified update target is missing from the working copy but its\n"
+ " immediate parent directory is present, checkout the target into its\n"
+ " parent directory at the specified depth. If --parents is specified,\n"
+ " create any missing parent directories of the target by checking them\n"
+ " out, too, at depth=empty.\n"
+ "\n"
" Use the --set-depth option to set a new working copy depth on the\n"
" targets of this operation.\n"),
{'r', 'N', opt_depth, opt_set_depth, 'q', opt_merge_cmd, opt_force,
- opt_ignore_externals, opt_changelist, opt_editor_cmd, opt_accept} },
+ opt_ignore_externals, opt_changelist, opt_editor_cmd, opt_accept,
+ opt_parents} },
{ "upgrade", svn_cl__upgrade, {0}, N_
("Upgrade the metadata storage format for a working copy.\n"
Modified: subversion/branches/issue-3668-3669/subversion/svn/patch-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/svn/patch-cmd.c?rev=1035404&r1=1035403&r2=1035404&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/svn/patch-cmd.c (original)
+++ subversion/branches/issue-3668-3669/subversion/svn/patch-cmd.c Mon Nov 15 18:50:38 2010
@@ -48,29 +48,43 @@ svn_cl__patch(apr_getopt_t *os,
{
svn_cl__opt_state_t *opt_state;
svn_client_ctx_t *ctx;
- apr_array_header_t *args;
apr_array_header_t *targets;
const char *abs_patch_path;
+ const char *patch_path;
const char *abs_target_path;
+ const char *target_path;
opt_state = ((svn_cl__cmd_baton_t *)baton)->opt_state;
ctx = ((svn_cl__cmd_baton_t *)baton)->ctx;
- SVN_ERR(svn_opt_parse_num_args(&args, os, 1, pool));
- SVN_ERR(svn_dirent_get_absolute(&abs_patch_path,
- APR_ARRAY_IDX(args, 0, const char *),
- pool));
-
- SVN_ERR(svn_client_args_to_target_array(&targets, os, opt_state->targets,
- ctx, pool));
- if (targets->nelts > 1)
+ SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
+ opt_state->targets,
+ ctx, pool));
+ SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, pool));
+
+ if (targets->nelts > 2)
return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0, NULL);
- svn_opt_push_implicit_dot_target(targets, pool);
- SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, pool));
- SVN_ERR(svn_dirent_get_absolute(&abs_target_path,
- APR_ARRAY_IDX(targets, 0, const char *),
- pool));
+ patch_path = APR_ARRAY_IDX(targets, 0, const char *);
+ if (svn_path_is_url(patch_path))
+ return svn_error_return(svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR,
+ NULL,
+ _("'%s' is not a local path"),
+ patch_path));
+ SVN_ERR(svn_dirent_get_absolute(&abs_patch_path, patch_path, pool));
+
+ if (targets->nelts == 1)
+ target_path = ""; /* "" is the canonical form of "." */
+ else
+ {
+ target_path = APR_ARRAY_IDX(targets, 1, const char *);
+ if (svn_path_is_url(target_path))
+ return svn_error_return(svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR,
+ NULL,
+ _("'%s' is not a local path"),
+ target_path));
+ }
+ SVN_ERR(svn_dirent_get_absolute(&abs_target_path, target_path, pool));
SVN_ERR(svn_client_patch(abs_patch_path, abs_target_path,
opt_state->dry_run, opt_state->strip,
Modified: subversion/branches/issue-3668-3669/subversion/svn/unlock-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/svn/unlock-cmd.c?rev=1035404&r1=1035403&r2=1035404&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/svn/unlock-cmd.c (original)
+++ subversion/branches/issue-3668-3669/subversion/svn/unlock-cmd.c Mon Nov 15 18:50:38 2010
@@ -27,6 +27,7 @@
/*** Includes. ***/
+#include "svn_path.h"
#include "svn_pools.h"
#include "svn_client.h"
#include "svn_error_codes.h"
@@ -48,6 +49,8 @@ svn_cl__unlock(apr_getopt_t *os,
svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
apr_array_header_t *targets;
+ svn_boolean_t wc_present = FALSE, url_present = FALSE;
+ int i;
SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
opt_state->targets,
@@ -59,6 +62,23 @@ svn_cl__unlock(apr_getopt_t *os,
SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, scratch_pool));
+ /* Check to see if at least one of our paths is a working copy
+ * path or a repository url. */
+ for (i = 0; i < targets->nelts; ++i)
+ {
+ const char *target = APR_ARRAY_IDX(targets, i, const char *);
+
+ if (! svn_path_is_url(target))
+ wc_present = TRUE;
+ else
+ url_present = TRUE;
+ }
+
+ if (url_present && wc_present)
+ return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Cannot mix repository and working copy "
+ "targets"));
+
return svn_error_return(
svn_client_unlock(targets, opt_state->force, ctx, scratch_pool));
}
Modified: subversion/branches/issue-3668-3669/subversion/svn/update-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/svn/update-cmd.c?rev=1035404&r1=1035403&r2=1035404&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/svn/update-cmd.c (original)
+++ subversion/branches/issue-3668-3669/subversion/svn/update-cmd.c Mon Nov 15 18:50:38 2010
@@ -92,11 +92,11 @@ svn_cl__update(apr_getopt_t *os,
ctx->notify_func2 = svn_cl__check_externals_failed_notify_wrapper;
ctx->notify_baton2 = &nwb;
- SVN_ERR(svn_client_update3(NULL, targets,
+ SVN_ERR(svn_client_update4(NULL, targets,
&(opt_state->start_revision),
depth, depth_is_sticky,
opt_state->ignore_externals,
- opt_state->force,
+ opt_state->force, opt_state->parents,
ctx, scratch_pool));
if (! opt_state->quiet)
Modified: subversion/branches/issue-3668-3669/subversion/tests/cmdline/depth_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/tests/cmdline/depth_tests.py?rev=1035404&r1=1035403&r2=1035404&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/tests/cmdline/depth_tests.py (original)
+++ subversion/branches/issue-3668-3669/subversion/tests/cmdline/depth_tests.py Mon Nov 15 18:50:38 2010
@@ -2718,6 +2718,90 @@ def update_depth_empty_root_of_infinite_
None, None,
None, None, None, None, wc_dir)
+def sparse_update_with_dash_dash_parents(sbox):
+ """update --parents"""
+
+ sbox.build(create_wc = False)
+ sbox.add_test_path(sbox.wc_dir, True)
+ alpha_path = os.path.join(sbox.wc_dir, 'A', 'B', 'E', 'alpha')
+ pi_path = os.path.join(sbox.wc_dir, 'A', 'D', 'G', 'pi')
+ omega_path = os.path.join(sbox.wc_dir, 'A', 'D', 'H', 'omega')
+
+ # Start with a depth=empty root checkout.
+ svntest.actions.run_and_verify_svn(
+ "Unexpected error from co --depth=empty",
+ svntest.verify.AnyOutput, [],
+ "co", "--depth", "empty", sbox.repo_url, sbox.wc_dir)
+
+ # Now, let's use --parents to pull in some scattered file children.
+ expected_output = svntest.wc.State(sbox.wc_dir, {
+ 'A' : Item(status='A '),
+ 'A/B' : Item(status='A '),
+ 'A/B/E' : Item(status='A '),
+ 'A/B/E/alpha' : Item(status='A '),
+ })
+ expected_disk = svntest.wc.State('', {
+ 'A' : Item(contents=None),
+ 'A/B' : Item(contents=None),
+ 'A/B/E' : Item(contents=None),
+ 'A/B/E/alpha' : Item(contents="This is the file 'alpha'.\n"),
+ })
+ expected_status = svntest.wc.State(sbox.wc_dir, {
+ '' : Item(status=' ', wc_rev=1),
+ 'A' : Item(status=' ', wc_rev=1),
+ 'A/B' : Item(status=' ', wc_rev=1),
+ 'A/B/E' : Item(status=' ', wc_rev=1),
+ 'A/B/E/alpha' : Item(status=' ', wc_rev=1),
+ })
+ svntest.actions.run_and_verify_update(sbox.wc_dir,
+ expected_output,
+ expected_disk,
+ expected_status,
+ None, None, None, None, None, False,
+ '--parents', alpha_path)
+
+ expected_output = svntest.wc.State(sbox.wc_dir, {
+ 'A/D' : Item(status='A '),
+ 'A/D/G' : Item(status='A '),
+ 'A/D/G/pi' : Item(status='A '),
+ })
+ expected_disk.add({
+ 'A/D' : Item(contents=None),
+ 'A/D/G' : Item(contents=None),
+ 'A/D/G/pi' : Item(contents="This is the file 'pi'.\n"),
+ })
+ expected_status.add({
+ 'A/D' : Item(status=' ', wc_rev=1),
+ 'A/D/G' : Item(status=' ', wc_rev=1),
+ 'A/D/G/pi' : Item(status=' ', wc_rev=1),
+ })
+ svntest.actions.run_and_verify_update(sbox.wc_dir,
+ expected_output,
+ expected_disk,
+ expected_status,
+ None, None, None, None, None, False,
+ '--parents', pi_path)
+
+ expected_output = svntest.wc.State(sbox.wc_dir, {
+ 'A/D/H' : Item(status='A '),
+ 'A/D/H/omega' : Item(status='A '),
+ })
+ expected_disk.add({
+ 'A/D/H' : Item(contents=None),
+ 'A/D/H/omega' : Item(contents="This is the file 'omega'.\n"),
+ })
+ expected_status.add({
+ 'A/D/H' : Item(status=' ', wc_rev=1),
+ 'A/D/H/omega' : Item(status=' ', wc_rev=1),
+ })
+ svntest.actions.run_and_verify_update(sbox.wc_dir,
+ expected_output,
+ expected_disk,
+ expected_status,
+ None, None, None, None, None, False,
+ '--parents', omega_path)
+
+
#----------------------------------------------------------------------
# list all tests here, starting with None:
test_list = [ None,
@@ -2763,6 +2847,7 @@ test_list = [ None,
tree_conflicts_resolved_depth_infinity,
update_excluded_path_sticky_depths,
update_depth_empty_root_of_infinite_children,
+ sparse_update_with_dash_dash_parents,
]
if __name__ == "__main__":
Modified: subversion/branches/issue-3668-3669/subversion/tests/cmdline/input_validation_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/tests/cmdline/input_validation_tests.py?rev=1035404&r1=1035403&r2=1035404&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/tests/cmdline/input_validation_tests.py (original)
+++ subversion/branches/issue-3668-3669/subversion/tests/cmdline/input_validation_tests.py Mon Nov 15 18:50:38 2010
@@ -201,6 +201,13 @@ def invalid_lock_targets(sbox):
run_and_verify_svn_in_wc(sbox, "svn: Cannot mix repository and working "
"copy targets", 'lock', target1, target2)
+def invalid_unlock_targets(sbox):
+ "wc paths and repo URL target mixture for 'unlock'"
+ sbox.build(read_only=True)
+ for (target1, target2) in [("iota", "^/"), ("file://", "iota")]:
+ run_and_verify_svn_in_wc(sbox, "svn: Cannot mix repository and working "
+ "copy targets", 'unlock', target1, target2)
+
def invalid_status_targets(sbox):
"non-working copy paths for 'status'"
sbox.build(read_only=True)
@@ -208,6 +215,13 @@ def invalid_status_targets(sbox):
run_and_verify_svn_in_wc(sbox, "svn:.*is not a local path", 'status',
target)
+def invalid_patch_targets(sbox):
+ "non-working copy paths for 'patch'"
+ sbox.build(read_only=True)
+ for (target1, target2) in [("foo", "^/"), ("^/", "^/"), ("^/", "foo")]:
+ run_and_verify_svn_in_wc(sbox, "svn:.*is not a local path", 'patch',
+ target1, target2)
+
########################################################################
# Run the tests
@@ -230,7 +244,9 @@ test_list = [ None,
invalid_resolved_targets,
invalid_revert_targets,
invalid_lock_targets,
+ invalid_unlock_targets,
invalid_status_targets,
+ invalid_patch_targets,
]
if __name__ == '__main__':
Modified: subversion/branches/issue-3668-3669/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/tests/cmdline/patch_tests.py?rev=1035404&r1=1035403&r2=1035404&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/branches/issue-3668-3669/subversion/tests/cmdline/patch_tests.py Mon Nov 15 18:50:38 2010
@@ -3414,6 +3414,10 @@ def patch_one_property(sbox, trailing_eo
1, # dry-run
'--strip', '3')
+ if is_os_windows():
+ # On Windows 'svn pg' uses \r\n as EOL.
+ value = value.replace('\n', '\r\n')
+
svntest.actions.check_prop('k', wc_dir, [value])
def patch_strip_cwd(sbox):
@@ -3508,7 +3512,7 @@ test_list = [ None,
patch_reverse_revert,
patch_strip_cwd,
XFail(patch_set_prop_no_eol),
- patch_add_symlink,
+ SkipUnless(patch_add_symlink, svntest.main.is_posix_os),
]
if __name__ == '__main__':
Modified: subversion/branches/issue-3668-3669/subversion/tests/cmdline/update_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/tests/cmdline/update_tests.py?rev=1035404&r1=1035403&r2=1035404&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/tests/cmdline/update_tests.py (original)
+++ subversion/branches/issue-3668-3669/subversion/tests/cmdline/update_tests.py Mon Nov 15 18:50:38 2010
@@ -5317,7 +5317,24 @@ def update_with_file_lock_and_keywords_p
if (mu_ts_before_update != mu_ts_after_update):
print("The timestamp of 'mu' before and after update does not match.")
raise svntest.Failure
-
+
+#----------------------------------------------------------------------
+# Updating a nonexistent or deleted path should be a successful no-op,
+# when there is no incoming change. In trunk@1035343, such an update
+# within a copied directory triggered an assertion failure.
+def update_nonexistent_child_of_copy(sbox):
+ """update a nonexistent child of a copied dir"""
+ sbox.build()
+ os.chdir(sbox.wc_dir)
+
+ svntest.main.run_svn(None, 'copy', 'A', 'A2')
+
+ # Try updating a nonexistent path in the copied dir.
+ svntest.main.run_svn(None, 'update', os.path.join('A2', 'nonexistent'))
+
+ # Try updating a deleted path in the copied dir.
+ svntest.main.run_svn(None, 'delete', os.path.join('A2', 'mu'))
+ svntest.main.run_svn(None, 'update', os.path.join('A2', 'mu'))
#######################################################################
# Run the tests
@@ -5382,7 +5399,8 @@ test_list = [ None,
XFail(update_empty_hides_entries),
mergeinfo_updates_merge_with_local_mods,
update_with_excluded_subdir,
- XFail(update_with_file_lock_and_keywords_property_set)
+ XFail(update_with_file_lock_and_keywords_property_set),
+ XFail(update_nonexistent_child_of_copy),
]
if __name__ == '__main__':
Modified: subversion/branches/issue-3668-3669/subversion/tests/libsvn_wc/op-depth-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/tests/libsvn_wc/op-depth-test.c?rev=1035404&r1=1035403&r2=1035404&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/branches/issue-3668-3669/subversion/tests/libsvn_wc/op-depth-test.c Mon Nov 15 18:50:38 2010
@@ -37,6 +37,8 @@
#include "private/svn_wc_private.h"
#include "private/svn_sqlite.h"
+#include "../../libsvn_wc/wc.h"
+#include "../../libsvn_wc/wc_db.h"
#include "../svn_test.h"
@@ -320,7 +322,7 @@ typedef struct {
* Append an error message to BATON->errors if they differ or are not both
* present.
*
- * If the ACTUAL row has field values that should have been elided
+ * If the FOUND row has field values that should have been elided
* (because they match the parent row), then do so now. We want to ignore
* any such lack of elision, for the purposes of these tests, because the
* method of copying in use (at the time this tweak is introduced) does
@@ -335,8 +337,9 @@ compare_nodes_rows(const void *key, apr_
comparison_baton_t *b = baton;
nodes_row_t *expected = apr_hash_get(b->expected_hash, key, klen);
nodes_row_t *found = apr_hash_get(b->found_hash, key, klen);
+ nodes_row_t elided;
- /* If the ACTUAL row has field values that should have been elided
+ /* If the FOUND row has field values that should have been elided
* (because they match the parent row), then do so now. */
if (found && found->op_depth > 0 && found->repo_relpath)
{
@@ -351,11 +354,16 @@ compare_nodes_rows(const void *key, apr_
APR_HASH_KEY_STRING);
if (parent_found && parent_found->op_depth > 0
&& parent_found->repo_relpath
+ && found->op_depth == parent_found->op_depth
+ && found->repo_revnum == parent_found->repo_revnum
&& strcmp(found->repo_relpath,
svn_relpath_join(parent_found->repo_relpath, name,
- b->scratch_pool)) == 0
- && found->repo_revnum == parent_found->repo_revnum)
+ b->scratch_pool)) == 0)
{
+ /* Iterating in hash order, which is arbitrary, so only make
+ changes in a local copy */
+ elided = *found;
+ found = &elided;
found->repo_relpath = NULL;
found->repo_revnum = SVN_INVALID_REVNUM;
}
@@ -415,7 +423,9 @@ check_db_rows(wc_baton_t *b,
SVN_ERR(open_wc_db(&sdb, b->wc_abspath, b->pool, b->pool));
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_NODES_INFO));
SVN_ERR(svn_sqlite__bindf(stmt, "ss", base_relpath,
- apr_psprintf(b->pool, "%s/%%", base_relpath)));
+ (base_relpath[0]
+ ? apr_psprintf(b->pool, "%s/%%", base_relpath)
+ : "_%")));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
while (have_row)
{
@@ -1155,6 +1165,519 @@ test_delete_with_update(const svn_test_o
return SVN_NO_ERROR;
}
+
+static svn_error_t *
+insert_dirs(wc_baton_t *b,
+ nodes_row_t *nodes)
+{
+ svn_sqlite__db_t *sdb;
+ svn_sqlite__stmt_t *stmt;
+ const char *dbpath = svn_dirent_join_many(b->pool,
+ b->wc_abspath, ".svn", "wc.db",
+ NULL);
+ const char * const statements[] = {
+ "DELETE FROM nodes;",
+ "INSERT INTO nodes (local_relpath, op_depth, presence, repos_path,"
+ " revision, wc_id, repos_id, kind, depth)"
+ " VALUES (?1, ?2, ?3, ?4, ?5, 1, 1, 'dir', 'infinity');",
+ "INSERT INTO nodes (local_relpath, op_depth, presence, repos_path,"
+ " revision, parent_relpath, wc_id, repos_id, kind, depth)"
+ " VALUES (?1, ?2, ?3, ?4, ?5, ?6, 1, 1, 'dir', 'infinity');",
+ NULL,
+ };
+
+ SVN_ERR(svn_sqlite__open(&sdb, dbpath, svn_sqlite__mode_readwrite,
+ statements, 0, NULL,
+ b->pool, b->pool));
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, 0));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+
+ while(nodes->local_relpath)
+ {
+ if (nodes->local_relpath[0])
+ {
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, 2));
+ SVN_ERR(svn_sqlite__bindf(stmt, "sissrs",
+ nodes->local_relpath,
+ (apr_int64_t)nodes->op_depth,
+ nodes->presence,
+ nodes->repo_relpath,
+ nodes->repo_revnum,
+ svn_relpath_dirname(nodes->local_relpath,
+ b->pool)));
+ }
+ else
+ {
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, 1));
+ SVN_ERR(svn_sqlite__bindf(stmt, "sissr",
+ nodes->local_relpath,
+ (apr_int64_t)nodes->op_depth,
+ nodes->presence,
+ nodes->repo_relpath,
+ nodes->repo_revnum));
+ }
+
+ SVN_ERR(svn_sqlite__step_done(stmt));
+ ++nodes;
+ }
+
+ SVN_ERR(svn_sqlite__close(sdb));
+
+ return SVN_NO_ERROR;
+}
+
+static int count_rows(nodes_row_t *rows)
+{
+ nodes_row_t *first = rows;
+ while(rows->local_relpath)
+ ++rows;
+ return rows - first;
+}
+
+static svn_error_t *
+base_dir_insert_remove(wc_baton_t *b,
+ const char *local_relpath,
+ svn_revnum_t revision,
+ nodes_row_t *before,
+ nodes_row_t *added)
+{
+ nodes_row_t *after;
+ const char *dir_abspath = svn_path_join(b->wc_abspath, local_relpath,
+ b->pool);
+ int i, num_before = count_rows(before), num_added = count_rows(added);
+
+ SVN_ERR(insert_dirs(b, before));
+
+ SVN_ERR(svn_wc__db_base_add_directory(b->wc_ctx->db, dir_abspath,
+ local_relpath, b->repos_url,
+ "not-even-a-uuid", revision,
+ apr_hash_make(b->pool), revision,
+ 0, NULL, NULL, svn_depth_infinity,
+ NULL, NULL, NULL, b->pool));
+
+ after = apr_palloc(b->pool, sizeof(*after) * (num_before + num_added + 1));
+ for (i = 0; i < num_before; ++i)
+ after[i] = before[i];
+ for (i = 0; i < num_added; ++i)
+ after[num_before+i] = added[i];
+ after[num_before+num_added].local_relpath = NULL;
+
+ SVN_ERR(check_db_rows(b, "", after));
+
+ SVN_ERR(svn_wc__db_base_remove(b->wc_ctx->db, dir_abspath, b->pool));
+
+ SVN_ERR(check_db_rows(b, "", before));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_base_dir_insert_remove(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ wc_baton_t b;
+
+ b.pool = pool;
+ SVN_ERR(svn_test__create_repos_and_wc(&b.repos_url, &b.wc_abspath,
+ "base_dir_insert_remove", opts, pool));
+ SVN_ERR(svn_wc_context_create(&b.wc_ctx, NULL, pool, pool));
+
+ {
+ /* / normal / normal
+ A normal A normal
+ A/B normal
+ */
+ nodes_row_t before[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ { 0 }
+ };
+ nodes_row_t added[] = {
+ { 0, "A/B", "normal", 2, "A/B" },
+ { 0 }
+ };
+ SVN_ERR(base_dir_insert_remove(&b, "A/B", 2, before, added));
+ }
+ {
+ /* / normal / normal
+ A normal base-del A normal base-del
+ A/B normal base-del
+ */
+ nodes_row_t before[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ { 1, "A", "base-deleted", NO_COPY_FROM },
+ { 0 }
+ };
+ nodes_row_t added[] = {
+ { 0, "A/B", "normal", 2, "A/B" },
+ { 1, "A/B", "base-deleted", NO_COPY_FROM },
+ { 0 }
+ };
+ SVN_ERR(base_dir_insert_remove(&b, "A/B", 2, before, added));
+ }
+ {
+ /* / normal / normal
+ A normal normal A normal normal
+ A/B normal base-del
+ */
+ nodes_row_t before[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ { 1, "A", "normal", 1, "X" },
+ { 0 }
+ };
+ nodes_row_t added[] = {
+ { 0, "A/B", "normal", 2, "A/B" },
+ { 1, "A/B", "base-deleted", NO_COPY_FROM },
+ { 0 }
+ };
+ SVN_ERR(base_dir_insert_remove(&b, "A/B", 2, before, added));
+ }
+ {
+ /* / normal / normal
+ A normal normal A normal normal
+ A/B normal not-pres A/B normal not-pres
+ A/B/C normal base-del
+ */
+ nodes_row_t before[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ { 0, "A/B", "normal", 2, "A/B" },
+ { 1, "A", "normal", 1, "X" },
+ { 1, "A/B", "not-present", NO_COPY_FROM },
+ { 0 }
+ };
+ nodes_row_t added[] = {
+ { 0, "A/B/C", "normal", 2, "A/B/C" },
+ { 1, "A/B/C", "base-deleted", NO_COPY_FROM },
+ { 0 }
+ };
+ SVN_ERR(base_dir_insert_remove(&b, "A/B/C", 2, before, added));
+ }
+ {
+ /* / normal / normal
+ A normal normal A normal normal
+ A/B normal A/B normal normal
+ */
+ nodes_row_t before[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ { 1, "A", "normal", 1, "X" },
+ { 1, "A/B", "normal", NO_COPY_FROM },
+ { 0 }
+ };
+ nodes_row_t added[] = {
+ { 0, "A/B", "normal", 2, "A/B" },
+ { 0 }
+ };
+ SVN_ERR(base_dir_insert_remove(&b, "A/B", 2, before, added));
+ }
+ {
+ /* / normal / normal
+ A normal normal A normal normal
+ A/B not-pres A/B normal not-pres
+ */
+ nodes_row_t before[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ { 1, "A", "normal", 1, "X" },
+ { 1, "A/B", "not-present", NO_COPY_FROM },
+ { 0 }
+ };
+ nodes_row_t added[] = {
+ { 0, "A/B", "normal", 2, "A/B" },
+ { 0 }
+ };
+ SVN_ERR(base_dir_insert_remove(&b, "A/B", 2, before, added));
+ }
+ {
+ /* / normal / normal
+ A normal normal A normal normal
+ A/B normal A/B normal base-del normal
+ */
+ nodes_row_t before[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ { 1, "A", "normal", 1, "X" },
+ { 2, "A/B", "normal", 1, "Y" },
+ { 0 }
+ };
+ nodes_row_t added[] = {
+ { 0, "A/B", "normal", 2, "A/B" },
+ { 1, "A/B", "base-deleted", NO_COPY_FROM },
+ { 0 }
+ };
+ SVN_ERR(base_dir_insert_remove(&b, "A/B", 2, before, added));
+ }
+ {
+ /* / normal / normal
+ A normal normal A normal normal
+ A/B normal base-del normal A/B normal base-del normal
+ A/B/C normal A/B/C normal base-del normal
+ */
+ nodes_row_t before[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ { 0, "A/B", "normal", 2, "A/B" },
+ { 1, "A", "normal", 1, "X" },
+ { 1, "A/B", "base-deleted", NO_COPY_FROM },
+ { 2, "A/B", "normal", 1, "Y" },
+ { 0 }
+ };
+ nodes_row_t added[] = {
+ { 0, "A/B/C", "normal", 2, "A/B/C" },
+ { 1, "A/B/C", "base-deleted", NO_COPY_FROM },
+ { 0 }
+ };
+ SVN_ERR(base_dir_insert_remove(&b, "A/B/C", 2, before, added));
+ }
+ {
+ /* / normal / normal
+ A normal normal A normal normal
+ A/B normal not-pres normal A/B normal not-pres normal
+ A/B/C normal A/B/C normal base-del normal
+ */
+ nodes_row_t before[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ { 0, "A/B", "normal", 2, "A/B" },
+ { 1, "A", "normal", 1, "X" },
+ { 1, "A/B", "not-present", NO_COPY_FROM },
+ { 2, "A/B", "normal", 1, "Y" },
+ { 2, "A/B/C", "normal", NO_COPY_FROM },
+ { 0 }
+ };
+ nodes_row_t added[] = {
+ { 0, "A/B/C", "normal", 2, "A/B/C" },
+ { 1, "A/B/C", "base-deleted", NO_COPY_FROM },
+ { 0 }
+ };
+ SVN_ERR(base_dir_insert_remove(&b, "A/B/C", 2, before, added));
+ }
+ {
+ /* / normal /
+ A normal normal A normal normal
+ A/B normal base-del normal A/B normal base-del normal
+ A/B/C not-pres A/B/C normal base-del not-pres
+ */
+ nodes_row_t before[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ { 0, "A/B", "normal", 2, "A/B" },
+ { 1, "A", "normal", 1, "X" },
+ { 1, "A/B", "base-deleted", NO_COPY_FROM },
+ { 2, "A/B", "normal", 1, "Y" },
+ { 2, "A/B/C", "not-present", NO_COPY_FROM },
+ { 0 }
+ };
+ nodes_row_t added[] = {
+ { 0, "A/B/C", "normal", 2, "A/B/C" },
+ { 1, "A/B/C", "base-deleted", NO_COPY_FROM },
+ { 0 }
+ };
+ SVN_ERR(base_dir_insert_remove(&b, "A/B/C", 2, before, added));
+ }
+ {
+ /* / normal /
+ A normal normal A normal normal
+ A/B normal not-pres normal A/B normal not-pres normal
+ A/B/C not-pres A/B/C normal base-del not-pres
+ */
+ nodes_row_t before[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ { 0, "A/B", "normal", 2, "A/B" },
+ { 1, "A", "normal", 1, "X" },
+ { 1, "A/B", "not-present", NO_COPY_FROM },
+ { 2, "A/B", "normal", 1, "Y" },
+ { 2, "A/B/C", "not-present", NO_COPY_FROM },
+ { 0 }
+ };
+ nodes_row_t added[] = {
+ { 0, "A/B/C", "normal", 2, "A/B/C" },
+ { 1, "A/B/C", "base-deleted", NO_COPY_FROM },
+ { 0 }
+ };
+ SVN_ERR(base_dir_insert_remove(&b, "A/B/C", 2, before, added));
+ }
+ {
+ /* / norm /
+ A norm norm A norm norm
+ A/B norm not-p norm A/B norm not-p norm
+ A/B/C norm A/B/C norm b-del norm
+ */
+ nodes_row_t before[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ { 0, "A/B", "normal", 2, "A/B" },
+ { 1, "A", "normal", 1, "X" },
+ { 1, "A/B", "not-present", NO_COPY_FROM },
+ { 2, "A/B", "normal", 1, "Y" },
+ { 3, "A/B/C", "normal", NO_COPY_FROM },
+ { 0 }
+ };
+ nodes_row_t added[] = {
+ { 0, "A/B/C", "normal", 2, "A/B/C" },
+ { 1, "A/B/C", "base-deleted", NO_COPY_FROM },
+ { 0 }
+ };
+ SVN_ERR(base_dir_insert_remove(&b, "A/B/C", 2, before, added));
+ }
+ {
+ /* / norm / norm
+ A norm A norm
+ A/B norm A/B norm
+ A/B/C norm - - norm A/B/C norm - - norm
+ A/B/C/D norm - - b-del
+ */
+ nodes_row_t before[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ { 0, "A/B", "normal", 2, "A/B" },
+ { 0, "A/B/C", "normal", 2, "A/B/C" },
+ { 3, "A/B/C", "normal", NO_COPY_FROM },
+ { 0 }
+ };
+ nodes_row_t added[] = {
+ { 0, "A/B/C/D", "normal", 2, "A/B/C/D" },
+ { 3, "A/B/C/D", "base-deleted", NO_COPY_FROM },
+ { 0 }
+ };
+ SVN_ERR(base_dir_insert_remove(&b, "A/B/C/D", 2, before, added));
+ }
+ {
+ /* / norm / norm
+ A norm A norm
+ A/B norm A/B norm
+ A/B/C norm - - norm A/B/C norm - - norm
+ A/B/C/D norm A/B/C/D norm - - b-del norm
+ */
+ nodes_row_t before[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ { 0, "A/B", "normal", 2, "A/B" },
+ { 0, "A/B/C", "normal", 2, "A/B/C" },
+ { 3, "A/B/C", "normal", NO_COPY_FROM },
+ { 4, "A/B/C/D", "normal", NO_COPY_FROM },
+ { 0 }
+ };
+ nodes_row_t added[] = {
+ { 0, "A/B/C/D", "normal", 2, "A/B/C/D" },
+ { 3, "A/B/C/D", "base-deleted", NO_COPY_FROM },
+ { 0 }
+ };
+ SVN_ERR(base_dir_insert_remove(&b, "A/B/C/D", 2, before, added));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+temp_op_make_copy(wc_baton_t *b,
+ const char *local_relpath,
+ nodes_row_t *before,
+ nodes_row_t *after)
+{
+ const char *dir_abspath = svn_path_join(b->wc_abspath, local_relpath,
+ b->pool);
+
+ SVN_ERR(insert_dirs(b, before));
+
+ SVN_ERR(svn_wc__db_temp_op_make_copy(b->wc_ctx->db, dir_abspath, b->pool));
+
+ SVN_ERR(check_db_rows(b, "", after));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_temp_op_make_copy(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ wc_baton_t b;
+
+ b.pool = pool;
+ SVN_ERR(svn_test__create_repos_and_wc(&b.repos_url, &b.wc_abspath,
+ "base_dir_insert_remove", opts, pool));
+ SVN_ERR(svn_wc_context_create(&b.wc_ctx, NULL, pool, pool));
+
+ {
+ /* / norm -
+ A norm -
+ A/B norm - norm
+ A/B/C norm - base-del norm
+ A/F norm - norm
+ A/F/G norm - norm
+ A/F/H norm - not-pres
+ A/F/E norm - base-del
+ A/X norm -
+ A/X/Y incomplete -
+ */
+ nodes_row_t before[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ { 0, "A/B", "normal", 2, "A/B" },
+ { 0, "A/B/C", "normal", 2, "A/B/C" },
+ { 0, "A/F", "normal", 2, "A/F" },
+ { 0, "A/F/G", "normal", 2, "A/F/G" },
+ { 0, "A/F/H", "normal", 2, "A/F/H" },
+ { 0, "A/F/E", "normal", 2, "A/F/E" },
+ { 0, "A/X", "normal", 2, "A/X" },
+ { 0, "A/X/Y", "incomplete", 2, "A/X/Y" },
+ { 2, "A/B", "normal", NO_COPY_FROM },
+ { 2, "A/B/C", "base-deleted", NO_COPY_FROM },
+ { 3, "A/B/C", "normal", NO_COPY_FROM },
+ { 2, "A/F", "normal", 1, "S2" },
+ { 2, "A/F/G", "normal", NO_COPY_FROM },
+ { 2, "A/F/H", "not-present", NO_COPY_FROM },
+ { 2, "A/F/E", "base-deleted", NO_COPY_FROM },
+ { 0 }
+ };
+ /* / norm -
+ A norm norm
+ A/B norm base-del norm
+ A/B/C norm base-del norm
+ A/F norm base-del norm
+ A/F/G norm base-del norm
+ A/F/H norm base-del not-pres
+ A/F/E norm base-del
+ A/X norm norm
+ A/X/Y incomplete incomplete
+ */
+ nodes_row_t after[] = {
+ { 0, "", "normal", 2, "" },
+ { 0, "A", "normal", 2, "A" },
+ { 0, "A/B", "normal", 2, "A/B" },
+ { 0, "A/B/C", "normal", 2, "A/B/C" },
+ { 0, "A/F", "normal", 2, "A/F" },
+ { 0, "A/F/G", "normal", 2, "A/F/G" },
+ { 0, "A/F/H", "normal", 2, "A/F/H" },
+ { 0, "A/F/E", "normal", 2, "A/F/E" },
+ { 0, "A/X", "normal", 2, "A/X" },
+ { 0, "A/X/Y", "incomplete", 2, "A/X/Y" },
+ { 1, "A", "normal", 2, "A" },
+ { 1, "A/B", "base-deleted", NO_COPY_FROM },
+ { 1, "A/B/C", "base-deleted", NO_COPY_FROM },
+ { 1, "A/F", "base-deleted", NO_COPY_FROM },
+ { 1, "A/F/G", "base-deleted", NO_COPY_FROM },
+ { 1, "A/F/H", "base-deleted", NO_COPY_FROM },
+ { 1, "A/F/E", "base-deleted", NO_COPY_FROM },
+ { 1, "A/X", "normal", NO_COPY_FROM },
+ { 1, "A/X/Y", "incomplete", NO_COPY_FROM },
+ { 2, "A/B", "normal", NO_COPY_FROM },
+ { 3, "A/B/C", "normal", NO_COPY_FROM },
+ { 2, "A/F", "normal", 1, "S2" },
+ { 2, "A/F/G", "normal", NO_COPY_FROM },
+ { 2, "A/F/H", "not-present", NO_COPY_FROM },
+ { 0 }
+ };
+
+ SVN_ERR(temp_op_make_copy(&b, "A", before, after));
+ }
+
+ return SVN_NO_ERROR;
+}
+
/* ---------------------------------------------------------------------- */
/* The list of test functions */
@@ -1188,5 +1711,11 @@ struct svn_test_descriptor_t test_funcs[
SVN_TEST_OPTS_WIMP(test_adds_change_kind,
"test_adds_change_kind",
"needs op_depth"),
+ SVN_TEST_OPTS_WIMP(test_base_dir_insert_remove,
+ "test_base_dir_insert_remove",
+ "needs op_depth"),
+ SVN_TEST_OPTS_WIMP(test_temp_op_make_copy,
+ "test_temp_op_make_copy",
+ "needs op_depth"),
SVN_TEST_NULL
};
Modified: subversion/branches/issue-3668-3669/subversion/tests/libsvn_wc/tree-conflict-data-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/tests/libsvn_wc/tree-conflict-data-test.c?rev=1035404&r1=1035403&r2=1035404&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/tests/libsvn_wc/tree-conflict-data-test.c (original)
+++ subversion/branches/issue-3668-3669/subversion/tests/libsvn_wc/tree-conflict-data-test.c Mon Nov 15 18:50:38 2010
@@ -53,15 +53,14 @@ fail(apr_pool_t *pool, const char *fmt,
static svn_error_t *
test_read_tree_conflict(apr_pool_t *pool)
{
- svn_wc_conflict_description2_t *conflict;
- apr_hash_t *conflicts;
+ const svn_wc_conflict_description2_t *conflict;
svn_wc_conflict_description2_t *exp_conflict;
const char *tree_conflict_data;
- apr_hash_index_t *hi;
const char *local_abspath;
+ const svn_skel_t *skel;
- tree_conflict_data = "((conflict Foo.c file update deleted edited "
- "(version 0 2 -1 0 0 ) (version 0 2 -1 0 0 )))";
+ tree_conflict_data = "(conflict Foo.c file update deleted edited "
+ "(version 0 2 -1 0 0 ) (version 0 2 -1 0 0 ))";
SVN_ERR(svn_dirent_get_absolute(&local_abspath, "Foo.c", pool));
exp_conflict = svn_wc_conflict_description_create_tree2(
@@ -70,11 +69,8 @@ test_read_tree_conflict(apr_pool_t *pool
exp_conflict->action = svn_wc_conflict_action_delete;
exp_conflict->reason = svn_wc_conflict_reason_edited;
- SVN_ERR(svn_wc__read_tree_conflicts(&conflicts, tree_conflict_data, "",
- pool));
-
- hi = apr_hash_first(pool, conflicts);
- conflict = svn__apr_hash_index_val(hi);
+ skel = svn_skel__parse(tree_conflict_data, strlen(tree_conflict_data), pool);
+ SVN_ERR(svn_wc__deserialize_conflict(&conflict, skel, "", pool, pool));
if ((conflict->node_kind != exp_conflict->node_kind) ||
(conflict->action != exp_conflict->action) ||
@@ -87,120 +83,13 @@ test_read_tree_conflict(apr_pool_t *pool
}
static svn_error_t *
-test_read_2_tree_conflicts(apr_pool_t *pool)
-{
- const char *tree_conflict_data;
- svn_wc_conflict_description2_t *conflict1, *conflict2;
- apr_hash_t *conflicts;
- svn_wc_conflict_description2_t *exp_conflict1, *exp_conflict2;
- apr_hash_index_t *hi;
- const char *local_abspath;
-
- tree_conflict_data =
- "((conflict Foo.c file update deleted edited "
- "(version 0 2 -1 0 0 ) (version 0 2 -1 0 0 )) "
- "(conflict Bar.h file update edited deleted "
- "(version 0 2 -1 0 0 ) (version 0 2 -1 0 0 )))";
-
- SVN_ERR(svn_dirent_get_absolute(&local_abspath, "Foo.c", pool));
- exp_conflict1 = svn_wc_conflict_description_create_tree2(
- local_abspath, svn_node_file, svn_wc_operation_update,
- NULL, NULL, pool);
- exp_conflict1->action = svn_wc_conflict_action_delete;
- exp_conflict1->reason = svn_wc_conflict_reason_edited;
-
- SVN_ERR(svn_dirent_get_absolute(&local_abspath, "Bar.h", pool));
- exp_conflict2 = svn_wc_conflict_description_create_tree2(
- local_abspath, svn_node_file, svn_wc_operation_update,
- NULL, NULL, pool);
- exp_conflict2->action = svn_wc_conflict_action_edit;
- exp_conflict2->reason = svn_wc_conflict_reason_deleted;
-
- SVN_ERR(svn_wc__read_tree_conflicts(&conflicts, tree_conflict_data, "",
- pool));
-
- hi = apr_hash_first(pool, conflicts);
- conflict1 = svn__apr_hash_index_val(hi);
- if ((conflict1->node_kind != exp_conflict1->node_kind) ||
- (conflict1->action != exp_conflict1->action) ||
- (conflict1->reason != exp_conflict1->reason) ||
- (conflict1->operation != exp_conflict1->operation) ||
- (strcmp(conflict1->local_abspath, exp_conflict1->local_abspath) != 0))
- return fail(pool, "Tree conflict struct #1 has bad data");
-
- hi = apr_hash_next(hi);
- conflict2 = svn__apr_hash_index_val(hi);
- if ((conflict2->node_kind != exp_conflict2->node_kind) ||
- (conflict2->action != exp_conflict2->action) ||
- (conflict2->reason != exp_conflict2->reason) ||
- (conflict2->operation != exp_conflict2->operation) ||
- (strcmp(conflict2->local_abspath, exp_conflict2->local_abspath) != 0))
- return fail(pool, "Tree conflict struct #2 has bad data");
-
- return SVN_NO_ERROR;
-}
-
-/* This needs to be adjusted in case the constants for the
- * delimiters change... */
-static const char* broken_tree_conflict_test_data[] = {
- /* Missing descriptions */
- "|Bar.h:file:update:edited:deleted::::::::",
- "Foo.c:file:update:deleted:edited::::::::|",
- "|||||||",
- "",
- /* Missing fields */
- "Foo.c:fileupdate:deleted:edited::::::::",
- "Foo.c",
- "::::",
- ":::",
- "Foo.c:::::::::::::;",
- /* Bad separators */
- "Foo.c:file:update:deleted:edited::::::::$Bar.h:file:update:edited:deleted::::::::",
- "Foo.c|file|update|deleted|edited:::::::::Bar.h|file|update|edited|deleted::::::::",
- /* Missing separators */
- "Foo.c:file:update:deleted:edited::::::::Bar.h:file:update:edited:deleted::::::::",
- "Foo.c:fileupdate:deleted:edited::::::::",
- /* Unescaped separators */
- "F|oo.c:file:update:deleted:edited::::::::",
- "F:oo.c:file:update:deleted:edited::::::::",
- /* Unescaped escape */
- "Foo.c\\:file:update:deleted:edited::::::::",
- "Foo.c\\",
- /* Illegally escaped char */
- "\\Foo.c:file:update:deleted:edited::::::::",
- NULL
-};
-
-static svn_error_t *
-test_read_invalid_tree_conflicts(apr_pool_t *pool)
-{
- int i;
- const char *tree_conflict_data;
- apr_hash_t *conflicts;
- svn_error_t *err;
-
- for (i = 0; broken_tree_conflict_test_data[i] != NULL; i++)
- {
- tree_conflict_data = broken_tree_conflict_test_data[i];
- err = svn_wc__read_tree_conflicts(&conflicts, tree_conflict_data, "",
- pool);
- if (err == SVN_NO_ERROR)
- return fail(pool,
- "Error in broken tree conflict data was not detected:\n"
- " %s", tree_conflict_data);
- svn_error_clear(err);
- }
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
test_write_tree_conflict(apr_pool_t *pool)
{
svn_wc_conflict_description2_t *conflict;
const char *tree_conflict_data;
- apr_hash_t *conflicts;
const char *expected;
const char *local_abspath;
+ svn_skel_t *skel;
SVN_ERR(svn_dirent_get_absolute(&local_abspath, "Foo.c", pool));
@@ -210,14 +99,11 @@ test_write_tree_conflict(apr_pool_t *poo
conflict->action = svn_wc_conflict_action_delete;
conflict->reason = svn_wc_conflict_reason_edited;
- conflicts = apr_hash_make(pool);
- apr_hash_set(conflicts, conflict->local_abspath, APR_HASH_KEY_STRING,
- conflict);
-
- expected = "((conflict Foo.c file update deleted edited "
- "(version 0 2 -1 0 0 ) (version 0 2 -1 0 0 )))";
+ SVN_ERR(svn_wc__serialize_conflict(&skel, conflict, pool, pool));
+ tree_conflict_data = svn_skel__unparse(skel, pool)->data;
- SVN_ERR(svn_wc__write_tree_conflicts(&tree_conflict_data, conflicts, pool));
+ expected = "(conflict Foo.c file update deleted edited "
+ "(version 0 2 -1 0 0 ) (version 0 2 -1 0 0 ))";
if (strcmp(expected, tree_conflict_data) != 0)
return fail(pool, "Unexpected text from tree conflict\n"
@@ -227,60 +113,6 @@ test_write_tree_conflict(apr_pool_t *poo
return SVN_NO_ERROR;
}
-static svn_error_t *
-test_write_2_tree_conflicts(apr_pool_t *pool)
-{
- svn_wc_conflict_description2_t *conflict1, *conflict2;
- apr_hash_t *conflicts;
- const char *tree_conflict_data;
- const char *expected1;
- const char *expected2;
- const char *local_abspath;
-
- SVN_ERR(svn_dirent_get_absolute(&local_abspath, "Foo.c", pool));
- conflict1 = svn_wc_conflict_description_create_tree2(
- local_abspath, svn_node_file, svn_wc_operation_update,
- NULL, NULL, pool);
- conflict1->action = svn_wc_conflict_action_delete;
- conflict1->reason = svn_wc_conflict_reason_edited;
-
- SVN_ERR(svn_dirent_get_absolute(&local_abspath, "Bar.h", pool));
- conflict2 = svn_wc_conflict_description_create_tree2(
- local_abspath, svn_node_file, svn_wc_operation_update,
- NULL, NULL, pool);
- conflict2->action = svn_wc_conflict_action_edit;
- conflict2->reason = svn_wc_conflict_reason_deleted;
-
- conflicts = apr_hash_make(pool);
- apr_hash_set(conflicts, conflict1->local_abspath, APR_HASH_KEY_STRING,
- conflict1);
- apr_hash_set(conflicts, conflict2->local_abspath, APR_HASH_KEY_STRING,
- conflict2);
-
- /* We don't know the order the hash will spit out the data, so just test
- for both possibilities. */
- expected1 = "((conflict Foo.c file update deleted edited "
- "(version 0 2 -1 0 0 ) (version 0 2 -1 0 0 )) "
- "(conflict Bar.h file update edited deleted "
- "(version 0 2 -1 0 0 ) (version 0 2 -1 0 0 )))";
- expected2 = "((conflict Bar.h file update edited deleted "
- "(version 0 2 -1 0 0 ) (version 0 2 -1 0 0 )) "
- "(conflict Foo.c file update deleted edited "
- "(version 0 2 -1 0 0 ) (version 0 2 -1 0 0 )))";
-
- SVN_ERR(svn_wc__write_tree_conflicts(&tree_conflict_data, conflicts, pool));
-
- if (strcmp(expected1, tree_conflict_data) != 0
- && strcmp(expected2, tree_conflict_data) != 0)
- return fail(pool, "Unexpected text from tree conflict\n"
- " Expected: %s\n"
- " OR %s\n"
- " Actual: %s\n", expected1, expected2,
- tree_conflict_data);
-
- return SVN_NO_ERROR;
-}
-
#ifdef THIS_TEST_RAISES_MALFUNCTION
static svn_error_t *
test_write_invalid_tree_conflicts(apr_pool_t *pool)
@@ -380,14 +212,8 @@ struct svn_test_descriptor_t test_funcs[
SVN_TEST_NULL,
SVN_TEST_PASS2(test_read_tree_conflict,
"read 1 tree conflict"),
- SVN_TEST_PASS2(test_read_2_tree_conflicts,
- "read 2 tree conflicts"),
- SVN_TEST_XFAIL2(test_read_invalid_tree_conflicts,
- "detect broken tree conflict data"),
SVN_TEST_PASS2(test_write_tree_conflict,
"write 1 tree conflict"),
- SVN_TEST_PASS2(test_write_2_tree_conflicts,
- "write 2 tree conflicts"),
#ifdef THIS_TEST_RAISES_MALFUNCTION
SVN_TEST_PASS2(test_write_invalid_tree_conflicts,
"detect broken tree conflict data while writing"),