Modified: subversion/branches/move-tracking-2/subversion/svn/info-cmd.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svn/info-cmd.c?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/svn/info-cmd.c (original) +++ subversion/branches/move-tracking-2/subversion/svn/info-cmd.c Mon Mar 9 09:53:06 2015 @@ -885,7 +885,7 @@ svn_cl__info(apr_getopt_t *os, if (opt_state->no_newline) return svn_error_create( SVN_ERR_CL_ARG_PARSING_ERROR, NULL, - _("--no-newline' is not valid in --xml mode")); + _("--no-newline is not valid in --xml mode")); /* If output is not incremental, output the XML header and wrap everything in a top-level element. This makes the output in
Modified: subversion/branches/move-tracking-2/subversion/svnrdump/load_editor.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnrdump/load_editor.c?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/svnrdump/load_editor.c (original) +++ subversion/branches/move-tracking-2/subversion/svnrdump/load_editor.c Mon Mar 9 09:53:06 2015 @@ -659,7 +659,8 @@ new_node_record(void **node_baton, { case svn_node_action_delete: case svn_node_action_replace: - SVN_ERR(commit_editor->delete_entry(nb->path, rb->rev - rb->rev_offset, + SVN_ERR(commit_editor->delete_entry(nb->path, + rb->rev - rb->rev_offset - 1, rb->db->baton, rb->pool)); if (nb->action == svn_node_action_delete) break; Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/copy_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/copy_tests.py?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/cmdline/copy_tests.py (original) +++ subversion/branches/move-tracking-2/subversion/tests/cmdline/copy_tests.py Mon Mar 9 09:53:06 2015 @@ -545,7 +545,7 @@ def no_copy_overwrites(sbox): # Repeat the last command. It should *fail* because A/D/H/G already exists. svntest.actions.run_and_verify_svn( - None, ".*'/A/D/H/G'.*", + None, ".*E160020: Path.*/A/D/H/G' already exists.*", 'cp', dirURL1, dirURL2, '-m', 'fooogle') Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/entries-dump.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/entries-dump.c?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/cmdline/entries-dump.c (original) +++ subversion/branches/move-tracking-2/subversion/tests/cmdline/entries-dump.c Mon Mar 9 09:53:06 2015 @@ -74,12 +74,20 @@ entries_dump(const char *dir_path, svn_w apr_hash_index_t *hi; svn_boolean_t locked; svn_error_t *err; + svn_wc_context_t *wc_ctx = NULL; + const char *dir_abspath; + + SVN_ERR(svn_dirent_get_absolute(&dir_abspath, dir_path, pool)); err = svn_wc_adm_open3(&adm_access, related, dir_path, FALSE, 0, NULL, NULL, pool); if (!err) { - SVN_ERR(svn_wc_locked(&locked, dir_path, pool)); + SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, + svn_wc__adm_get_db(adm_access), + pool)); + + SVN_ERR(svn_wc_locked2(NULL, &locked, wc_ctx, dir_abspath, pool)); SVN_ERR(svn_wc_entries_read(&entries, adm_access, TRUE, pool)); } else if (err && err->apr_err == SVN_ERR_WC_LOCKED @@ -88,12 +96,17 @@ entries_dump(const char *dir_path, svn_w { /* Common caller error: Can't open a baton when there is one. */ svn_error_clear(err); - SVN_ERR(svn_wc_locked(&locked, dir_path, pool)); + + SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, + svn_wc__adm_get_db(related), + pool)); + + SVN_ERR(svn_wc_locked2(NULL, &locked, wc_ctx, dir_abspath, pool)); SVN_ERR(svn_wc_entries_read(&entries, related, TRUE, pool)); } else { - const char *dir_abspath, *lockfile_path; + const char *lockfile_path; svn_node_kind_t kind; /* ### Should svn_wc_adm_open3 be returning UPGRADE_REQUIRED? */ @@ -101,7 +114,6 @@ entries_dump(const char *dir_path, svn_w return err; svn_error_clear(err); adm_access = NULL; - SVN_ERR(svn_dirent_get_absolute(&dir_abspath, dir_path, pool)); SVN_ERR(svn_wc__read_entries_old(&entries, dir_abspath, pool, pool)); lockfile_path = svn_dirent_join_many(pool, dir_path, svn_wc_get_adm_dir(pool), @@ -161,6 +173,9 @@ entries_dump(const char *dir_path, svn_w printf("entries['%s'] = e\n", (const char *)key); } + if (wc_ctx) + SVN_ERR(svn_wc_context_destroy(wc_ctx)); + if (adm_access) SVN_ERR(svn_wc_adm_close2(adm_access, pool)); Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/externals_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/externals_tests.py?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/cmdline/externals_tests.py (original) +++ subversion/branches/move-tracking-2/subversion/tests/cmdline/externals_tests.py Mon Mar 9 09:53:06 2015 @@ -4086,6 +4086,75 @@ def nested_notification(sbox): svntest.actions.run_and_verify_svn(expected_output, [], 'update', sbox.ospath('D1')) +def file_external_to_normal_file(sbox): + "change a file external to a normal file" + + sbox.build() + wc_dir = sbox.wc_dir + sbox.simple_propset('svn:externals', '^/iota iota', 'A') + sbox.simple_commit() + + expected_status = svntest.actions.get_virginal_state(wc_dir, 2) + expected_status.add({ + 'A/iota' : Item(status=' ', wc_rev='2', switched='X'), + }) + expected_output = svntest.wc.State(wc_dir, { + 'A/iota' : Item(status='A '), + }) + + svntest.actions.run_and_verify_update(wc_dir, expected_output, None, + expected_status) + + # Create second working copy in this state + sbox2 = sbox.clone_dependent(copy_wc=True) + + sbox.simple_propdel('svn:externals', 'A') + + expected_output = svntest.wc.State(wc_dir, { + 'A/iota' : Item(verb='Removed external'), + }) + expected_status.remove('A/iota') + expected_status.tweak('A', status=' M') + svntest.actions.run_and_verify_update(wc_dir, expected_output, None, + expected_status) + + sbox.simple_copy('iota', 'A/iota') + sbox.simple_commit() + + expected_output = svntest.wc.State(wc_dir, { + }) + expected_status.tweak(wc_rev=3) + expected_status.tweak('A', status=' ') + expected_status.add({ + # This case used to triggered a switched status in 1.8.x before this + # test (and the fix for this problem) where added. + 'A/iota' : Item(status=' ', wc_rev='3'), + }) + svntest.actions.run_and_verify_update(wc_dir, expected_output, None, + expected_status) + + + wc_dir = sbox2.wc_dir + + expected_status = svntest.actions.get_virginal_state(wc_dir, 3) + expected_output = svntest.wc.State(wc_dir, { + 'A' : Item(status=' U'), + 'A/iota' : Item(verb='Removed external', prev_verb='Skipped'), + }) + # This reports an obstruction and removes the file external + svntest.actions.run_and_verify_update(wc_dir, expected_output, None, + expected_status) + + expected_status.add({ + 'A/iota' : Item(status=' ', wc_rev='3'), + }) + expected_output = svntest.wc.State(wc_dir, { + 'A/iota' : Item(status='A '), + }) + # This should bring in the new file + svntest.actions.run_and_verify_update(wc_dir, expected_output, None, + expected_status) + ######################################################################## # Run the tests @@ -4159,6 +4228,7 @@ test_list = [ None, copy_pin_externals_wc_mixed_revisions, copy_pin_externals_whitepace_dir, nested_notification, + file_external_to_normal_file, ] if __name__ == '__main__': Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/lock_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/lock_tests.py?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/cmdline/lock_tests.py (original) +++ subversion/branches/move-tracking-2/subversion/tests/cmdline/lock_tests.py Mon Mar 9 09:53:06 2015 @@ -2381,9 +2381,16 @@ def delete_dir_with_lots_of_locked_files svntest.actions.run_and_verify_svn(None, [], 'lock', '-m', 'All locks', *locked_paths) - # Locally delete A + # Locally delete A (regression against earlier versions, which + # always used a special non-standard request) sbox.simple_rm("A") + # But a further replacement never worked + sbox.simple_mkdir("A") + # And an additional propset didn't work either + # (but doesn't require all lock tokens recursively) + sbox.simple_propset("k", "v", "A") + # Commit the deletion # XFAIL: As of 1.8.10, this commit fails with: # svn: E175002: Unexpected HTTP status 400 'Bad Request' on '<path>' Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/stat_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/stat_tests.py?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/cmdline/stat_tests.py (original) +++ subversion/branches/move-tracking-2/subversion/tests/cmdline/stat_tests.py Mon Mar 9 09:53:06 2015 @@ -1598,44 +1598,81 @@ def status_dash_u_deleted_directories(sb # check status -u of B expected = svntest.verify.UnorderedOutput( - ["D 1 %s\n" % "B", - "D 1 %s\n" % os.path.join("B", "lambda"), - "D 1 %s\n" % os.path.join("B", "E"), - "D 1 %s\n" % os.path.join("B", "E", "alpha"), - "D 1 %s\n" % os.path.join("B", "E", "beta"), - "D 1 %s\n" % os.path.join("B", "F"), + ["D 1 1 jrandom %s\n" % \ + "B", + "D 1 1 jrandom %s\n" % \ + os.path.join("B", "lambda"), + "D 1 1 jrandom %s\n" % \ + os.path.join("B", "E"), + "D 1 1 jrandom %s\n" % \ + os.path.join("B", "E", "alpha"), + "D 1 1 jrandom %s\n" % \ + os.path.join("B", "E", "beta"), + "D 1 1 jrandom %s\n" % + os.path.join("B", "F"), "Status against revision: 1\n" ]) svntest.actions.run_and_verify_svn(expected, [], + "status", "-u", "-v", "B") + + expected = \ + ["D 1 %s\n" % "B", + "Status against revision: 1\n" ] + svntest.actions.run_and_verify_svn(expected, + [], "status", "-u", "B") + # again, but now from inside B, should give the same output if not os.path.exists('B'): os.mkdir('B') os.chdir("B") expected = svntest.verify.UnorderedOutput( - ["D 1 %s\n" % ".", - "D 1 %s\n" % "lambda", - "D 1 %s\n" % "E", - "D 1 %s\n" % os.path.join("E", "alpha"), - "D 1 %s\n" % os.path.join("E", "beta"), - "D 1 %s\n" % "F", + ["D 1 1 jrandom %s\n" % \ + ".", + "D 1 1 jrandom %s\n" % \ + "lambda", + "D 1 1 jrandom %s\n" % \ + "E", + "D 1 1 jrandom %s\n" % \ + os.path.join("E", "alpha"), + "D 1 1 jrandom %s\n" % \ + os.path.join("E", "beta"), + "D 1 1 jrandom %s\n" % \ + "F", "Status against revision: 1\n" ]) svntest.actions.run_and_verify_svn(expected, [], + "status", "-u", "-v", ".") + + expected = \ + ["D 1 %s\n" % ".", + "Status against revision: 1\n" ] + svntest.actions.run_and_verify_svn(expected, + [], "status", "-u", ".") # check status -u of B/E expected = svntest.verify.UnorderedOutput( - ["D 1 %s\n" % os.path.join("B", "E"), - "D 1 %s\n" % os.path.join("B", "E", "alpha"), - "D 1 %s\n" % os.path.join("B", "E", "beta"), + ["D 1 1 jrandom %s\n" % \ + os.path.join("B", "E"), + "D 1 1 jrandom %s\n" % \ + os.path.join("B", "E", "alpha"), + "D 1 1 jrandom %s\n" % \ + os.path.join("B", "E", "beta"), "Status against revision: 1\n" ]) os.chdir(was_cwd) os.chdir(A_path) svntest.actions.run_and_verify_svn(expected, [], + "status", "-u", "-v", + os.path.join("B", "E")) + + + expected = [ "Status against revision: 1\n" ] + svntest.actions.run_and_verify_svn(expected, + [], "status", "-u", os.path.join("B", "E")) Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/svnlook_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/svnlook_tests.py?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/cmdline/svnlook_tests.py (original) +++ subversion/branches/move-tracking-2/subversion/tests/cmdline/svnlook_tests.py Mon Mar 9 09:53:06 2015 @@ -695,7 +695,6 @@ fp.close()""" "Properties on '/A':\n", ' bogus_prop\n', ' svn:log\n', ' svn:author\n', - ' svn:check-locks\n', # internal prop, not really expected ' bogus_rev_prop\n', ' svn:date\n', ' svn:txn-client-compat-version\n', Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/svnsync_authz_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/svnsync_authz_tests.py?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/cmdline/svnsync_authz_tests.py (original) +++ subversion/branches/move-tracking-2/subversion/tests/cmdline/svnsync_authz_tests.py Mon Mar 9 09:53:06 2015 @@ -30,7 +30,7 @@ import sys, os # Test suite-specific modules -import locale, re, urllib +import locale, re # Our testing module import svntest @@ -471,8 +471,7 @@ def copy_delete_unreadable_child(sbox): src_authz + ':/A': '* =', }) - dest_url = svntest.main.file_scheme_prefix \ - + urllib.pathname2url(os.path.abspath(dest_sbox.repo_dir)) + dest_url = dest_sbox.file_protocol_repo_url() run_init(dest_url, sbox.repo_url) run_sync(dest_url) Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/svnsync_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/svnsync_tests.py?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/cmdline/svnsync_tests.py (original) +++ subversion/branches/move-tracking-2/subversion/tests/cmdline/svnsync_tests.py Mon Mar 9 09:53:06 2015 @@ -28,7 +28,7 @@ import sys, os # Test suite-specific modules -import re, urllib +import re # Our testing module import svntest @@ -131,16 +131,14 @@ def setup_and_sync(sbox, dump_file_conte repo_url = sbox.repo_url cwd = os.getcwd() if is_src_ra_local: - repo_url = svntest.main.file_scheme_prefix + \ - urllib.pathname2url(os.path.join(cwd, sbox.repo_dir)) + repo_url = sbox.file_protocol_repo_url() if subdir: repo_url = repo_url + subdir dest_repo_url = dest_sbox.repo_url if is_dest_ra_local: - dest_repo_url = svntest.main.file_scheme_prefix + \ - urllib.pathname2url(os.path.join(cwd, dest_sbox.repo_dir)) + dest_repo_url = dest_sbox.file_protocol_repo_url() run_init(dest_repo_url, repo_url, source_prop_encoding) run_sync(dest_repo_url, repo_url, Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/main.py URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/main.py?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/main.py (original) +++ subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/main.py Mon Mar 9 09:53:06 2015 @@ -112,7 +112,7 @@ class SVNRepositoryCreateFailure(Failure # Windows specifics if sys.platform == 'win32': windows = True - file_scheme_prefix = 'file:' + file_scheme_prefix = 'file:///' _exe = '.exe' _bat = '.bat' os.environ['SVN_DBG_STACKTRACES_TO_STDERR'] = 'y' @@ -1987,7 +1987,9 @@ def _create_parser(): parser.set_defaults( server_minor_version=SVN_VER_MINOR, url=file_scheme_prefix + \ - urllib.pathname2url(os.path.abspath(os.getcwd())), + svntest.wc.svn_uri_quote( + os.path.abspath( + os.getcwd()).replace(os.path.sep, '/')), http_library=_default_http_library) return parser @@ -2237,7 +2239,9 @@ def execute_tests(test_list, serial_only # Calculate pristine_greek_repos_url from test_area_url. pristine_greek_repos_url = options.test_area_url + '/' + \ - urllib.pathname2url(pristine_greek_repos_dir) + svntest.wc.svn_uri_quote( + pristine_greek_repos_dir.replace( + os.path.sep, '/')) if options.use_jsvn: if options.svn_bin is None: Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/sandbox.py URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/sandbox.py?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/sandbox.py (original) +++ subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/sandbox.py Mon Mar 9 09:53:06 2015 @@ -24,7 +24,6 @@ import os import shutil import copy -import urllib import logging import re @@ -114,7 +113,8 @@ class Sandbox: if empty or not read_only: # use a local repo self.repo_dir = os.path.join(svntest.main.general_repo_dir, self.name) self.repo_url = (svntest.main.options.test_area_url + '/' - + urllib.pathname2url(self.repo_dir)) + + svntest.wc.svn_uri_quote( + self.repo_dir.replace(os.path.sep, '/'))) self.add_test_path(self.repo_dir) else: self.repo_dir = svntest.main.pristine_greek_repos_dir @@ -195,7 +195,8 @@ class Sandbox: path = (os.path.join(svntest.main.general_repo_dir, self.name) + '.' + suffix) url = svntest.main.options.test_area_url + \ - '/' + urllib.pathname2url(path) + '/' + svntest.wc.svn_uri_quote( + path.replace(os.path.sep, '/')) self.add_test_path(path, remove) return path, url @@ -276,6 +277,12 @@ class Sandbox: temporary and 'TEMP' or 'PERM', parts[1]) + def file_protocol_repo_url(self): + """get a file:// url pointing to the repository""" + return svntest.main.file_scheme_prefix + \ + svntest.wc.svn_uri_quote( + os.path.abspath(self.repo_dir).replace(os.path.sep, '/')) + def simple_update(self, target=None, revision='HEAD'): """Update the WC or TARGET. TARGET is a relpath relative to the WC.""" Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/wc.py URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/wc.py?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/wc.py (original) +++ subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/wc.py Mon Mar 9 09:53:06 2015 @@ -1035,6 +1035,16 @@ def sqlite_stmt(wc_root_path, stmt): c.execute(stmt) return c.fetchall() +def sqlite_exec(wc_root_path, stmt): + """Execute STMT on the SQLite wc.db in WC_ROOT_PATH and return the + results.""" + + db = open_wc_db(wc_root_path)[0] + c = db.cursor() + c.execute(stmt) + db.commit() + + # ------------ ### probably toss these at some point. or major rework. or something. ### just bootstrapping some changes for now. Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/upgrade_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/upgrade_tests.py?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/cmdline/upgrade_tests.py (original) +++ subversion/branches/move-tracking-2/subversion/tests/cmdline/upgrade_tests.py Mon Mar 9 09:53:06 2015 @@ -1438,6 +1438,42 @@ def upgrade_1_7_dir_external(sbox): # svn: warning: W200033: sqlite[S5]: database is locked svntest.actions.run_and_verify_svn(None, [], 'upgrade', sbox.wc_dir) +def auto_analyze(sbox): + """automatic SQLite ANALYZE""" + + sbox.build(create_wc = False) + + replace_sbox_with_tarfile(sbox, 'wc-without-stat1.tar.bz2') + svntest.main.run_svnadmin('setuuid', sbox.repo_dir, + '52ec7e4b-e5f0-451d-829f-f05d5571b4ab') + + # Don't use svn to do relocate as that will add the table. + val = svntest.wc.sqlite_exec(sbox.wc_dir, + "update repository " + "set root ='" + sbox.repo_url + "'"); + + # Make working copy read-only (but not wc_dir itself as + # svntest.main.chmod_tree will not reset it.) + for path, subdirs, files in os.walk(sbox.wc_dir): + for d in subdirs: + os.chmod(os.path.join(path, d), 0555) + for f in files: + os.chmod(os.path.join(path, f), 0444) + + state = svntest.actions.get_virginal_state(sbox.wc_dir, 1) + svntest.actions.run_and_verify_status(sbox.wc_dir, state) + + svntest.main.chmod_tree(sbox.wc_dir, 0666, 0022) + + state = svntest.actions.get_virginal_state(sbox.wc_dir, 1) + svntest.actions.run_and_verify_status(sbox.wc_dir, state) + + val = svntest.wc.sqlite_stmt(sbox.wc_dir, + "select 1 from sqlite_master " + "where name = 'sqlite_stat1'") + if val != [(1,)]: + raise svntest.Failure("analyze failed") + ######################################################################## # Run the tests @@ -1494,6 +1530,7 @@ test_list = [ None, iprops_upgrade1_6, changelist_upgrade_1_6, upgrade_1_7_dir_external, + auto_analyze, ] Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c (original) +++ subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c Mon Mar 9 09:53:06 2015 @@ -5167,6 +5167,17 @@ test_fs_info_format(const svn_test_opts_ return SVN_NO_ERROR; } +/* Sleeps until apr_time_now() value changes. */ +static void sleep_for_timestamps(void) +{ + apr_time_t start = apr_time_now(); + + while (start == apr_time_now()) + { + apr_sleep(APR_USEC_PER_SEC / 1000); + } +} + static svn_error_t * commit_timestamp(const svn_test_opts_t *opts, apr_pool_t *pool) @@ -5178,6 +5189,7 @@ commit_timestamp(const svn_test_opts_t * svn_revnum_t rev = 0; apr_hash_t *proplist; svn_string_t *svn_date; + svn_string_t *txn_svn_date; SVN_ERR(svn_test__create_fs(&fs, "test-fs-commit-timestamp", opts, pool)); @@ -5196,29 +5208,6 @@ commit_timestamp(const svn_test_opts_t * /* Commit that overwrites the specified svn:date. */ SVN_ERR(svn_fs_begin_txn(&txn, fs, rev, pool)); - { - /* Setting the internal property doesn't enable svn:date behaviour. */ - apr_array_header_t *props = apr_array_make(pool, 3, sizeof(svn_prop_t)); - svn_prop_t prop, other_prop1, other_prop2; - svn_string_t *val; - - prop.name = SVN_FS__PROP_TXN_CLIENT_DATE; - prop.value = svn_string_create("1", pool); - other_prop1.name = "foo"; - other_prop1.value = svn_string_create("fooval", pool); - other_prop2.name = "bar"; - other_prop2.value = svn_string_create("barval", pool); - APR_ARRAY_PUSH(props, svn_prop_t) = other_prop1; - APR_ARRAY_PUSH(props, svn_prop_t) = prop; - APR_ARRAY_PUSH(props, svn_prop_t) = other_prop2; - SVN_ERR(svn_fs_change_txn_props(txn, props, pool)); - SVN_ERR(svn_fs_txn_prop(&val, txn, other_prop1.name, pool)); - SVN_TEST_ASSERT(val && !strcmp(val->data, other_prop1.value->data)); - SVN_ERR(svn_fs_txn_prop(&val, txn, other_prop2.name, pool)); - SVN_TEST_ASSERT(val && !strcmp(val->data, other_prop2.value->data)); - - SVN_ERR(svn_fs_change_txn_prop(txn, prop.name, prop.value, pool)); - } SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); SVN_ERR(svn_fs_make_dir(txn_root, "/bar", pool)); SVN_ERR(svn_fs_change_txn_prop(txn, SVN_PROP_REVISION_DATE, date, pool)); @@ -5257,6 +5246,37 @@ commit_timestamp(const svn_test_opts_t * APR_HASH_KEY_STRING); SVN_TEST_ASSERT(svn_date); + /* Commit that doesn't do anything special about svn:date. */ + SVN_ERR(svn_fs_begin_txn2(&txn, fs, rev, 0, pool)); + SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); + SVN_ERR(svn_fs_make_dir(txn_root, "/zig/foo", pool)); + SVN_ERR(svn_fs_txn_prop(&txn_svn_date, txn, SVN_PROP_REVISION_DATE, pool)); + SVN_TEST_ASSERT(txn_svn_date); + sleep_for_timestamps(); + SVN_ERR(svn_fs_commit_txn(NULL, &rev, txn, pool)); + + SVN_ERR(svn_fs_revision_proplist(&proplist, fs, rev, pool)); + svn_date = apr_hash_get(proplist, SVN_PROP_REVISION_DATE, + APR_HASH_KEY_STRING); + SVN_TEST_ASSERT(svn_date); + SVN_TEST_ASSERT(!svn_string_compare(svn_date, txn_svn_date)); + + /* Commit that instructs the backend to use a specific svn:date, but + * doesn't provide one. This used to fail with BDB prior to r1663697. */ + SVN_ERR(svn_fs_begin_txn2(&txn, fs, rev, SVN_FS_TXN_CLIENT_DATE, pool)); + SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); + SVN_ERR(svn_fs_make_dir(txn_root, "/zig/bar", pool)); + SVN_ERR(svn_fs_txn_prop(&txn_svn_date, txn, SVN_PROP_REVISION_DATE, pool)); + SVN_TEST_ASSERT(txn_svn_date); + sleep_for_timestamps(); + SVN_ERR(svn_fs_commit_txn(NULL, &rev, txn, pool)); + + SVN_ERR(svn_fs_revision_proplist(&proplist, fs, rev, pool)); + svn_date = apr_hash_get(proplist, SVN_PROP_REVISION_DATE, + APR_HASH_KEY_STRING); + SVN_TEST_ASSERT(svn_date); + SVN_TEST_ASSERT(!svn_string_compare(svn_date, txn_svn_date)); + return SVN_NO_ERROR; } @@ -6698,6 +6718,70 @@ test_prop_and_text_rep_sharing_collision return SVN_NO_ERROR; } +static svn_error_t * +test_internal_txn_props(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_fs_t *fs; + svn_fs_txn_t *txn; + svn_string_t *val; + svn_prop_t prop; + svn_prop_t internal_prop; + apr_array_header_t *props; + apr_hash_t *proplist; + svn_error_t *err; + + SVN_ERR(svn_test__create_fs(&fs, "test-repo-internal-txn-props", + opts, pool)); + SVN_ERR(svn_fs_begin_txn2(&txn, fs, 0, + SVN_FS_TXN_CHECK_LOCKS | + SVN_FS_TXN_CHECK_OOD | + SVN_FS_TXN_CLIENT_DATE, pool)); + + /* Ensure that we cannot read internal transaction properties. */ + SVN_ERR(svn_fs_txn_prop(&val, txn, SVN_FS__PROP_TXN_CHECK_LOCKS, pool)); + SVN_TEST_ASSERT(!val); + SVN_ERR(svn_fs_txn_prop(&val, txn, SVN_FS__PROP_TXN_CHECK_OOD, pool)); + SVN_TEST_ASSERT(!val); + SVN_ERR(svn_fs_txn_prop(&val, txn, SVN_FS__PROP_TXN_CLIENT_DATE, pool)); + SVN_TEST_ASSERT(!val); + + SVN_ERR(svn_fs_txn_proplist(&proplist, txn, pool)); + SVN_TEST_ASSERT(apr_hash_count(proplist) == 1); + val = svn_hash_gets(proplist, SVN_PROP_REVISION_DATE); + SVN_TEST_ASSERT(val); + + /* We also cannot change or discard them. */ + val = svn_string_create("Ooops!", pool); + + err = svn_fs_change_txn_prop(txn, SVN_FS__PROP_TXN_CHECK_LOCKS, val, pool); + SVN_TEST_ASSERT_ERROR(err, SVN_ERR_INCORRECT_PARAMS); + err = svn_fs_change_txn_prop(txn, SVN_FS__PROP_TXN_CHECK_LOCKS, NULL, pool); + SVN_TEST_ASSERT_ERROR(err, SVN_ERR_INCORRECT_PARAMS); + err = svn_fs_change_txn_prop(txn, SVN_FS__PROP_TXN_CHECK_OOD, val, pool); + SVN_TEST_ASSERT_ERROR(err, SVN_ERR_INCORRECT_PARAMS); + err = svn_fs_change_txn_prop(txn, SVN_FS__PROP_TXN_CHECK_OOD, NULL, pool); + SVN_TEST_ASSERT_ERROR(err, SVN_ERR_INCORRECT_PARAMS); + err = svn_fs_change_txn_prop(txn, SVN_FS__PROP_TXN_CLIENT_DATE, val, pool); + SVN_TEST_ASSERT_ERROR(err, SVN_ERR_INCORRECT_PARAMS); + err = svn_fs_change_txn_prop(txn, SVN_FS__PROP_TXN_CLIENT_DATE, NULL, pool); + SVN_TEST_ASSERT_ERROR(err, SVN_ERR_INCORRECT_PARAMS); + + prop.name = "foo"; + prop.value = svn_string_create("bar", pool); + internal_prop.name = SVN_FS__PROP_TXN_CHECK_LOCKS; + internal_prop.value = svn_string_create("Ooops!", pool); + + props = apr_array_make(pool, 2, sizeof(svn_prop_t)); + APR_ARRAY_PUSH(props, svn_prop_t) = prop; + APR_ARRAY_PUSH(props, svn_prop_t) = internal_prop; + + err = svn_fs_change_txn_props(txn, props, pool); + SVN_TEST_ASSERT_ERROR(err, SVN_ERR_INCORRECT_PARAMS); + + return SVN_NO_ERROR; +} + /* ------------------------------------------------------------------------ */ /* The test table. */ @@ -6829,6 +6913,8 @@ static struct svn_test_descriptor_t test "test modify txn being written in FSFS"), SVN_TEST_OPTS_PASS(test_prop_and_text_rep_sharing_collision, "test property and text rep-sharing collision"), + SVN_TEST_OPTS_PASS(test_internal_txn_props, + "test setting and getting internal txn props"), SVN_TEST_NULL }; Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_ra/ra-test.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_ra/ra-test.c?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/libsvn_ra/ra-test.c (original) +++ subversion/branches/move-tracking-2/subversion/tests/libsvn_ra/ra-test.c Mon Mar 9 09:53:06 2015 @@ -651,7 +651,7 @@ commit_callback_failure(const svn_test_o apr_hash_make(pool), commit_callback_with_failure, NULL, NULL, FALSE, pool)); - SVN_ERR(editor->open_root(edit_baton, 1, pool, &root_baton)); + SVN_ERR(editor->open_root(edit_baton, 0, pool, &root_baton)); SVN_ERR(editor->change_dir_prop(root_baton, "A", svn_string_create("B", pool), pool)); SVN_ERR(editor->close_directory(root_baton, pool)); @@ -664,6 +664,99 @@ commit_callback_failure(const svn_test_o return SVN_NO_ERROR; } +static svn_error_t * +base_revision_above_youngest(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_ra_session_t *ra_session; + const svn_delta_editor_t *editor; + void *edit_baton; + void *root_baton; + svn_error_t *err; + SVN_ERR(make_and_open_repos(&ra_session, "base_revision_above_youngest", + opts, pool)); + + SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton, + apr_hash_make(pool), NULL, + NULL, NULL, FALSE, pool)); + + /* r1 doesn't exist, but we say we want to apply changes against this + revision to see how the ra layers behave. + + Some will see an error directly on open_root, others in a later + state. */ + + /* ra-local and http pre-v2 will see the error here */ + err = editor->open_root(edit_baton, 1, pool, &root_baton); + + if (!err) + err = editor->change_dir_prop(root_baton, "A", + svn_string_create("B", pool), pool); + + /* http v2 will notice it here (PROPPATCH) */ + if (!err) + err = editor->close_directory(root_baton, pool); + + /* ra svn only notes it at some later point. Typically here */ + if (!err) + err = editor->close_edit(edit_baton, pool); + + SVN_TEST_ASSERT_ERROR(err, + SVN_ERR_FS_NO_SUCH_REVISION); + + SVN_ERR(editor->abort_edit(edit_baton, pool)); + return SVN_NO_ERROR; +} + +static svn_error_t * +delete_revision_above_youngest(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_ra_session_t *ra_session; + const svn_delta_editor_t *editor; + svn_error_t *err; + void *edit_baton; + + SVN_ERR(make_and_open_repos(&ra_session, "delete_revision_above_youngest", + opts, pool)); + + SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton, + apr_hash_make(pool), NULL, + NULL, NULL, FALSE, pool)); + + { + void *root_baton; + void *dir_baton; + + SVN_ERR(editor->open_root(edit_baton, 0, pool, &root_baton)); + SVN_ERR(editor->add_directory("A", root_baton, NULL, SVN_INVALID_REVNUM, + pool, &dir_baton)); + SVN_ERR(editor->close_directory(dir_baton, pool)); + SVN_ERR(editor->close_edit(edit_baton, pool)); + } + + SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton, + apr_hash_make(pool), NULL, + NULL, NULL, FALSE, pool)); + + { + void *root_baton; + SVN_ERR(editor->open_root(edit_baton, 1, pool, &root_baton)); + + /* Now we supply r2, while HEAD is r1 */ + err = editor->delete_entry("A", 2, root_baton, pool); + + if (!err) + err = editor->close_edit(edit_baton, pool); + + SVN_TEST_ASSERT_ERROR(err, + SVN_ERR_FS_NO_SUCH_REVISION); + + SVN_ERR(editor->abort_edit(edit_baton, pool)); + } + return SVN_NO_ERROR; +} + /* The test table. */ @@ -684,6 +777,10 @@ static struct svn_test_descriptor_t test "test ra_get_dir2"), SVN_TEST_OPTS_PASS(commit_callback_failure, "commit callback failure"), + SVN_TEST_OPTS_PASS(base_revision_above_youngest, + "base revision newer than youngest"), + SVN_TEST_OPTS_PASS(delete_revision_above_youngest, + "delete revision newer than youngest"), SVN_TEST_NULL }; Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/conflict-data-test.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/conflict-data-test.c?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/conflict-data-test.c (original) +++ subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/conflict-data-test.c Mon Mar 9 09:53:06 2015 @@ -809,6 +809,108 @@ test_prop_conflicts(const svn_test_opts_ return SVN_NO_ERROR; } +static svn_error_t * +test_prop_conflict_resolving(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_test__sandbox_t b; + svn_skel_t *conflict; + const char *A_abspath; + const char *marker_abspath; + apr_hash_t *conflicted_props; + apr_hash_t *props; + const char *value; + + SVN_ERR(svn_test__sandbox_create(&b, "test_prop_resolving", opts, pool)); + SVN_ERR(sbox_wc_mkdir(&b, "A")); + + SVN_ERR(sbox_wc_propset(&b, "prop-1", "r1", "A")); + SVN_ERR(sbox_wc_propset(&b, "prop-2", "r1", "A")); + SVN_ERR(sbox_wc_propset(&b, "prop-3", "r1", "A")); + SVN_ERR(sbox_wc_propset(&b, "prop-4", "r1", "A")); + SVN_ERR(sbox_wc_propset(&b, "prop-5", "r1", "A")); + SVN_ERR(sbox_wc_propset(&b, "prop-6", "r1", "A")); + + SVN_ERR(sbox_wc_commit(&b, "")); + SVN_ERR(sbox_wc_propset(&b, "prop-1", "r2", "A")); + SVN_ERR(sbox_wc_propset(&b, "prop-2", "r2", "A")); + SVN_ERR(sbox_wc_propset(&b, "prop-3", "r2", "A")); + SVN_ERR(sbox_wc_propset(&b, "prop-4", NULL, "A")); + SVN_ERR(sbox_wc_propset(&b, "prop-5", NULL, "A")); + SVN_ERR(sbox_wc_propset(&b, "prop-7", "r2", "A")); + SVN_ERR(sbox_wc_propset(&b, "prop-8", "r2", "A")); + SVN_ERR(sbox_wc_commit(&b, "")); + + SVN_ERR(sbox_wc_propset(&b, "prop-1", "mod", "A")); + SVN_ERR(sbox_wc_propset(&b, "prop-2", "mod", "A")); + SVN_ERR(sbox_wc_propset(&b, "prop-3", "mod", "A")); + SVN_ERR(sbox_wc_propset(&b, "prop-4", "mod", "A")); + SVN_ERR(sbox_wc_propset(&b, "prop-5", "mod", "A")); + SVN_ERR(sbox_wc_propset(&b, "prop-6", "mod", "A")); + SVN_ERR(sbox_wc_propset(&b, "prop-7", "mod", "A")); + SVN_ERR(sbox_wc_propset(&b, "prop-8", "mod", "A")); + + SVN_ERR(sbox_wc_update(&b, "", 1)); + + A_abspath = sbox_wc_path(&b, "A"); + SVN_ERR(svn_wc__db_read_conflict(&conflict, NULL, + b.wc_ctx->db, A_abspath, + pool, pool)); + + /* We have tree conflicts... */ + SVN_TEST_ASSERT(conflict != NULL); + + SVN_ERR(svn_wc__conflict_read_prop_conflict(&marker_abspath, + NULL, NULL, NULL, + &conflicted_props, + b.wc_ctx->db, A_abspath, + conflict, + pool, pool)); + + SVN_TEST_ASSERT(conflicted_props != NULL); + /* All properties but r6 are conflicted */ + SVN_TEST_ASSERT(apr_hash_count(conflicted_props) == 7); + SVN_TEST_ASSERT(! svn_hash_gets(conflicted_props, "prop-6")); + + /* Let's resolve a few conflicts */ + SVN_ERR(sbox_wc_resolve_prop(&b, "A", "prop-1", + svn_wc_conflict_choose_mine_conflict)); + SVN_ERR(sbox_wc_resolve_prop(&b, "A", "prop-2", + svn_wc_conflict_choose_theirs_conflict)); + SVN_ERR(sbox_wc_resolve_prop(&b, "A", "prop-3", + svn_wc_conflict_choose_merged)); + + SVN_ERR(svn_wc__db_read_conflict(&conflict, NULL, + b.wc_ctx->db, A_abspath, + pool, pool)); + + /* We have tree conflicts... */ + SVN_TEST_ASSERT(conflict != NULL); + + SVN_ERR(svn_wc__conflict_read_prop_conflict(&marker_abspath, + NULL, NULL, NULL, + &conflicted_props, + b.wc_ctx->db, A_abspath, + conflict, + pool, pool)); + + SVN_TEST_ASSERT(conflicted_props != NULL); + SVN_TEST_ASSERT(apr_hash_count(conflicted_props) == 4); + + SVN_ERR(svn_wc__db_read_props(&props, b.wc_ctx->db, A_abspath, + pool, pool)); + + value = svn_prop_get_value(props, "prop-1"); + SVN_TEST_STRING_ASSERT(value, "mod"); + value = svn_prop_get_value(props, "prop-2"); + SVN_TEST_STRING_ASSERT(value, "r1"); + value = svn_prop_get_value(props, "prop-3"); + SVN_TEST_STRING_ASSERT(value, "mod"); + + return SVN_NO_ERROR; +} + + /* The test table. */ static int max_threads = 1; @@ -830,6 +932,8 @@ static struct svn_test_descriptor_t test "read and write a tree conflict"), SVN_TEST_OPTS_PASS(test_prop_conflicts, "test prop conflicts"), + SVN_TEST_OPTS_PASS(test_prop_conflict_resolving, + "test property conflict resolving"), SVN_TEST_NULL }; Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/op-depth-test.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/op-depth-test.c?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/op-depth-test.c (original) +++ subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/op-depth-test.c Mon Mar 9 09:53:06 2015 @@ -310,16 +310,17 @@ check_db_rows(svn_test__sandbox_t *b, row->repo_revnum = svn_sqlite__column_revnum(stmt, 3); row->repo_relpath = svn_sqlite__column_text(stmt, 4, b->pool); row->file_external = !svn_sqlite__column_is_null(stmt, 5); - if (row->file_external && svn_sqlite__column_is_null(stmt, 6)) - comparison_baton.errors - = svn_error_createf(SVN_ERR_TEST_FAILED, comparison_baton.errors, - "incomplete {%s}", print_row(row, b->pool)); row->moved_to = svn_sqlite__column_text(stmt, 7, b->pool); row->moved_here = svn_sqlite__column_boolean(stmt, 8); SVN_ERR(svn_sqlite__column_properties(&props_hash, stmt, 9, b->pool, b->pool)); row->props = props_hash_to_text(props_hash, b->pool); + if (row->file_external && svn_sqlite__column_is_null(stmt, 6)) + comparison_baton.errors + = svn_error_createf(SVN_ERR_TEST_FAILED, comparison_baton.errors, + "incomplete {%s}", print_row(row, b->pool)); + key = apr_psprintf(b->pool, "%d %s", row->op_depth, row->local_relpath); apr_hash_set(found_hash, key, APR_HASH_KEY_STRING, row); @@ -3582,11 +3583,13 @@ revert_file_externals(const svn_test_opt SVN_ERR(sbox_wc_update(&b, "", 1)); { nodes_row_t rows[] = { - { 0, "", "normal", 1, "" }, - { 0, "f", "normal", 1, "f" }, - { 1, "A", "normal", NO_COPY_FROM }, - { 0, "h", "normal", 1, "f", TRUE }, - { 0, "A/g", "normal", 1, "f", TRUE }, + { 0, "", "normal", 1, "" }, + { 0, "f", "normal", 1, "f" }, + { 1, "A", "normal", NO_COPY_FROM }, + { 0, "h", "normal", 1, "f", TRUE }, + { 0, "A/g", "normal", 1, "f", TRUE }, + + { 0, "g", "not-present", 0, "g"}, { 0 } }; SVN_ERR(check_db_rows(&b, "", rows)); @@ -3595,10 +3598,12 @@ revert_file_externals(const svn_test_opt SVN_ERR(sbox_wc_revert(&b, "", svn_depth_infinity)); { nodes_row_t rows[] = { - { 0, "", "normal", 1, "" }, - { 0, "f", "normal", 1, "f" }, - { 0, "h", "normal", 1, "f", TRUE }, - { 0, "A/g", "normal", 1, "f", TRUE }, + { 0, "", "normal", 1, "" }, + { 0, "f", "normal", 1, "f" }, + { 0, "h", "normal", 1, "f", TRUE }, + { 0, "A/g", "normal", 1, "f", TRUE }, + + { 0, "g", "not-present", 0, "g"}, { 0 } }; SVN_ERR(check_db_rows(&b, "", rows)); @@ -3607,9 +3612,11 @@ revert_file_externals(const svn_test_opt SVN_ERR(sbox_wc_update(&b, "", 1)); { nodes_row_t rows[] = { - { 0, "", "normal", 1, "" }, - { 0, "f", "normal", 1, "f" }, - { 0, "g", "normal", 1, "f", TRUE }, + { 0, "", "normal", 1, "" }, + { 0, "f", "normal", 1, "f" }, + { 0, "g", "normal", 1, "f", TRUE }, + + { 0, "h", "not-present", 0, "h"}, { 0 } }; SVN_ERR(check_db_rows(&b, "", rows)); Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/utils.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/utils.c?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/utils.c (original) +++ subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/utils.c Mon Mar 9 09:53:06 2015 @@ -599,6 +599,35 @@ sbox_wc_resolve(svn_test__sandbox_t *b, } svn_error_t * +sbox_wc_resolve_prop(svn_test__sandbox_t *b, const char *path, + const char *propname, + svn_wc_conflict_choice_t conflict_choice) +{ + const char *lock_abspath; + svn_error_t *err; + + SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, b->wc_ctx, + sbox_wc_path(b, path), + b->pool, b->pool)); + err = svn_wc__resolve_conflicts(b->wc_ctx, sbox_wc_path(b, path), + svn_depth_empty, + FALSE, + propname, + FALSE, + conflict_choice, + NULL, NULL, /* conflict func */ + NULL, NULL, /* cancellation */ + NULL, NULL, /* notification */ + b->pool); + + err = svn_error_compose_create(err, svn_wc__release_write_lock(b->wc_ctx, + lock_abspath, + b->pool)); + return err; +} + + +svn_error_t * sbox_wc_move(svn_test__sandbox_t *b, const char *src, const char *dst) { svn_client_ctx_t *ctx; Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/utils.h URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/utils.h?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/utils.h (original) +++ subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/utils.h Mon Mar 9 09:53:06 2015 @@ -166,6 +166,12 @@ sbox_wc_resolve(svn_test__sandbox_t *b, /* */ svn_error_t * +sbox_wc_resolve_prop(svn_test__sandbox_t *b, const char *path, + const char *propname, + svn_wc_conflict_choice_t conflict_choice); + +/* */ +svn_error_t * sbox_wc_move(svn_test__sandbox_t *b, const char *src, const char *dst); /* Set property NAME to VALUE on PATH. If VALUE=NULL, delete the property. */ Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/wc-queries-test.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/wc-queries-test.c?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/wc-queries-test.c (original) +++ subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/wc-queries-test.c Mon Mar 9 09:53:06 2015 @@ -108,6 +108,7 @@ static const int slow_statements[] = /* Slow, but just if foreign keys are enabled: * STMT_DELETE_PRISTINE_IF_UNREFERENCED, */ + STMT_HAVE_STAT1_TABLE, /* Queries sqlite_master which has no index */ -1 /* final marker */ }; Modified: subversion/branches/move-tracking-2/subversion/tests/svn_test_main.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/svn_test_main.c?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/svn_test_main.c (original) +++ subversion/branches/move-tracking-2/subversion/tests/svn_test_main.c Mon Mar 9 09:53:06 2015 @@ -158,29 +158,46 @@ static const apr_getopt_option_t cl_opti /* When non-zero, don't remove test directories */ static svn_boolean_t skip_cleanup = FALSE; -/* All cleanup actions are registered as cleanups on this pool. */ -#if !defined(thread_local) && APR_HAS_THREADS +/* All cleanup actions are registered as cleanups on the cleanup_pool, + * which may be thread-specific. */ +#if APR_HAS_THREADS +/* The thread-local data key for the cleanup pool. */ +static apr_threadkey_t *cleanup_pool_key = NULL; -# if __STDC_VERSION__ >= 201112 && !defined __STDC_NO_THREADS__ -# define thread_local _Thread_local -# elif defined(WIN32) && defined(_MSC_VER) -# define thread_local __declspec(thread) -# elif defined(__thread) - /* ### Might work somewhere? */ -# define thread_local __thread -# else - /* gcc defines __thread in some versions, but not all. - ### Who knows how to check for this? - ### stackoverflow recommends __GNUC__ but that breaks on - ### openbsd. */ -# endif -#endif +/* No-op destructor for apr_threadkey_private_create(). */ +static void null_threadkey_dtor(void *stuff) {} + +/* Set the thread-specific cleanup pool. */ +static void set_cleanup_pool(apr_pool_t *pool) +{ + apr_status_t status = apr_threadkey_private_set(pool, cleanup_pool_key); + if (status) + { + printf("apr_threadkey_private_set() failed with code %ld.\n", + (long)status); + exit(1); + } +} -#ifdef thread_local -#define HAVE_PER_THREAD_CLEANUP -static thread_local apr_pool_t * cleanup_pool = NULL; +/* Get the thread-specific cleanup pool. */ +static apr_pool_t *get_cleanup_pool(void) +{ + void *data; + apr_status_t status = apr_threadkey_private_get(&data, cleanup_pool_key); + if (status) + { + printf("apr_threadkey_private_get() failed with code %ld.\n", + (long)status); + exit(1); + } + return data; +} + +# define cleanup_pool (get_cleanup_pool()) +# define HAVE_PER_THREAD_CLEANUP #else static apr_pool_t *cleanup_pool = NULL; +# define set_cleanup_pool(p) (cleanup_pool = (p)) #endif /* Used by test_thread to serialize access to stdout. */ @@ -508,7 +525,7 @@ test_thread(apr_thread_t *thread, void * = apr_allocator_owner_get(svn_pool_create_allocator(FALSE)); #ifdef HAVE_PER_THREAD_CLEANUP - cleanup_pool = svn_pool_create(thread_root); + set_cleanup_pool(svn_pool_create(thread_root)); #endif pool = svn_pool_create(thread_root); @@ -780,6 +797,19 @@ svn_test_main(int argc, const char *argv svn_error_clear(err); } + /* Set up the thread-local storage key for the cleanup pool. */ +#ifdef HAVE_PER_THREAD_CLEANUP + apr_err = apr_threadkey_private_create(&cleanup_pool_key, + null_threadkey_dtor, + pool); + if (apr_err) + { + printf("apr_threadkey_private_create() failed with code %ld.\n", + (long)apr_err); + exit(1); + } +#endif /* HAVE_PER_THREAD_CLEANUP */ + /* Remember the command line */ test_argc = argc; test_argv = argv; @@ -954,7 +984,7 @@ svn_test_main(int argc, const char *argv } /* Create an iteration pool for the tests */ - cleanup_pool = svn_pool_create(pool); + set_cleanup_pool(svn_pool_create(pool)); test_pool = svn_pool_create(pool); if (!allow_segfaults) Propchange: subversion/branches/move-tracking-2/tools/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Mon Mar 9 09:53:06 2015 @@ -82,4 +82,4 @@ /subversion/branches/verify-at-commit/tools:1462039-1462408 /subversion/branches/verify-keep-going/tools:1439280-1546110 /subversion/branches/wc-collate-path/tools:1402685-1480384 -/subversion/trunk/tools:1606692-1663280 +/subversion/trunk/tools:1606692-1665165 Modified: subversion/branches/move-tracking-2/tools/dist/backport.pl URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/tools/dist/backport.pl?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/tools/dist/backport.pl (original) +++ subversion/branches/move-tracking-2/tools/dist/backport.pl Mon Mar 9 09:53:06 2015 @@ -3,7 +3,18 @@ use warnings; use strict; use feature qw/switch say/; -#no warnings 'experimental::smartmatch'; +use v5.10.0; # needed for $^V + +# The given/when smartmatch facility, introduced in Perl v5.10, was made +# experimental and "subject to change" in v5.18 (see perl5180delta). Every +# use of it now triggers a warning. +# +# As of Perl v5.20.1, the semantics of given/when provided by Perl are +# compatible with those expected by the script, so disable the warning for +# those Perls. But don't try to disable the the warning category on Perls +# that don't know that category, since that breaks compilation. +no if (v5.17.0 le $^V and $^V le v5.20.1), + warnings => 'experimental::smartmatch'; # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file @@ -124,6 +135,39 @@ $SVNq = "$SVN -q "; $SVNq =~ s/-q// if $DEBUG; +my $BACKPORT_OPTIONS_HELP = <<EOF; +y: Run a merge. It will not be committed. + WARNING: This will run 'update' and 'revert -R ./'. +l: Show logs for the entries being nominated. +v: Show the full entry (the prompt only shows an abridged version). +q: Quit the "for each entry" loop. If you have entered any votes or + approvals, you will be prompted to commit them. +±1: Enter a +1 or -1 vote + You will be prompted to commit your vote at the end. +±0: Enter a +0 or -0 vote + You will be prompted to commit your vote at the end. +a: Move the entry to the "Approved changes" section. + When both approving and voting on an entry, approve first: for example, + to enter a third +1 vote, type "a" "+" "1". +e: Edit the entry in \$EDITOR, which is '$EDITOR'. + You will be prompted to commit your edits at the end. +N: Move to the next entry. Do not prompt for the current entry again, even + in future runs, unless the STATUS nomination has been modified (e.g., + revisions added, justification changed) in the repository. + (This is a local action that will not affect other people or bots.) + : Move to the next entry. Prompt for the current entry again in the next + run of backport.pl. + (That's a space character, ASCII 0x20.) +?: Display this list. +EOF + +my $BACKPORT_OPTIONS_MERGE_OPTIONS_HELP = <<EOF; +y: Open a shell. +d: View a diff. +N: Move to the next entry. +?: Display this list. +EOF + sub backport_usage { my $basename = basename $0; print <<EOF; @@ -153,30 +197,11 @@ sense of "match" is either substring (fg In interactive mode (the default), you will be prompted once per STATUS entry. At a prompt, you have the following options: -y: Run a merge. It will not be committed. - WARNING: This will run 'update' and 'revert -R ./'. -l: Show logs for the entries being nominated. -v: Show the full entry (the prompt only shows an abridged version). -q: Quit the "for each nomination" loop. -±1: Enter a +1 or -1 vote - You will be prompted to commit your vote at the end. -±0: Enter a +0 or -0 vote - You will be prompted to commit your vote at the end. -a: Move the entry to the "Approved changes" section. - When both approving and voting on an entry, approve first: for example, - to enter a third +1 vote, type "a" "+" "1". -e: Edit the entry in $EDITOR. - You will be prompted to commit your edits at the end. -N: Move to the next entry. Cache the entry in '$STATEFILE' and do not - prompt for it again (even across runs) until it is changed. - : Move to the next entry, without adding the current one to the cache. - (That's a space character, ASCII 0x20.) +$BACKPORT_OPTIONS_HELP After running a merge, you have the following options: -y: Open a shell. -d: View a diff. -N: Move to the next entry. +$BACKPORT_OPTIONS_MERGE_OPTIONS_HELP To commit a merge, you have two options: either answer 'y' to the second prompt to open a shell, and manually run 'svn commit' therein; or set \$MAY_COMMIT=1 @@ -1006,13 +1031,13 @@ sub handle_entry { # See above for why the while(1). QUESTION: while (1) { my $key = $entry{digest}; - given (prompt 'Run a merge? [y,l,v,±1,±0,q,e,a, ,N] ', + given (prompt 'Run a merge? [y,l,v,±1,±0,q,e,a, ,N,?] ', verbose => 1, extra => qr/[+-]/) { when (/^y/i) { - #validate_branch_contains_named_revisions %entry; + # TODO: validate_branch_contains_named_revisions %entry; merge \%entry; while (1) { - given (prompt "Shall I open a subshell? [ydN] ", verbose => 1) { + given (prompt "Shall I open a subshell? [ydN?] ", verbose => 1) { when (/^y/i) { # TODO: if $MAY_COMMIT, save the log message to a file (say, # backport.logmsg in the wcroot). @@ -1024,6 +1049,10 @@ sub handle_entry { or warn "diff failed ($?): $!"; next; } + when (/^[?]/i) { + print $BACKPORT_OPTIONS_MERGE_OPTIONS_HELP; + next; + } when (/^N/i) { # fall through. } @@ -1087,6 +1116,10 @@ sub handle_entry { when (/^\x20/) { last PROMPT; # Fall off the end of the given/when block. } + when (/^[?]/i) { + print $BACKPORT_OPTIONS_HELP; + next QUESTION; + } default { say "Please use one of the options in brackets (q to quit)!"; next QUESTION; @@ -1222,7 +1255,7 @@ sub nominate_main { } my @lines; - warn "Wrapping [$logmsg]\n"; + warn "Wrapping [$logmsg]\n" if $DEBUG; push @lines, wrap " * ", ' 'x3, join ', ', map "r$_", @revnums; push @lines, wrap ' 'x3, ' 'x3, split /\n/, $logmsg; push @lines, " Justification:"; Modified: subversion/branches/move-tracking-2/tools/dist/backport_branch_with_original_revision.dump URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/tools/dist/backport_branch_with_original_revision.dump?rev=1665166&r1=1665165&r2=1665166&view=diff ============================================================================== --- subversion/branches/move-tracking-2/tools/dist/backport_branch_with_original_revision.dump (original) +++ subversion/branches/move-tracking-2/tools/dist/backport_branch_with_original_revision.dump Mon Mar 9 09:53:06 2015 @@ -1,6 +1,6 @@ SVN-fs-dump-format-version: 2 -UUID: d401d159-515a-4461-be2f-1d66eda6f451 +UUID: 76cee987-25c9-4d6c-ad40-000000000009 Revision-number: 0 Prop-content-length: 10
