You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2012/12/24 10:49:04 UTC
svn commit: r1425612 [2/2] - in /subversion/branches/tweak-build-take-two:
./ build/ subversion/include/private/ subversion/libsvn_client/
subversion/libsvn_fs/ subversion/libsvn_subr/ subversion/libsvn_wc/
subversion/mod_authz_svn/ subversion/mod_dav_...
Modified: subversion/branches/tweak-build-take-two/subversion/svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/tweak-build-take-two/subversion/svn/util.c?rev=1425612&r1=1425611&r2=1425612&view=diff
==============================================================================
--- subversion/branches/tweak-build-take-two/subversion/svn/util.c (original)
+++ subversion/branches/tweak-build-take-two/subversion/svn/util.c Mon Dec 24 09:49:03 2012
@@ -62,6 +62,7 @@
#include "private/svn_token.h"
#include "private/svn_opt_private.h"
#include "private/svn_client_private.h"
+#include "private/svn_cmdline_private.h"
#include "private/svn_string_private.h"
@@ -93,125 +94,6 @@ svn_cl__print_commit_info(const svn_comm
}
-/* Helper for the next two functions. Set *EDITOR to some path to an
- editor binary. Sources to search include: the EDITOR_CMD argument
- (if not NULL), $SVN_EDITOR, the runtime CONFIG variable (if CONFIG
- is not NULL), $VISUAL, $EDITOR. Return
- SVN_ERR_CL_NO_EXTERNAL_EDITOR if no binary can be found. */
-static svn_error_t *
-find_editor_binary(const char **editor,
- const char *editor_cmd,
- apr_hash_t *config)
-{
- const char *e;
- struct svn_config_t *cfg;
-
- /* Use the editor specified on the command line via --editor-cmd, if any. */
- e = editor_cmd;
-
- /* Otherwise look for the Subversion-specific environment variable. */
- if (! e)
- e = getenv("SVN_EDITOR");
-
- /* If not found then fall back on the config file. */
- if (! e)
- {
- cfg = config ? apr_hash_get(config, SVN_CONFIG_CATEGORY_CONFIG,
- APR_HASH_KEY_STRING) : NULL;
- svn_config_get(cfg, &e, SVN_CONFIG_SECTION_HELPERS,
- SVN_CONFIG_OPTION_EDITOR_CMD, NULL);
- }
-
- /* If not found yet then try general purpose environment variables. */
- if (! e)
- e = getenv("VISUAL");
- if (! e)
- e = getenv("EDITOR");
-
-#ifdef SVN_CLIENT_EDITOR
- /* If still not found then fall back on the hard-coded default. */
- if (! e)
- e = SVN_CLIENT_EDITOR;
-#endif
-
- /* Error if there is no editor specified */
- if (e)
- {
- const char *c;
-
- for (c = e; *c; c++)
- if (!svn_ctype_isspace(*c))
- break;
-
- if (! *c)
- return svn_error_create
- (SVN_ERR_CL_NO_EXTERNAL_EDITOR, NULL,
- _("The EDITOR, SVN_EDITOR or VISUAL environment variable or "
- "'editor-cmd' run-time configuration option is empty or "
- "consists solely of whitespace. Expected a shell command."));
- }
- else
- return svn_error_create
- (SVN_ERR_CL_NO_EXTERNAL_EDITOR, NULL,
- _("None of the environment variables SVN_EDITOR, VISUAL or EDITOR are "
- "set, and no 'editor-cmd' run-time configuration option was found"));
-
- *editor = e;
- return SVN_NO_ERROR;
-}
-
-
-/* Use the visual editor to edit files. This requires that the file name itself
- be shell-safe, although the path to reach that file need not be shell-safe.
- */
-svn_error_t *
-svn_cl__edit_file_externally(const char *path,
- const char *editor_cmd,
- apr_hash_t *config,
- apr_pool_t *pool)
-{
- const char *editor, *cmd, *base_dir, *file_name, *base_dir_apr;
- char *old_cwd;
- int sys_err;
- apr_status_t apr_err;
-
- svn_dirent_split(&base_dir, &file_name, path, pool);
-
- SVN_ERR(find_editor_binary(&editor, editor_cmd, config));
-
- apr_err = apr_filepath_get(&old_cwd, APR_FILEPATH_NATIVE, pool);
- if (apr_err)
- return svn_error_wrap_apr(apr_err, _("Can't get working directory"));
-
- /* APR doesn't like "" directories */
- if (base_dir[0] == '\0')
- base_dir_apr = ".";
- else
- SVN_ERR(svn_path_cstring_from_utf8(&base_dir_apr, base_dir, pool));
-
- apr_err = apr_filepath_set(base_dir_apr, pool);
- if (apr_err)
- return svn_error_wrap_apr
- (apr_err, _("Can't change working directory to '%s'"), base_dir);
-
- cmd = apr_psprintf(pool, "%s %s", editor, file_name);
- sys_err = system(cmd);
-
- apr_err = apr_filepath_set(old_cwd, pool);
- if (apr_err)
- svn_handle_error2(svn_error_wrap_apr
- (apr_err, _("Can't restore working directory")),
- stderr, TRUE /* fatal */, "svn: ");
-
- if (sys_err)
- /* Extracting any meaning from sys_err is platform specific, so just
- use the raw value. */
- return svn_error_createf(SVN_ERR_EXTERNAL_PROGRAM, NULL,
- _("system('%s') returned %d"), cmd, sys_err);
-
- return SVN_NO_ERROR;
-}
-
svn_error_t *
svn_cl__merge_file_externally(const char *base_path,
const char *their_path,
@@ -290,248 +172,6 @@ svn_cl__merge_file_externally(const char
return SVN_NO_ERROR;
}
-svn_error_t *
-svn_cl__edit_string_externally(svn_string_t **edited_contents /* UTF-8! */,
- const char **tmpfile_left /* UTF-8! */,
- const char *editor_cmd,
- const char *base_dir /* UTF-8! */,
- const svn_string_t *contents /* UTF-8! */,
- const char *filename,
- apr_hash_t *config,
- svn_boolean_t as_text,
- const char *encoding,
- apr_pool_t *pool)
-{
- const char *editor;
- const char *cmd;
- apr_file_t *tmp_file;
- const char *tmpfile_name;
- const char *tmpfile_native;
- const char *tmpfile_apr, *base_dir_apr;
- svn_string_t *translated_contents;
- apr_status_t apr_err, apr_err2;
- apr_size_t written;
- apr_finfo_t finfo_before, finfo_after;
- svn_error_t *err = SVN_NO_ERROR, *err2;
- char *old_cwd;
- int sys_err;
- svn_boolean_t remove_file = TRUE;
-
- SVN_ERR(find_editor_binary(&editor, editor_cmd, config));
-
- /* Convert file contents from UTF-8/LF if desired. */
- if (as_text)
- {
- const char *translated;
- SVN_ERR(svn_subst_translate_cstring2(contents->data, &translated,
- APR_EOL_STR, FALSE,
- NULL, FALSE, pool));
- translated_contents = svn_string_create_empty(pool);
- if (encoding)
- SVN_ERR(svn_utf_cstring_from_utf8_ex2(&translated_contents->data,
- translated, encoding, pool));
- else
- SVN_ERR(svn_utf_cstring_from_utf8(&translated_contents->data,
- translated, pool));
- translated_contents->len = strlen(translated_contents->data);
- }
- else
- translated_contents = svn_string_dup(contents, pool);
-
- /* Move to BASE_DIR to avoid getting characters that need quoting
- into tmpfile_name */
- apr_err = apr_filepath_get(&old_cwd, APR_FILEPATH_NATIVE, pool);
- if (apr_err)
- return svn_error_wrap_apr(apr_err, _("Can't get working directory"));
-
- /* APR doesn't like "" directories */
- if (base_dir[0] == '\0')
- base_dir_apr = ".";
- else
- SVN_ERR(svn_path_cstring_from_utf8(&base_dir_apr, base_dir, pool));
- apr_err = apr_filepath_set(base_dir_apr, pool);
- if (apr_err)
- {
- return svn_error_wrap_apr
- (apr_err, _("Can't change working directory to '%s'"), base_dir);
- }
-
- /*** From here on, any problems that occur require us to cd back!! ***/
-
- /* Ask the working copy for a temporary file named FILENAME-something. */
- err = svn_io_open_uniquely_named(&tmp_file, &tmpfile_name,
- "" /* dirpath */,
- filename,
- ".tmp",
- svn_io_file_del_none, pool, pool);
-
- if (err && (APR_STATUS_IS_EACCES(err->apr_err) || err->apr_err == EROFS))
- {
- const char *temp_dir_apr;
-
- svn_error_clear(err);
-
- SVN_ERR(svn_io_temp_dir(&base_dir, pool));
-
- SVN_ERR(svn_path_cstring_from_utf8(&temp_dir_apr, base_dir, pool));
- apr_err = apr_filepath_set(temp_dir_apr, pool);
- if (apr_err)
- {
- return svn_error_wrap_apr
- (apr_err, _("Can't change working directory to '%s'"), base_dir);
- }
-
- err = svn_io_open_uniquely_named(&tmp_file, &tmpfile_name,
- "" /* dirpath */,
- filename,
- ".tmp",
- svn_io_file_del_none, pool, pool);
- }
-
- if (err)
- goto cleanup2;
-
- /*** From here on, any problems that occur require us to cleanup
- the file we just created!! ***/
-
- /* Dump initial CONTENTS to TMP_FILE. */
- apr_err = apr_file_write_full(tmp_file, translated_contents->data,
- translated_contents->len, &written);
-
- apr_err2 = apr_file_close(tmp_file);
- if (! apr_err)
- apr_err = apr_err2;
-
- /* Make sure the whole CONTENTS were written, else return an error. */
- if (apr_err)
- {
- err = svn_error_wrap_apr(apr_err, _("Can't write to '%s'"),
- tmpfile_name);
- goto cleanup;
- }
-
- err = svn_path_cstring_from_utf8(&tmpfile_apr, tmpfile_name, pool);
- if (err)
- goto cleanup;
-
- /* Get information about the temporary file before the user has
- been allowed to edit its contents. */
- apr_err = apr_stat(&finfo_before, tmpfile_apr,
- APR_FINFO_MTIME, pool);
- if (apr_err)
- {
- err = svn_error_wrap_apr(apr_err, _("Can't stat '%s'"), tmpfile_name);
- goto cleanup;
- }
-
- /* Backdate the file a little bit in case the editor is very fast
- and doesn't change the size. (Use two seconds, since some
- filesystems have coarse granularity.) It's OK if this call
- fails, so we don't check its return value.*/
- apr_file_mtime_set(tmpfile_apr, finfo_before.mtime - 2000, pool);
-
- /* Stat it again to get the mtime we actually set. */
- apr_err = apr_stat(&finfo_before, tmpfile_apr,
- APR_FINFO_MTIME | APR_FINFO_SIZE, pool);
- if (apr_err)
- {
- err = svn_error_wrap_apr(apr_err, _("Can't stat '%s'"), tmpfile_name);
- goto cleanup;
- }
-
- /* Prepare the editor command line. */
- err = svn_utf_cstring_from_utf8(&tmpfile_native, tmpfile_name, pool);
- if (err)
- goto cleanup;
- cmd = apr_psprintf(pool, "%s %s", editor, tmpfile_native);
-
- /* If the caller wants us to leave the file around, return the path
- of the file we'll use, and make a note not to destroy it. */
- if (tmpfile_left)
- {
- *tmpfile_left = svn_dirent_join(base_dir, tmpfile_name, pool);
- remove_file = FALSE;
- }
-
- /* Now, run the editor command line. */
- sys_err = system(cmd);
- if (sys_err != 0)
- {
- /* Extracting any meaning from sys_err is platform specific, so just
- use the raw value. */
- err = svn_error_createf(SVN_ERR_EXTERNAL_PROGRAM, NULL,
- _("system('%s') returned %d"), cmd, sys_err);
- goto cleanup;
- }
-
- /* Get information about the temporary file after the assumed editing. */
- apr_err = apr_stat(&finfo_after, tmpfile_apr,
- APR_FINFO_MTIME | APR_FINFO_SIZE, pool);
- if (apr_err)
- {
- err = svn_error_wrap_apr(apr_err, _("Can't stat '%s'"), tmpfile_name);
- goto cleanup;
- }
-
- /* If the file looks changed... */
- if ((finfo_before.mtime != finfo_after.mtime) ||
- (finfo_before.size != finfo_after.size))
- {
- svn_stringbuf_t *edited_contents_s;
- err = svn_stringbuf_from_file2(&edited_contents_s, tmpfile_name, pool);
- if (err)
- goto cleanup;
-
- *edited_contents = svn_stringbuf__morph_into_string(edited_contents_s);
-
- /* Translate back to UTF8/LF if desired. */
- if (as_text)
- {
- err = svn_subst_translate_string2(edited_contents, FALSE, FALSE,
- *edited_contents, encoding, FALSE,
- pool, pool);
- if (err)
- {
- err = svn_error_quick_wrap
- (err,
- _("Error normalizing edited contents to internal format"));
- goto cleanup;
- }
- }
- }
- else
- {
- /* No edits seem to have been made */
- *edited_contents = NULL;
- }
-
- cleanup:
- if (remove_file)
- {
- /* Remove the file from disk. */
- err2 = svn_io_remove_file2(tmpfile_name, FALSE, pool);
-
- /* Only report remove error if there was no previous error. */
- if (! err && err2)
- err = err2;
- else
- svn_error_clear(err2);
- }
-
- cleanup2:
- /* If we against all probability can't cd back, all further relative
- file references would be screwed up, so we have to abort. */
- apr_err = apr_filepath_set(old_cwd, pool);
- if (apr_err)
- {
- svn_handle_error2(svn_error_wrap_apr
- (apr_err, _("Can't restore working directory")),
- stderr, TRUE /* fatal */, "svn: ");
- }
-
- return svn_error_trace(err);
-}
-
/* A svn_client_ctx_t's log_msg_baton3, for use with
svn_cl__make_log_msg_baton(). */
@@ -732,8 +372,8 @@ svn_cl__get_log_message(const char **log
while (! message)
{
/* We still don't have a valid commit message. Use $EDITOR to
- get one. Note that svn_cl__edit_externally will still return
- a UTF-8'ized log message. */
+ get one. Note that svn_cl__edit_string_externally will still
+ return a UTF-8'ized log message. */
int i;
svn_stringbuf_t *tmp_message = svn_stringbuf_dup(default_msg, pool);
svn_error_t *err = SVN_NO_ERROR;
@@ -793,12 +433,12 @@ svn_cl__get_log_message(const char **log
/* Use the external edit to get a log message. */
if (! lmb->non_interactive)
{
- err = svn_cl__edit_string_externally(&msg_string, &lmb->tmpfile_left,
- lmb->editor_cmd, lmb->base_dir,
- msg_string, "svn-commit",
- lmb->config, TRUE,
- lmb->message_encoding,
- pool);
+ err = svn_cmdline__edit_string_externally(&msg_string, &lmb->tmpfile_left,
+ lmb->editor_cmd, lmb->base_dir,
+ msg_string, "svn-commit",
+ lmb->config, TRUE,
+ lmb->message_encoding,
+ pool);
}
else /* non_interactive flag says we can't pop up an editor, so error */
{
Modified: subversion/branches/tweak-build-take-two/subversion/svnmucc/svnmucc.c
URL: http://svn.apache.org/viewvc/subversion/branches/tweak-build-take-two/subversion/svnmucc/svnmucc.c?rev=1425612&r1=1425611&r2=1425612&view=diff
==============================================================================
--- subversion/branches/tweak-build-take-two/subversion/svnmucc/svnmucc.c (original)
+++ subversion/branches/tweak-build-take-two/subversion/svnmucc/svnmucc.c Mon Dec 24 09:49:03 2012
@@ -55,6 +55,9 @@
#include "private/svn_cmdline_private.h"
#include "private/svn_ra_private.h"
+#include "private/svn_string_private.h"
+
+#include "svn_private_config.h"
static void handle_error(svn_error_t *err, apr_pool_t *pool)
{
@@ -750,6 +753,29 @@ execute(const apr_array_header_t *action
"svnmucc: ", "--config-option"));
cfg_config = apr_hash_get(config, SVN_CONFIG_CATEGORY_CONFIG,
APR_HASH_KEY_STRING);
+
+ if (! apr_hash_get(revprops, SVN_PROP_REVISION_LOG, APR_HASH_KEY_STRING))
+ {
+ svn_string_t *msg = svn_string_create("", pool);
+
+ /* If we can do so, try to pop up $EDITOR to fetch a log message. */
+ if (non_interactive)
+ {
+ return svn_error_create
+ (SVN_ERR_CL_INSUFFICIENT_ARGS, NULL,
+ _("Cannot invoke editor to get log message "
+ "when non-interactive"));
+ }
+ else
+ {
+ SVN_ERR(svn_cmdline__edit_string_externally(
+ &msg, NULL, NULL, "", msg, "svnmucc-commit", config,
+ TRUE, NULL, apr_hash_pool_get(revprops)));
+ }
+
+ apr_hash_set(revprops, SVN_PROP_REVISION_LOG, APR_HASH_KEY_STRING, msg);
+ }
+
SVN_ERR(create_ra_callbacks(&ra_callbacks, username, password, config_dir,
cfg_config, non_interactive, no_auth_cache,
pool));
@@ -899,37 +925,42 @@ static void
usage(apr_pool_t *pool, int exit_val)
{
FILE *stream = exit_val == EXIT_SUCCESS ? stdout : stderr;
- static const char *msg =
- "Multiple URL Command Client (for Subversion)\n"
- "\nUsage: svnmucc [OPTION]... [ACTION]...\n"
- "\nActions:\n"
- " cp REV URL1 URL2 copy URL1@REV to URL2\n"
- " mkdir URL create new directory URL\n"
- " mv URL1 URL2 move URL1 to URL2\n"
- " rm URL delete URL\n"
- " put SRC-FILE URL add or modify file URL with contents copied from\n"
- " SRC-FILE (use \"-\" to read from standard input)\n"
- " propset NAME VAL URL set property NAME on URL to value VAL\n"
- " propsetf NAME VAL URL set property NAME on URL to value from file VAL\n"
- " propdel NAME URL delete property NAME from URL\n"
- "\nOptions:\n"
- " -h, --help, -? display this text\n"
- " -m, --message ARG use ARG as a log message\n"
- " -F, --file ARG read log message from file ARG\n"
- " -u, --username ARG commit the changes as username ARG\n"
- " -p, --password ARG use ARG as the password\n"
- " -U, --root-url ARG interpret all action URLs are relative to ARG\n"
- " -r, --revision ARG use revision ARG as baseline for changes\n"
- " --with-revprop A[=B] set revision property A in new revision to B\n"
- " if specified, else to the empty string\n"
- " -n, --non-interactive don't prompt the user about anything\n"
- " -X, --extra-args ARG append arguments from file ARG (one per line;\n"
- " use \"-\" to read from standard input)\n"
- " --config-dir ARG use ARG to override the config directory\n"
- " --config-option ARG use ARG to override a configuration option\n"
- " --no-auth-cache do not cache authentication tokens\n"
- " --version print version information\n";
- svn_error_clear(svn_cmdline_fputs(msg, stream, pool));
+ svn_error_clear(svn_cmdline_fputs(
+ _("Subversion multiple URL command client\n"
+ "usage: svnmucc [OPTION]... [ACTION]...\n"
+ "\n"
+ " Perform one or more Subversion repository URL-based ACTIONs, committing\n"
+ " the result as a (single) new revision.\n"
+ "\n"
+ "Actions:\n"
+ " cp REV URL1 URL2 : copy URL1@REV to URL2\n"
+ " mkdir URL : create new directory URL\n"
+ " mv URL1 URL2 : move URL1 to URL2\n"
+ " rm URL : delete URL\n"
+ " put SRC-FILE URL : add or modify file URL with contents copied from\n"
+ " SRC-FILE (use \"-\" to read from standard input)\n"
+ " propset NAME VAL URL : set property NAME on URL to value VAL\n"
+ " propsetf NAME VAL URL : set property NAME on URL to value from file VAL\n"
+ " propdel NAME URL : delete property NAME from URL\n"
+ "\n"
+ "Valid options:\n"
+ " -h, -? [--help] : display this text\n"
+ " -m [--message] ARG : use ARG as a log message\n"
+ " -F [--file] ARG : read log message from file ARG\n"
+ " -u [--username] ARG : commit the changes as username ARG\n"
+ " -p [--password] ARG : use ARG as the password\n"
+ " -U [--root-url] ARG : interpret all action URLs relative to ARG\n"
+ " -r [--revision] ARG : use revision ARG as baseline for changes\n"
+ " --with-revprop ARG : set revision property in the following format:\n"
+ " NAME[=VALUE]\n"
+ " -n [--non-interactive] : don't prompt the user about anything\n"
+ " -X [--extra-args] ARG : append arguments from file ARG (one per line;\n"
+ " : use \"-\" to read from standard input)\n"
+ " --config-dir ARG : use ARG to override the config directory\n"
+ " --config-option ARG : use ARG to override a configuration option\n"
+ " --no-auth-cache : do not cache authentication tokens\n"
+ " --version : print version information\n"),
+ stream, pool));
apr_pool_destroy(pool);
exit(exit_val);
}
@@ -959,6 +990,53 @@ display_version(apr_getopt_t *os, apr_po
return SVN_NO_ERROR;
}
+/* Return an error about the mutual exclusivity of the -m, -F, and
+ --with-revprop=svn:log command-line options. */
+static svn_error_t *
+mutually_exclusive_logs_error(void)
+{
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("--message (-m), --file (-F), and "
+ "--with-revprop=svn:log are mutually "
+ "exclusive"));
+}
+
+/* Ensure that the REVPROPS hash contains a command-line-provided log
+ message, if any, and that there was but one source of such a thing
+ provided on that command-line. */
+static svn_error_t *
+sanitize_log_sources(apr_hash_t *revprops,
+ const char *message,
+ svn_stringbuf_t *filedata)
+{
+ apr_pool_t *hash_pool = apr_hash_pool_get(revprops);
+
+ /* If we already have a log message in the revprop hash, then just
+ make sure the user didn't try to also use -m or -F. Otherwise,
+ we need to consult -m or -F to find a log message, if any. */
+ if (apr_hash_get(revprops, SVN_PROP_REVISION_LOG, APR_HASH_KEY_STRING))
+ {
+ if (filedata || message)
+ return mutually_exclusive_logs_error();
+ }
+ else if (filedata)
+ {
+ if (message)
+ return mutually_exclusive_logs_error();
+
+ SVN_ERR(svn_utf_cstring_to_utf8(&message, filedata->data, hash_pool));
+ apr_hash_set(revprops, SVN_PROP_REVISION_LOG, APR_HASH_KEY_STRING,
+ svn_stringbuf__morph_into_string(filedata));
+ }
+ else if (message)
+ {
+ apr_hash_set(revprops, SVN_PROP_REVISION_LOG, APR_HASH_KEY_STRING,
+ svn_string_create(message, hash_pool));
+ }
+
+ return SVN_NO_ERROR;
+}
+
int
main(int argc, const char **argv)
{
@@ -994,6 +1072,7 @@ main(int argc, const char **argv)
{NULL, 0, 0, NULL}
};
const char *message = NULL;
+ svn_stringbuf_t *filedata = NULL;
const char *username = NULL, *password = NULL;
const char *root_url = NULL, *extra_args_file = NULL;
const char *config_dir = NULL;
@@ -1031,12 +1110,9 @@ main(int argc, const char **argv)
case 'F':
{
const char *arg_utf8;
- svn_stringbuf_t *contents;
err = svn_utf_cstring_to_utf8(&arg_utf8, arg, pool);
if (! err)
- err = svn_stringbuf_from_file2(&contents, arg, pool);
- if (! err)
- err = svn_utf_cstring_to_utf8(&message, contents->data, pool);
+ err = svn_stringbuf_from_file2(&filedata, arg, pool);
if (err)
handle_error(err, pool);
}
@@ -1109,6 +1185,11 @@ main(int argc, const char **argv)
}
}
+ /* Make sure we have a log message to use. */
+ err = sanitize_log_sources(revprops, message, filedata);
+ if (err)
+ handle_error(err, pool);
+
/* Copy the rest of our command-line arguments to an array,
UTF-8-ing them along the way. */
action_args = apr_array_make(pool, opts->argc, sizeof(const char *));
@@ -1324,21 +1405,6 @@ main(int argc, const char **argv)
if (! actions->nelts)
usage(pool, EXIT_FAILURE);
- if (message == NULL)
- {
- if (apr_hash_get(revprops, SVN_PROP_REVISION_LOG,
- APR_HASH_KEY_STRING) == NULL)
- /* None of -F, -m, or --with-revprop=svn:log specified; default. */
- apr_hash_set(revprops, SVN_PROP_REVISION_LOG, APR_HASH_KEY_STRING,
- svn_string_create("committed using svnmucc", pool));
- }
- else
- {
- /* -F or -m specified; use that even if --with-revprop=svn:log. */
- apr_hash_set(revprops, SVN_PROP_REVISION_LOG, APR_HASH_KEY_STRING,
- svn_string_create(message, pool));
- }
-
if ((err = execute(actions, anchor, revprops, username, password,
config_dir, config_options, non_interactive,
no_auth_cache, base_revision, pool)))
Modified: subversion/branches/tweak-build-take-two/subversion/svnrdump/dump_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/tweak-build-take-two/subversion/svnrdump/dump_editor.c?rev=1425612&r1=1425611&r2=1425612&view=diff
==============================================================================
--- subversion/branches/tweak-build-take-two/subversion/svnrdump/dump_editor.c (original)
+++ subversion/branches/tweak-build-take-two/subversion/svnrdump/dump_editor.c Mon Dec 24 09:49:03 2012
@@ -50,7 +50,8 @@ struct dir_baton
struct dump_edit_baton *eb;
struct dir_baton *parent_dir_baton;
- apr_pool_t *pool; /* Directory pool */
+ /* Pool for per-directory allocations */
+ apr_pool_t *pool;
/* is this directory a new addition to this revision? */
svn_boolean_t added;
@@ -65,11 +66,21 @@ struct dir_baton
const char *copyfrom_path; /* a relpath */
svn_revnum_t copyfrom_rev;
+ /* Properties which were modified during change_dir_prop. */
+ apr_hash_t *props;
+
+ /* Properties which were deleted during change_dir_prop. */
+ apr_hash_t *deleted_props;
+
/* Hash of paths that need to be deleted, though some -might- be
replaced. Maps const char * paths to this dir_baton. Note that
they're full paths, because that's what the editor driver gives
us, although they're all really within this directory. */
apr_hash_t *deleted_entries;
+
+ /* Flags to trigger dumping props and record termination newlines. */
+ svn_boolean_t dump_props;
+ svn_boolean_t dump_newlines;
};
/* A file baton used by all file-related callback functions in the dump
@@ -79,11 +90,32 @@ struct file_baton
struct dump_edit_baton *eb;
struct dir_baton *parent_dir_baton;
+ /* Pool for per-file allocations */
+ apr_pool_t *pool;
+
/* the path to this file */
const char *repos_relpath; /* a relpath */
+ /* Properties which were modified during change_file_prop. */
+ apr_hash_t *props;
+
+ /* Properties which were deleted during change_file_prop. */
+ apr_hash_t *deleted_props;
+
/* The checksum of the file the delta is being applied to */
const char *base_checksum;
+
+ /* Copy state and source information (if any). */
+ svn_boolean_t is_copy;
+ const char *copyfrom_path;
+ svn_revnum_t copyfrom_rev;
+
+ /* The action associate with this node. */
+ enum svn_node_action action;
+
+ /* Flags to trigger dumping props and text. */
+ svn_boolean_t dump_text;
+ svn_boolean_t dump_props;
};
/* A handler baton to be used in window_handler(). */
@@ -112,31 +144,20 @@ struct dump_edit_baton {
/* Pool for per-revision allocations */
apr_pool_t *pool;
- /* Properties which were modified during change_file_prop
- * or change_dir_prop. */
- apr_hash_t *props;
-
- /* Properties which were deleted during change_file_prop
- * or change_dir_prop. */
- apr_hash_t *deleted_props;
-
- /* Temporary buffer to write property hashes to in human-readable
- * form. ### Is this really needed? */
- svn_stringbuf_t *propstring;
-
/* Temporary file used for textdelta application along with its
absolute path; these two variables should be allocated in the
per-edit-session pool */
const char *delta_abspath;
apr_file_t *delta_file;
- /* Flags to trigger dumping props and text */
- svn_boolean_t dump_text;
- svn_boolean_t dump_props;
- svn_boolean_t dump_newlines;
-
/* The revision we're currently dumping. */
svn_revnum_t current_revision;
+
+ /* The kind (file or directory) and baton of the item whose block of
+ dump stream data has not been fully completed; NULL if there's no
+ such item. */
+ svn_node_kind_t pending_kind;
+ void *pending_baton;
};
/* Make a directory baton to represent the directory at PATH (relative
@@ -147,21 +168,20 @@ struct dump_edit_baton {
* information is valid, the directory will be compared against its
* copy source.
*
- * PARENT_DIR_BATON is the directory baton of this directory's parent,
- * or NULL if this is the top-level directory of the edit. ADDED
- * indicates if this directory is newly added in this revision.
- * Perform all allocations in POOL. */
+ * PB is the directory baton of this directory's parent, or NULL if
+ * this is the top-level directory of the edit. ADDED indicates if
+ * this directory is newly added in this revision. Perform all
+ * allocations in POOL. */
static struct dir_baton *
make_dir_baton(const char *path,
const char *copyfrom_path,
svn_revnum_t copyfrom_rev,
void *edit_baton,
- void *parent_dir_baton,
+ struct dir_baton *pb,
svn_boolean_t added,
apr_pool_t *pool)
{
struct dump_edit_baton *eb = edit_baton;
- struct dir_baton *pb = parent_dir_baton;
struct dir_baton *new_db = apr_pcalloc(pool, sizeof(*new_db));
const char *repos_relpath;
@@ -186,11 +206,38 @@ make_dir_baton(const char *path,
new_db->copyfrom_rev = copyfrom_rev;
new_db->added = added;
new_db->written_out = FALSE;
+ new_db->props = apr_hash_make(pool);
+ new_db->deleted_props = apr_hash_make(pool);
new_db->deleted_entries = apr_hash_make(pool);
return new_db;
}
+/* Make a file baton to represent the directory at PATH (relative to
+ * PB->eb). PB is the directory baton of this directory's parent, or
+ * NULL if this is the top-level directory of the edit. Perform all
+ * allocations in POOL. */
+static struct file_baton *
+make_file_baton(const char *path,
+ struct dir_baton *pb,
+ apr_pool_t *pool)
+{
+ struct file_baton *new_fb = apr_pcalloc(pool, sizeof(*new_fb));
+
+ new_fb->eb = pb->eb;
+ new_fb->parent_dir_baton = pb;
+ new_fb->pool = pool;
+ new_fb->repos_relpath = svn_relpath_canonicalize(path, pool);
+ new_fb->props = apr_hash_make(pool);
+ new_fb->deleted_props = apr_hash_make(pool);
+ new_fb->is_copy = FALSE;
+ new_fb->copyfrom_path = NULL;
+ new_fb->copyfrom_rev = SVN_INVALID_REVNUM;
+ new_fb->action = svn_node_action_change;
+
+ return new_fb;
+}
+
/* Return in *HEADER and *CONTENT the headers and content for PROPS. */
static svn_error_t *
get_props_content(svn_stringbuf_t **header,
@@ -227,9 +274,13 @@ get_props_content(svn_stringbuf_t **head
return SVN_NO_ERROR;
}
-/* Extract and dump properties stored in edit baton EB, using POOL for
- * any temporary allocations. If TRIGGER_VAR is not NULL, it is set to FALSE.
- * Unless DUMP_DATA_TOO is set, only property headers are dumped.
+/* Extract and dump properties stored in PROPS and property deletions
+ * stored in DELETED_PROPS. If TRIGGER_VAR is not NULL, it is set to
+ * FALSE.
+ *
+ * If PROPSTRING is non-NULL, set *PROPSTRING to a string containing
+ * the content block of the property changes; otherwise, dump that to
+ * the stream, too.
*/
static svn_error_t *
do_dump_props(svn_stringbuf_t **propstring,
@@ -237,7 +288,6 @@ do_dump_props(svn_stringbuf_t **propstri
apr_hash_t *props,
apr_hash_t *deleted_props,
svn_boolean_t *trigger_var,
- svn_boolean_t dump_data_too,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -250,14 +300,14 @@ do_dump_props(svn_stringbuf_t **propstri
SVN_ERR(get_props_content(&header, &content, props, deleted_props,
result_pool, scratch_pool));
-
- /* This is a wacky side-effect of this function. */
- *propstring = content;
-
len = header->len;
SVN_ERR(svn_stream_write(stream, header->data, &len));
- if (dump_data_too)
+ if (propstring)
+ {
+ *propstring = content;
+ }
+ else
{
/* Content-length: 14 */
SVN_ERR(svn_stream_printf(stream, scratch_pool,
@@ -309,7 +359,8 @@ do_dump_newlines(struct dump_edit_baton
static svn_error_t *
dump_node(struct dump_edit_baton *eb,
const char *repos_relpath,
- svn_node_kind_t kind,
+ struct dir_baton *db,
+ struct file_baton *fb,
enum svn_node_action action,
svn_boolean_t is_copy,
const char *copyfrom_path,
@@ -320,6 +371,7 @@ dump_node(struct dump_edit_baton *eb,
assert(svn_relpath_is_canonical(repos_relpath));
assert(!copyfrom_path || svn_relpath_is_canonical(copyfrom_path));
+ assert(! (db && fb));
/* Add the edit root relpath prefix if necessary. */
if (eb->update_anchor_relpath)
@@ -332,10 +384,10 @@ dump_node(struct dump_edit_baton *eb,
node_relpath));
/* Node-kind: "file" | "dir" */
- if (kind == svn_node_file)
+ if (fb)
SVN_ERR(svn_stream_printf(eb->stream, pool,
SVN_REPOS_DUMPFILE_NODE_KIND ": file\n"));
- else if (kind == svn_node_dir)
+ else if (db)
SVN_ERR(svn_stream_printf(eb->stream, pool,
SVN_REPOS_DUMPFILE_NODE_KIND ": dir\n"));
@@ -358,9 +410,9 @@ dump_node(struct dump_edit_baton *eb,
{
/* Delete the original, and then re-add the replacement as a
copy using recursive calls into this function. */
- SVN_ERR(dump_node(eb, repos_relpath, kind, svn_node_action_delete,
+ SVN_ERR(dump_node(eb, repos_relpath, db, fb, svn_node_action_delete,
FALSE, NULL, SVN_INVALID_REVNUM, pool));
- SVN_ERR(dump_node(eb, repos_relpath, kind, svn_node_action_add,
+ SVN_ERR(dump_node(eb, repos_relpath, db, fb, svn_node_action_add,
is_copy, copyfrom_path, copyfrom_rev, pool));
}
else
@@ -372,7 +424,10 @@ dump_node(struct dump_edit_baton *eb,
/* Wait for a change_*_prop to be called before dumping
anything */
- eb->dump_props = TRUE;
+ if (fb)
+ fb->dump_props = TRUE;
+ else if (db)
+ db->dump_props = TRUE;
}
break;
@@ -410,16 +465,16 @@ dump_node(struct dump_edit_baton *eb,
set DUMP_NEWLINES here to print the newlines unless
change_dir_prop() is called next otherwise the `svnadmin load`
parser will fail. */
- if (kind == svn_node_dir)
- eb->dump_newlines = TRUE;
+ if (db)
+ db->dump_newlines = TRUE;
}
else
{
- /* eb->dump_props (for files) is handled in close_file()
+ /* fb->dump_props (for files) is handled in close_file()
which is called immediately.
However, directories are not closed until all the work
- inside them has been done; eb->dump_props (for directories)
+ inside them has been done; db->dump_props (for directories)
is handled (via dump_pending()) in all the functions that
can possibly be called after add_directory():
@@ -431,7 +486,10 @@ dump_node(struct dump_edit_baton *eb,
- open_file()
change_dir_prop() is a special case. */
- eb->dump_props = TRUE;
+ if (fb)
+ fb->dump_props = TRUE;
+ else if (db)
+ db->dump_props = TRUE;
}
break;
@@ -483,21 +541,45 @@ dump_mkdir(struct dump_edit_baton *eb,
/* Dump pending items from the specified node, to allow starting the dump
of a child node */
static svn_error_t *
-dump_pending(struct dir_baton *pb,
+dump_pending(struct dump_edit_baton *eb,
apr_pool_t *scratch_pool)
{
- /* Some pending properties to dump? */
- SVN_ERR(do_dump_props(&pb->eb->propstring, pb->eb->stream,
- pb->eb->props, pb->eb->deleted_props,
- &(pb->eb->dump_props), TRUE,
- pb->pool, scratch_pool));
+ if (! eb->pending_baton)
+ return SVN_NO_ERROR;
+
+ if (eb->pending_kind == svn_node_dir)
+ {
+ struct dir_baton *db = eb->pending_baton;
+
+ /* Some pending properties to dump? */
+ SVN_ERR(do_dump_props(NULL, eb->stream, db->props, db->deleted_props,
+ &(db->dump_props), db->pool, scratch_pool));
+
+ /* Some pending newlines to dump? */
+ SVN_ERR(do_dump_newlines(eb, &(db->dump_newlines), scratch_pool));
+ }
+ else if (eb->pending_kind == svn_node_file)
+ {
+ struct file_baton *fb = eb->pending_baton;
+
+ /* Some pending properties to dump? */
+ SVN_ERR(do_dump_props(NULL, eb->stream, fb->props, fb->deleted_props,
+ &(fb->dump_props), fb->pool, scratch_pool));
+ }
+ else
+ abort();
- /* Some pending newlines to dump? */
- SVN_ERR(do_dump_newlines(pb->eb, &(pb->eb->dump_newlines), scratch_pool));
+ /* Anything that was pending is pending no longer. */
+ eb->pending_baton = NULL;
+ eb->pending_kind = svn_node_none;
return SVN_NO_ERROR;
}
+
+
+/*** Editor Function Implementations ***/
+
static svn_error_t *
open_root(void *edit_baton,
svn_revnum_t base_revision,
@@ -510,10 +592,6 @@ open_root(void *edit_baton,
/* Clear the per-revision pool after each revision */
svn_pool_clear(eb->pool);
- eb->props = apr_hash_make(eb->pool);
- eb->deleted_props = apr_hash_make(eb->pool);
- eb->propstring = svn_stringbuf_create_empty(eb->pool);
-
LDR_DBG(("open_root %p\n", *root_baton));
if (eb->update_anchor_relpath)
@@ -549,10 +627,15 @@ open_root(void *edit_baton,
to letting the typical plumbing handle this task. */
new_db = make_dir_baton(NULL, NULL, SVN_INVALID_REVNUM,
edit_baton, NULL, TRUE, pool);
- SVN_ERR(dump_node(eb, new_db->repos_relpath, svn_node_dir,
- svn_node_action_add, FALSE, NULL, SVN_INVALID_REVNUM,
- pool));
+ SVN_ERR(dump_node(eb, new_db->repos_relpath, new_db,
+ NULL, svn_node_action_add, FALSE,
+ NULL, SVN_INVALID_REVNUM, pool));
+
+ /* Remember that we've started but not yet finished
+ handling this directory. */
new_db->written_out = TRUE;
+ eb->pending_baton = new_db;
+ eb->pending_kind = svn_node_dir;
}
}
svn_pool_destroy(iterpool);
@@ -565,7 +648,6 @@ open_root(void *edit_baton,
}
*root_baton = new_db;
-
return SVN_NO_ERROR;
}
@@ -579,10 +661,12 @@ delete_entry(const char *path,
LDR_DBG(("delete_entry %s\n", path));
- SVN_ERR(dump_pending(pb, pool));
+ SVN_ERR(dump_pending(pb->eb, pool));
- /* Add this path to the deleted_entries of the parent directory
- baton. */
+ /* We don't dump this deletion immediate. Rather, we add this path
+ to the deleted_entries of the parent directory baton. That way,
+ we can tell (later) an addition from a replacement. All the real
+ deletions get handled in close_directory(). */
apr_hash_set(pb->deleted_entries, apr_pstrdup(pb->eb->pool, path),
APR_HASH_KEY_STRING, pb);
@@ -604,11 +688,11 @@ add_directory(const char *path,
LDR_DBG(("add_directory %s\n", path));
+ SVN_ERR(dump_pending(pb->eb, pool));
+
new_db = make_dir_baton(path, copyfrom_path, copyfrom_rev, pb->eb,
pb, TRUE, pb->eb->pool);
- SVN_ERR(dump_pending(pb, pool));
-
/* This might be a replacement -- is the path already deleted? */
val = apr_hash_get(pb->deleted_entries, path, APR_HASH_KEY_STRING);
@@ -616,8 +700,7 @@ add_directory(const char *path,
is_copy = ARE_VALID_COPY_ARGS(copyfrom_path, copyfrom_rev);
/* Dump the node */
- SVN_ERR(dump_node(pb->eb, new_db->repos_relpath,
- svn_node_dir,
+ SVN_ERR(dump_node(pb->eb, new_db->repos_relpath, new_db, NULL,
val ? svn_node_action_replace : svn_node_action_add,
is_copy,
is_copy ? new_db->copyfrom_path : NULL,
@@ -628,7 +711,11 @@ add_directory(const char *path,
/* Delete the path, it's now been dumped */
apr_hash_set(pb->deleted_entries, path, APR_HASH_KEY_STRING, NULL);
+ /* Remember that we've started, but not yet finished handling this
+ directory. */
new_db->written_out = TRUE;
+ pb->eb->pending_baton = new_db;
+ pb->eb->pending_kind = svn_node_dir;
*child_baton = new_db;
return SVN_NO_ERROR;
@@ -648,7 +735,7 @@ open_directory(const char *path,
LDR_DBG(("open_directory %s\n", path));
- SVN_ERR(dump_pending(pb, pool));
+ SVN_ERR(dump_pending(pb->eb, pool));
/* If the parent directory has explicit comparison path and rev,
record the same for this one. */
@@ -662,6 +749,7 @@ open_directory(const char *path,
new_db = make_dir_baton(path, copyfrom_path, copyfrom_rev, pb->eb, pb,
FALSE, pb->eb->pool);
+
*child_baton = new_db;
return SVN_NO_ERROR;
}
@@ -672,10 +760,33 @@ close_directory(void *dir_baton,
{
struct dir_baton *db = dir_baton;
apr_hash_index_t *hi;
+ svn_boolean_t this_pending;
LDR_DBG(("close_directory %p\n", dir_baton));
- SVN_ERR(dump_pending(db, pool));
+ /* Remember if this directory is the one currently pending. */
+ this_pending = (db->eb->pending_baton == db);
+
+ SVN_ERR(dump_pending(db->eb, pool));
+
+ /* If this directory was pending, then dump_pending() should have
+ taken care of all the props and such. Of course, the only way
+ that would be the case is if this directory was added/replaced.
+
+ Otherwise, if stuff for this directory has already been written
+ out (at some point in the past, prior to our handling other
+ nodes), we might need to generate a second "change" record just
+ to carry the information we've since learned about the
+ directory. */
+ if ((! this_pending) && (db->dump_props))
+ {
+ SVN_ERR(dump_node(db->eb, db->repos_relpath, db, NULL,
+ svn_node_action_change, FALSE,
+ NULL, SVN_INVALID_REVNUM, pool));
+ db->eb->pending_baton = db;
+ db->eb->pending_kind = svn_node_dir;
+ SVN_ERR(dump_pending(db->eb, pool));
+ }
/* Dump the deleted directory entries */
for (hi = apr_hash_first(pool, db->deleted_entries); hi;
@@ -683,11 +794,13 @@ close_directory(void *dir_baton,
{
const char *path = svn__apr_hash_index_key(hi);
- SVN_ERR(dump_node(db->eb, path, svn_node_unknown, svn_node_action_delete,
+ SVN_ERR(dump_node(db->eb, path, NULL, NULL, svn_node_action_delete,
FALSE, NULL, SVN_INVALID_REVNUM, pool));
}
+ /* ### should be unnecessary */
SVN_ERR(svn_hash__clear(db->deleted_entries, pool));
+
return SVN_NO_ERROR;
}
@@ -700,42 +813,33 @@ add_file(const char *path,
void **file_baton)
{
struct dir_baton *pb = parent_baton;
- struct file_baton *fb = apr_pcalloc(pool, sizeof(*fb));
+ struct file_baton *fb;
void *val;
- svn_boolean_t is_copy;
-
- fb->eb = pb->eb;
- fb->parent_dir_baton = pb;
- fb->repos_relpath = svn_relpath_canonicalize(path, pool);
LDR_DBG(("add_file %s\n", path));
- SVN_ERR(dump_pending(pb, pool));
+ SVN_ERR(dump_pending(pb->eb, pool));
+ /* Make the file baton. */
+ fb = make_file_baton(path, pb, pool);
+
/* This might be a replacement -- is the path already deleted? */
val = apr_hash_get(pb->deleted_entries, path, APR_HASH_KEY_STRING);
/* Detect add-with-history. */
- is_copy = ARE_VALID_COPY_ARGS(copyfrom_path, copyfrom_rev);
-
- /* Dump the node. */
- SVN_ERR(dump_node(pb->eb, fb->repos_relpath,
- svn_node_file,
- val ? svn_node_action_replace : svn_node_action_add,
- is_copy,
- is_copy ? svn_relpath_canonicalize(copyfrom_path, pool)
- : NULL,
- is_copy ? copyfrom_rev : SVN_INVALID_REVNUM,
- pool));
+ if (ARE_VALID_COPY_ARGS(copyfrom_path, copyfrom_rev))
+ {
+ fb->copyfrom_path = svn_relpath_canonicalize(copyfrom_path, fb->pool);
+ fb->copyfrom_rev = copyfrom_rev;
+ fb->is_copy = TRUE;
+ }
+ fb->action = val ? svn_node_action_replace : svn_node_action_add;
+ /* Delete the path, it's now been dumped. */
if (val)
- /* delete the path, it's now been dumped. */
apr_hash_set(pb->deleted_entries, path, APR_HASH_KEY_STRING, NULL);
- /* Build a nice file baton to pass to change_file_prop and
- apply_textdelta */
*file_baton = fb;
-
return SVN_NO_ERROR;
}
@@ -747,36 +851,26 @@ open_file(const char *path,
void **file_baton)
{
struct dir_baton *pb = parent_baton;
- struct file_baton *fb = apr_pcalloc(pool, sizeof(*fb));
- const char *copyfrom_path = NULL;
- svn_revnum_t copyfrom_rev = SVN_INVALID_REVNUM;
-
- fb->eb = pb->eb;
- fb->parent_dir_baton = pb;
- fb->repos_relpath = svn_relpath_canonicalize(path, pool);
+ struct file_baton *fb;
LDR_DBG(("open_file %s\n", path));
- SVN_ERR(dump_pending(pb, pool));
+ SVN_ERR(dump_pending(pb->eb, pool));
+
+ /* Make the file baton. */
+ fb = make_file_baton(path, pb, pool);
/* If the parent directory has explicit copyfrom path and rev,
record the same for this one. */
if (ARE_VALID_COPY_ARGS(pb->copyfrom_path, pb->copyfrom_rev))
{
- copyfrom_path = svn_relpath_join(pb->copyfrom_path,
- svn_relpath_basename(path, NULL),
- pb->eb->pool);
- copyfrom_rev = pb->copyfrom_rev;
+ fb->copyfrom_path = svn_relpath_join(pb->copyfrom_path,
+ svn_relpath_basename(path, NULL),
+ pb->eb->pool);
+ fb->copyfrom_rev = pb->copyfrom_rev;
}
- SVN_ERR(dump_node(pb->eb, fb->repos_relpath, svn_node_file,
- svn_node_action_change, FALSE, copyfrom_path,
- copyfrom_rev, pool));
-
- /* Build a nice file baton to pass to change_file_prop and
- apply_textdelta */
*file_baton = fb;
-
return SVN_NO_ERROR;
}
@@ -787,37 +881,30 @@ change_dir_prop(void *parent_baton,
apr_pool_t *pool)
{
struct dir_baton *db = parent_baton;
-
+ svn_boolean_t this_pending;
+
LDR_DBG(("change_dir_prop %p\n", parent_baton));
+ /* This directory is not pending, but something else is, so handle
+ the "something else". */
+ this_pending = (db->eb->pending_baton == db);
+ if (! this_pending)
+ SVN_ERR(dump_pending(db->eb, pool));
+
if (svn_property_kind2(name) != svn_prop_regular_kind)
return SVN_NO_ERROR;
if (value)
- apr_hash_set(db->eb->props, apr_pstrdup(db->eb->pool, name),
- APR_HASH_KEY_STRING, svn_string_dup(value, db->eb->pool));
+ apr_hash_set(db->props, apr_pstrdup(db->pool, name),
+ APR_HASH_KEY_STRING, svn_string_dup(value, db->pool));
else
- apr_hash_set(db->eb->deleted_props, apr_pstrdup(db->eb->pool, name),
+ apr_hash_set(db->deleted_props, apr_pstrdup(db->pool, name),
APR_HASH_KEY_STRING, "");
- if (! db->written_out)
- {
- /* If db->written_out is set, it means that the node information
- corresponding to this directory has already been written: don't
- do anything; do_dump_props() will take care of dumping the
- props. If it not, dump the node itself before dumping the
- props. */
-
- SVN_ERR(dump_node(db->eb, db->repos_relpath, svn_node_dir,
- svn_node_action_change, FALSE, db->copyfrom_path,
- db->copyfrom_rev, pool));
- db->written_out = TRUE;
- }
-
/* Make sure we eventually output the props, and disable printing
a couple of extra newlines */
- db->eb->dump_newlines = FALSE;
- db->eb->dump_props = TRUE;
+ db->dump_newlines = FALSE;
+ db->dump_props = TRUE;
return SVN_NO_ERROR;
}
@@ -829,7 +916,6 @@ change_file_prop(void *file_baton,
apr_pool_t *pool)
{
struct file_baton *fb = file_baton;
- struct dump_edit_baton *eb = fb->eb;
LDR_DBG(("change_file_prop %p\n", file_baton));
@@ -837,16 +923,16 @@ change_file_prop(void *file_baton,
return SVN_NO_ERROR;
if (value)
- apr_hash_set(eb->props, apr_pstrdup(eb->pool, name),
- APR_HASH_KEY_STRING, svn_string_dup(value, eb->pool));
+ apr_hash_set(fb->props, apr_pstrdup(fb->pool, name),
+ APR_HASH_KEY_STRING, svn_string_dup(value, fb->pool));
else
- apr_hash_set(eb->deleted_props, apr_pstrdup(eb->pool, name),
+ apr_hash_set(fb->deleted_props, apr_pstrdup(fb->pool, name),
APR_HASH_KEY_STRING, "");
/* Dump the property headers and wait; close_file might need
to write text headers too depending on whether
apply_textdelta is called */
- eb->dump_props = TRUE;
+ fb->dump_props = TRUE;
return SVN_NO_ERROR;
}
@@ -875,15 +961,14 @@ apply_textdelta(void *file_baton, const
{
struct file_baton *fb = file_baton;
struct dump_edit_baton *eb = fb->eb;
-
- /* Custom handler_baton allocated in a separate pool */
struct handler_baton *hb;
svn_stream_t *delta_filestream;
- hb = apr_pcalloc(eb->pool, sizeof(*hb));
-
LDR_DBG(("apply_textdelta %p\n", file_baton));
+ /* This is custom handler_baton, allocated from a separate pool. */
+ hb = apr_pcalloc(eb->pool, sizeof(*hb));
+
/* Use a temporary file to measure the Text-content-length */
delta_filestream = svn_stream_from_aprfile2(eb->delta_file, TRUE, pool);
@@ -892,7 +977,8 @@ apply_textdelta(void *file_baton, const
delta_filestream, 0,
SVN_DELTA_COMPRESSION_LEVEL_DEFAULT, pool);
- eb->dump_text = TRUE;
+ /* Record that there's text to be dumped, and its base checksum. */
+ fb->dump_text = TRUE;
fb->base_checksum = apr_pstrdup(eb->pool, base_checksum);
/* The actual writing takes place when this function has
@@ -912,17 +998,25 @@ close_file(void *file_baton,
struct file_baton *fb = file_baton;
struct dump_edit_baton *eb = fb->eb;
apr_finfo_t *info = apr_pcalloc(pool, sizeof(apr_finfo_t));
-
+ svn_stringbuf_t *propstring;
+
LDR_DBG(("close_file %p\n", file_baton));
- /* Some pending properties to dump? Dump just the headers- dump the
- props only after dumping the text headers too (if present) */
- SVN_ERR(do_dump_props(&eb->propstring, eb->stream,
- eb->props, eb->deleted_props,
- &(eb->dump_props), FALSE, pool, pool));
+ SVN_ERR(dump_pending(eb, pool));
+
+ /* Dump the node. */
+ SVN_ERR(dump_node(eb, fb->repos_relpath, NULL, fb,
+ fb->action, fb->is_copy, fb->copyfrom_path,
+ fb->copyfrom_rev, pool));
+
+ /* Some pending properties to dump? We'll dump just the headers for
+ now, then dump the actual propchange content only after dumping
+ the text headers too (if present). */
+ SVN_ERR(do_dump_props(&propstring, eb->stream, fb->props, fb->deleted_props,
+ &(fb->dump_props), pool, pool));
/* Dump the text headers */
- if (eb->dump_text)
+ if (fb->dump_text)
{
apr_status_t err;
@@ -957,31 +1051,31 @@ close_file(void *file_baton,
/* Content-length: 1549 */
/* If both text and props are absent, skip this header */
- if (eb->dump_props)
+ if (fb->dump_props)
SVN_ERR(svn_stream_printf(eb->stream, pool,
SVN_REPOS_DUMPFILE_CONTENT_LENGTH
": %ld\n\n",
- (unsigned long)info->size + eb->propstring->len));
- else if (eb->dump_text)
+ (unsigned long)info->size + propstring->len));
+ else if (fb->dump_text)
SVN_ERR(svn_stream_printf(eb->stream, pool,
SVN_REPOS_DUMPFILE_CONTENT_LENGTH
": %ld\n\n",
(unsigned long)info->size));
/* Dump the props now */
- if (eb->dump_props)
+ if (fb->dump_props)
{
- SVN_ERR(svn_stream_write(eb->stream, eb->propstring->data,
- &(eb->propstring->len)));
+ SVN_ERR(svn_stream_write(eb->stream, propstring->data,
+ &(propstring->len)));
/* Cleanup */
- eb->dump_props = FALSE;
- SVN_ERR(svn_hash__clear(eb->props, eb->pool));
- SVN_ERR(svn_hash__clear(eb->deleted_props, eb->pool));
+ fb->dump_props = FALSE;
+ SVN_ERR(svn_hash__clear(fb->props, fb->pool));
+ SVN_ERR(svn_hash__clear(fb->deleted_props, fb->pool));
}
/* Dump the text */
- if (eb->dump_text)
+ if (fb->dump_text)
{
/* Seek to the beginning of the delta file, map it to a stream,
and copy the stream to eb->stream. Then close the stream and
@@ -998,7 +1092,6 @@ close_file(void *file_baton,
/* Cleanup */
SVN_ERR(svn_stream_close(delta_filestream));
SVN_ERR(svn_io_file_trunc(eb->delta_file, 0, pool));
- eb->dump_text = FALSE;
}
/* Write a couple of blank lines for matching output with `svnadmin
@@ -1143,6 +1236,7 @@ svn_rdump__get_dump_editor(const svn_del
eb->ra_session = ra_session;
eb->update_anchor_relpath = update_anchor_relpath;
eb->current_revision = revision;
+ eb->pending_kind = svn_node_none;
/* Create a special per-revision pool */
eb->pool = svn_pool_create(pool);
Modified: subversion/branches/tweak-build-take-two/subversion/tests/cmdline/merge_authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/tweak-build-take-two/subversion/tests/cmdline/merge_authz_tests.py?rev=1425612&r1=1425611&r2=1425612&view=diff
==============================================================================
--- subversion/branches/tweak-build-take-two/subversion/tests/cmdline/merge_authz_tests.py (original)
+++ subversion/branches/tweak-build-take-two/subversion/tests/cmdline/merge_authz_tests.py Mon Dec 24 09:49:03 2012
@@ -256,8 +256,9 @@ def mergeinfo_and_skipped_paths(sbox):
'C' : Item(),
})
expected_skip = wc.State(A_COPY_2_path, {
- 'B/E' : Item(),
- 'D/H/psi' : Item(),
+ 'B/E' : Item(),
+ 'D/G/rho' : Item(),
+ 'D/H/psi' : Item(),
})
svntest.actions.run_and_verify_merge(A_COPY_2_path, '4', '8',
sbox.repo_url + '/A', None,
Modified: subversion/branches/tweak-build-take-two/subversion/tests/cmdline/merge_reintegrate_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/tweak-build-take-two/subversion/tests/cmdline/merge_reintegrate_tests.py?rev=1425612&r1=1425611&r2=1425612&view=diff
==============================================================================
--- subversion/branches/tweak-build-take-two/subversion/tests/cmdline/merge_reintegrate_tests.py (original)
+++ subversion/branches/tweak-build-take-two/subversion/tests/cmdline/merge_reintegrate_tests.py Mon Dec 24 09:49:03 2012
@@ -825,6 +825,18 @@ def reintegrate_on_shallow_wc(sbox):
'Some more work on the A_COPY branch', wc_dir)
# Reuse the same expectations as the prior merge, except for the mergeinfo
# on the target root that now includes the latest rev on the branch.
+ expected_mergeinfo_output.add({
+ 'D' : Item(status=' U')
+ })
+ expected_A_status.tweak('D', status=' M')
+ expected_A_disk.tweak('D', props={SVN_PROP_MERGEINFO : '/A_COPY/D:2-4*'})
+ # ... a depth-restricted item is skipped ...
+ expected_A_skip.add({
+ 'D/H/psi' : Item()
+ })
+ # Currently this fails due to r1424469. For a full explanation see
+ # http://svn.haxx.se/dev/archive-2012-12/0472.shtml
+ # and http://svn.haxx.se/dev/archive-2012-12/0475.shtml
expected_A_disk.tweak('', props={SVN_PROP_MERGEINFO : '/A_COPY:2-4'})
svntest.actions.run_and_verify_merge(A_path, None, None,
sbox.repo_url + '/A_COPY', None,
Modified: subversion/branches/tweak-build-take-two/subversion/tests/cmdline/merge_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/tweak-build-take-two/subversion/tests/cmdline/merge_tests.py?rev=1425612&r1=1425611&r2=1425612&view=diff
==============================================================================
--- subversion/branches/tweak-build-take-two/subversion/tests/cmdline/merge_tests.py (original)
+++ subversion/branches/tweak-build-take-two/subversion/tests/cmdline/merge_tests.py Mon Dec 24 09:49:03 2012
@@ -7812,10 +7812,14 @@ def merge_to_sparse_directories(sbox):
# Merge r4:9 into the immediates WC.
# The root of the immediates WC should get inheritable r4:9 as should
# the one file present 'mu'. The three directory children present, 'B',
- # 'C', and 'D' are checked out at depth empty; the one of these affected
- # by the merge, 'D', gets non-inheritable mergeinfo for r4:9.
+ # 'C', and 'D' are checked out at depth empty; the two of these affected
+ # by the merge, 'B' and 'D', get non-inheritable mergeinfo for r4:9.
# The root and 'D' do should also get the changes
# that affect them directly (the prop adds from r8 and r9).
+ #
+ # Currently this fails due to r1424469. For a full explanation see
+ # http://svn.haxx.se/dev/archive-2012-12/0472.shtml
+ # and http://svn.haxx.se/dev/archive-2012-12/0475.shtml
expected_output = wc.State(immediates_dir, {
'D' : Item(status=' U'),
'mu' : Item(status='U '),
@@ -7823,14 +7827,14 @@ def merge_to_sparse_directories(sbox):
})
expected_mergeinfo_output = wc.State(immediates_dir, {
'' : Item(status=' U'),
+ 'B' : Item(status=' U'),
'D' : Item(status=' U'),
})
expected_elision_output = wc.State(immediates_dir, {
- 'D' : Item(status=' U'),
})
expected_status = wc.State(immediates_dir, {
'' : Item(status=' M', wc_rev=9),
- 'B' : Item(status=' ', wc_rev=9),
+ 'B' : Item(status=' M', wc_rev=9),
'mu' : Item(status='M ', wc_rev=9),
'C' : Item(status=' ', wc_rev=9),
'D' : Item(status=' M', wc_rev=9),
@@ -7838,12 +7842,15 @@ def merge_to_sparse_directories(sbox):
expected_disk = wc.State('', {
'' : Item(props={SVN_PROP_MERGEINFO : '/A:5-9',
"prop:name" : "propval"}),
- 'B' : Item(),
+ 'B' : Item(props={SVN_PROP_MERGEINFO : '/A/B:5-9*'}),
'mu' : Item("New content"),
'C' : Item(),
- 'D' : Item(props={"prop:name" : "propval"}),
+ 'D' : Item(props={SVN_PROP_MERGEINFO : '/A/D:5-9*',
+ "prop:name" : "propval"}),
})
expected_skip = svntest.wc.State(immediates_dir, {
+ 'D/H/omega' : Item(),
+ 'B/E/beta' : Item(),
})
svntest.actions.run_and_verify_merge(immediates_dir, '4', '9',
sbox.repo_url + '/A', None,
@@ -7896,7 +7903,8 @@ def merge_to_sparse_directories(sbox):
props={SVN_PROP_MERGEINFO : '/A/mu:5-9'}),
})
expected_skip = svntest.wc.State(files_dir, {
- 'D' : Item(),
+ 'D/H/omega' : Item(),
+ 'B/E/beta' : Item(),
})
svntest.actions.run_and_verify_merge(files_dir, '4', '9',
sbox.repo_url + '/A', None,
@@ -7939,7 +7947,8 @@ def merge_to_sparse_directories(sbox):
})
expected_skip = svntest.wc.State(empty_dir, {
'mu' : Item(),
- 'D' : Item(),
+ 'D/H/omega' : Item(),
+ 'B/E/beta' : Item(),
})
svntest.actions.run_and_verify_merge(empty_dir, '4', '9',
sbox.repo_url + '/A', None,
Modified: subversion/branches/tweak-build-take-two/subversion/tests/cmdline/merge_tree_conflict_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/tweak-build-take-two/subversion/tests/cmdline/merge_tree_conflict_tests.py?rev=1425612&r1=1425611&r2=1425612&view=diff
==============================================================================
--- subversion/branches/tweak-build-take-two/subversion/tests/cmdline/merge_tree_conflict_tests.py (original)
+++ subversion/branches/tweak-build-take-two/subversion/tests/cmdline/merge_tree_conflict_tests.py Mon Dec 24 09:49:03 2012
@@ -1331,12 +1331,19 @@ def tree_conflicts_merge_edit_onto_missi
expected_skip = svntest.wc.State('', {
'F/alpha' : Item(),
- # BH: After fixing several issues in the obstruction handling
- # I get the following Skip notification. Please review!
+ # Obstruction handling improvements in 1.7 and 1.8 added
+ 'DF/D1/beta' : Item(),
+ 'DDD/D1/D2/D3/zeta' : Item(),
+ 'DDD/D1/D2/D3' : Item(),
+ 'DDF/D1/D2/gamma' : Item(),
+ 'D/D1/delta' : Item(),
'D/D1' : Item(),
+ 'DD/D1/D2/epsilon' : Item(),
+ 'DD/D1/D2' : Item(),
})
-
+ # Currently this test fails because some parts of the merge
+ # start succeeding.
svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
[ DeepTreesTestCase(
"local_tree_missing_incoming_leaf_edit",
@@ -1410,6 +1417,12 @@ def tree_conflicts_merge_del_onto_missin
expected_skip = svntest.wc.State('', {
'F/alpha' : Item(),
'D/D1' : Item(),
+ # Obstruction handling improvements in 1.7 and 1.8 added
+ 'D/D1' : Item(),
+ 'DD/D1/D2' : Item(),
+ 'DF/D1/beta' : Item(),
+ 'DDD/D1/D2/D3' : Item(),
+ 'DDF/D1/D2/gamma' : Item(),
})
svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
Modified: subversion/branches/tweak-build-take-two/subversion/tests/cmdline/svnmucc_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/tweak-build-take-two/subversion/tests/cmdline/svnmucc_tests.py?rev=1425612&r1=1425611&r2=1425612&view=diff
==============================================================================
--- subversion/branches/tweak-build-take-two/subversion/tests/cmdline/svnmucc_tests.py (original)
+++ subversion/branches/tweak-build-take-two/subversion/tests/cmdline/svnmucc_tests.py Mon Dec 24 09:49:03 2012
@@ -45,6 +45,7 @@ def reject_bogus_mergeinfo(sbox):
# validate the mergeinfo up front then it will only test the client
svntest.actions.run_and_verify_svnmucc(None, [], expected_error,
'propset', 'svn:mergeinfo', '/B:0',
+ '-m', 'log msg',
sbox.repo_url + '/A')
_svnmucc_re = re.compile('^(r[0-9]+) committed by jrandom at (.*)$')
@@ -111,12 +112,14 @@ def basic_svnmucc(sbox):
test_svnmucc(sbox.repo_url,
['A /foo'
], # ---------
+ '-m', 'log msg',
'mkdir', 'foo')
# revision 3
test_svnmucc(sbox.repo_url,
['A /z.c',
], # ---------
+ '-m', 'log msg',
'put', empty_file, 'z.c')
# revision 4
@@ -124,6 +127,7 @@ def basic_svnmucc(sbox):
['A /foo/z.c (from /z.c:3)',
'A /foo/bar (from /foo:3)',
], # ---------
+ '-m', 'log msg',
'cp', '3', 'z.c', 'foo/z.c',
'cp', '3', 'foo', 'foo/bar')
@@ -134,6 +138,7 @@ def basic_svnmucc(sbox):
'D /foo',
'A /zig/zag (from /foo:4)',
], # ---------
+ '-m', 'log msg',
'cp', '4', 'foo', 'zig',
'rm', 'zig/bar',
'mv', 'foo', 'zig/zag')
@@ -144,6 +149,7 @@ def basic_svnmucc(sbox):
'A /zig/zag/bar/y.c (from /z.c:5)',
'A /zig/zag/bar/x.c (from /z.c:3)',
], # ---------
+ '-m', 'log msg',
'mv', 'z.c', 'zig/zag/bar/y.c',
'cp', '3', 'z.c', 'zig/zag/bar/x.c')
@@ -153,6 +159,7 @@ def basic_svnmucc(sbox):
'A /zig/zag/bar/y y.c (from /zig/zag/bar/y.c:6)',
'A /zig/zag/bar/y%20y.c (from /zig/zag/bar/y.c:6)',
], # ---------
+ '-m', 'log msg',
'mv', 'zig/zag/bar/y.c', 'zig/zag/bar/y%20y.c',
'cp', 'HEAD', 'zig/zag/bar/y.c', 'zig/zag/bar/y%2520y.c')
@@ -163,6 +170,7 @@ def basic_svnmucc(sbox):
'A /zig/zag/bar/z%20z.c (from /zig/zag/bar/y%20y.c:7)',
'A /zig/zag/bar/z z2.c (from /zig/zag/bar/y y.c:7)',
], #---------
+ '-m', 'log msg',
'mv', 'zig/zag/bar/y%20y.c', 'zig/zag/bar/z z1.c',
'cp', 'HEAD', 'zig/zag/bar/y%2520y.c', 'zig/zag/bar/z%2520z.c',
'cp', 'HEAD', 'zig/zag/bar/y y.c', 'zig/zag/bar/z z2.c')
@@ -176,6 +184,7 @@ def basic_svnmucc(sbox):
'D /zig/foo/bar/z z2.c',
'R /zig/foo/bar/z z1.c (from /zig/zag/bar/x.c:6)',
], #---------
+ '-m', 'log msg',
'mv', 'zig/zag', 'zig/foo',
'rm', 'zig/foo/bar/z z1.c',
'rm', 'zig/foo/bar/z%20z2.c',
@@ -186,6 +195,7 @@ def basic_svnmucc(sbox):
test_svnmucc(sbox.repo_url,
['R /zig/foo/bar (from /zig/z.c:9)',
], #---------
+ '-m', 'log msg',
'rm', 'zig/foo/bar',
'cp', '9', 'zig/z.c', 'zig/foo/bar')
@@ -194,6 +204,7 @@ def basic_svnmucc(sbox):
['R /zig/foo/bar (from /zig/foo/bar:9)',
'D /zig/foo/bar/z z1.c',
], #---------
+ '-m', 'log msg',
'rm', 'zig/foo/bar',
'cp', '9', 'zig/foo/bar', 'zig/foo/bar',
'rm', 'zig/foo/bar/z%20z1.c')
@@ -202,6 +213,7 @@ def basic_svnmucc(sbox):
test_svnmucc(sbox.repo_url,
['R /zig/foo (from /zig/foo/bar:11)',
], #---------
+ '-m', 'log msg',
'rm', 'zig/foo',
'cp', 'head', 'zig/foo/bar', 'zig/foo')
@@ -214,6 +226,7 @@ def basic_svnmucc(sbox):
'D /foo/foo/bar',
'R /foo/foo/foo/bar (from /foo:4)',
], #---------
+ '-m', 'log msg',
'rm', 'zig',
'cp', '4', 'foo', 'foo',
'cp', '4', 'foo', 'foo/foo',
@@ -228,6 +241,7 @@ def basic_svnmucc(sbox):
'A /boozle/buz',
'A /boozle/buz/nuz',
], #---------
+ '-m', 'log msg',
'cp', '4', 'foo', 'boozle',
'mkdir', 'boozle/buz',
'mkdir', 'boozle/buz/nuz')
@@ -238,6 +252,7 @@ def basic_svnmucc(sbox):
'A /boozle/guz (from /boozle/buz:14)',
'A /boozle/guz/svnmucc-test.py',
], #---------
+ '-m', 'log msg',
'put', empty_file, 'boozle/buz/svnmucc-test.py',
'cp', '14', 'boozle/buz', 'boozle/guz',
'put', empty_file, 'boozle/guz/svnmucc-test.py')
@@ -247,20 +262,25 @@ def basic_svnmucc(sbox):
['M /boozle/buz/svnmucc-test.py',
'R /boozle/guz/svnmucc-test.py',
], #---------
+ '-m', 'log msg',
'put', empty_file, 'boozle/buz/svnmucc-test.py',
'rm', 'boozle/guz/svnmucc-test.py',
'put', empty_file, 'boozle/guz/svnmucc-test.py')
# revision 17
test_svnmucc(sbox.repo_url,
- ['R /foo/bar (from /foo/foo:16)'], #---------
+ ['R /foo/bar (from /foo/foo:16)'
+ ], #---------
+ '-m', 'log msg',
'rm', 'foo/bar',
'cp', '16', 'foo/foo', 'foo/bar',
'propset', 'testprop', 'true', 'foo/bar')
# revision 18
test_svnmucc(sbox.repo_url,
- ['M /foo/bar'], #---------
+ ['M /foo/bar'
+ ], #---------
+ '-m', 'log msg',
'propdel', 'testprop', 'foo/bar')
# revision 19
@@ -268,6 +288,7 @@ def basic_svnmucc(sbox):
['M /foo/z.c',
'M /foo/foo',
], #---------
+ '-m', 'log msg',
'propset', 'testprop', 'true', 'foo/z.c',
'propset', 'testprop', 'true', 'foo/foo')
@@ -276,6 +297,7 @@ def basic_svnmucc(sbox):
['M /foo/z.c',
'M /foo/foo',
], #---------
+ '-m', 'log msg',
'propsetf', 'testprop', empty_file, 'foo/z.c',
'propsetf', 'testprop', empty_file, 'foo/foo')
@@ -283,6 +305,7 @@ def basic_svnmucc(sbox):
xtest_svnmucc(sbox.repo_url,
["svnmucc: E200004: 'a' is not a revision"
], #---------
+ '-m', 'log msg',
'cp', 'a', 'b')
# Expected cannot be younger error
@@ -290,18 +313,21 @@ def basic_svnmucc(sbox):
['svnmucc: E205000: Copy source revision cannot be younger ' +
'than base revision',
], #---------
+ '-m', 'log msg',
'cp', '42', 'a', 'b')
# Expected already exists error
xtest_svnmucc(sbox.repo_url,
["svnmucc: E125002: 'foo' already exists",
], #---------
+ '-m', 'log msg',
'cp', '17', 'a', 'foo')
# Expected copy_src already exists error
xtest_svnmucc(sbox.repo_url,
["svnmucc: E125002: 'a/bar' (from 'foo/bar:17') already exists",
], #---------
+ '-m', 'log msg',
'cp', '17', 'foo', 'a',
'cp', '17', 'foo/foo', 'a/bar')
@@ -309,12 +335,14 @@ def basic_svnmucc(sbox):
xtest_svnmucc(sbox.repo_url,
["svnmucc: E125002: 'a' not found",
], #---------
+ '-m', 'log msg',
'cp', '17', 'a', 'b')
def propset_root_internal(sbox, target):
## propset on ^/
svntest.actions.run_and_verify_svnmucc(None, None, [],
+ '-m', 'log msg',
'propset', 'foo', 'bar',
target)
svntest.actions.run_and_verify_svn(None, 'bar', [],
@@ -323,6 +351,7 @@ def propset_root_internal(sbox, target):
## propdel on ^/
svntest.actions.run_and_verify_svnmucc(None, None, [],
+ '-m', 'log msg',
'propdel', 'foo',
target)
svntest.actions.run_and_verify_svn(None, [], [],
@@ -338,12 +367,58 @@ def propset_root(sbox):
propset_root_internal(sbox, sbox.repo_url + '/iota')
+def too_many_log_messages(sbox):
+ "test log message mutual exclusivity checks"
+
+ sbox.build() # would use read-only=True, but need a place to stuff msg_file
+ msg_file = sbox.ospath('svnmucc_msg')
+ svntest.main.file_append(msg_file, 'some log message')
+ err_msg = ["svnmucc: E205000: --message (-m), --file (-F), and "
+ "--with-revprop=svn:log are mutually exclusive"]
+
+ xtest_svnmucc(sbox.repo_url, err_msg,
+ '--non-interactive',
+ '-m', 'log msg',
+ '-F', msg_file,
+ 'mkdir', 'A/subdir')
+ xtest_svnmucc(sbox.repo_url, err_msg,
+ '--non-interactive',
+ '-m', 'log msg',
+ '--with-revprop', 'svn:log=proppy log message',
+ 'mkdir', 'A/subdir')
+ xtest_svnmucc(sbox.repo_url, err_msg,
+ '--non-interactive',
+ '-F', msg_file,
+ '--with-revprop', 'svn:log=proppy log message',
+ 'mkdir', 'A/subdir')
+ xtest_svnmucc(sbox.repo_url, err_msg,
+ '--non-interactive',
+ '-m', 'log msg',
+ '-F', msg_file,
+ '--with-revprop', 'svn:log=proppy log message',
+ 'mkdir', 'A/subdir')
+
+@Issues(3418)
+def no_log_msg_non_interactive(sbox):
+ "test non-interactive without a log message"
+
+ sbox.build(create_wc=False)
+ xtest_svnmucc(sbox.repo_url,
+ ["svnmucc: E205001: Cannot invoke editor to get log message "
+ "when non-interactive"
+ ], #---------
+ '--non-interactive',
+ 'mkdir', 'A/subdir')
+
+
######################################################################
test_list = [ None,
reject_bogus_mergeinfo,
basic_svnmucc,
propset_root,
+ too_many_log_messages,
+ no_log_msg_non_interactive,
]
if __name__ == '__main__':
Modified: subversion/branches/tweak-build-take-two/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/tweak-build-take-two/subversion/tests/cmdline/svntest/main.py?rev=1425612&r1=1425611&r2=1425612&view=diff
==============================================================================
--- subversion/branches/tweak-build-take-two/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/tweak-build-take-two/subversion/tests/cmdline/svntest/main.py Mon Dec 24 09:49:03 2012
@@ -651,13 +651,6 @@ def _with_auth(args):
else:
return args + ('--username', wc_author )
-def _with_log_message(args):
-
- if '-m' in args or '--message' in args or '-F' in args:
- return args
- else:
- return args + ('--message', 'default log message')
-
# For running subversion and returning the output
def run_svn(error_expected, *varargs):
"""Run svn with VARARGS; return exit code as int; stdout, stderr as
@@ -705,7 +698,7 @@ def run_svnmucc(*varargs):
"""Run svnmucc with VARARGS, returns exit code as int; stdout, stderr as
list of lines (including line terminators). Use binary mode for output."""
return run_command(svnmucc_binary, 1, 1,
- *(_with_auth(_with_config_dir(_with_log_message(varargs)))))
+ *(_with_auth(_with_config_dir(varargs))))
def run_entriesdump(path):
"""Run the entries-dump helper, returning a dict of Entry objects."""
Modified: subversion/branches/tweak-build-take-two/subversion/tests/cmdline/update_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/tweak-build-take-two/subversion/tests/cmdline/update_tests.py?rev=1425612&r1=1425611&r2=1425612&view=diff
==============================================================================
--- subversion/branches/tweak-build-take-two/subversion/tests/cmdline/update_tests.py (original)
+++ subversion/branches/tweak-build-take-two/subversion/tests/cmdline/update_tests.py Mon Dec 24 09:49:03 2012
@@ -5653,7 +5653,6 @@ def update_moved_dir_file_add(sbox):
None, None, None,
None, None, 1)
-@XFail()
def update_moved_dir_dir_add(sbox):
"update locally moved dir with incoming dir"
sbox.build()
@@ -5672,8 +5671,9 @@ def update_moved_dir_dir_add(sbox):
# the incoming file should auto-merge
expected_output = svntest.wc.State(wc_dir, {
- 'A/B/E2/foo' : Item(status='A '),
- 'A/B/E2/foo/bar' : Item(status='A '),
+ 'A/B/E' : Item(status=' ', treeconflict='C'),
+ 'A/B/E/foo' : Item(status=' ', treeconflict='A'),
+ 'A/B/E/foo/bar' : Item(status=' ', treeconflict='A'),
})
expected_disk = svntest.main.greek_state.copy()
expected_disk.remove('A/B/E/alpha', 'A/B/E/beta', 'A/B/E')
@@ -5681,19 +5681,16 @@ def update_moved_dir_dir_add(sbox):
'A/B/E2' : Item(),
'A/B/E2/alpha' : Item(contents="This is the file 'alpha'.\n"),
'A/B/E2/beta' : Item(contents="This is the file 'beta'.\n"),
- 'A/B/E2/foo' : Item(),
- 'A/B/E2/foo/bar' : Item(contents=bar_content),
})
expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
expected_status.tweak('A/B/E', 'A/B/E/alpha', 'A/B/E/beta', status='D ')
+ expected_status.tweak('A/B/E', treeconflict='C')
expected_status.add({
'A/B/E/foo' : Item(status='D ', wc_rev='2'),
'A/B/E/foo/bar' : Item(status='D ', wc_rev='2'),
'A/B/E2' : Item(status='A ', copied='+', wc_rev='-'),
'A/B/E2/beta' : Item(status=' ', copied='+', wc_rev='-'),
'A/B/E2/alpha' : Item(status=' ', copied='+', wc_rev='-'),
- 'A/B/E2/foo' : Item(status='A ', copied='+', wc_rev='-'),
- 'A/B/E2/foo/bar' : Item(status='A ', copied='+', wc_rev='-'),
})
svntest.actions.run_and_verify_update(wc_dir,
expected_output,
@@ -5701,6 +5698,16 @@ def update_moved_dir_dir_add(sbox):
expected_status,
None, None, None,
None, None, 1)
+ svntest.actions.run_and_verify_svn("resolve failed", None, [],
+ 'resolve',
+ '--recursive',
+ '--accept=mine-conflict', wc_dir)
+ expected_status.tweak(treeconflict=None)
+ expected_status.add({
+ 'A/B/E2/foo' : Item(status=' ', copied='+', wc_rev='-'),
+ 'A/B/E2/foo/bar' : Item(status=' ', copied='+', wc_rev='-'),
+ })
+ svntest.actions.run_and_verify_status(wc_dir, expected_status)
@XFail()
@Issue(4037)
Modified: subversion/branches/tweak-build-take-two/subversion/tests/cmdline/upgrade_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/tweak-build-take-two/subversion/tests/cmdline/upgrade_tests.py?rev=1425612&r1=1425611&r2=1425612&view=diff
==============================================================================
--- subversion/branches/tweak-build-take-two/subversion/tests/cmdline/upgrade_tests.py (original)
+++ subversion/branches/tweak-build-take-two/subversion/tests/cmdline/upgrade_tests.py Mon Dec 24 09:49:03 2012
@@ -1143,18 +1143,21 @@ def upgrade_file_externals(sbox):
expected_output = svntest.verify.RegexOutput('r2 committed.*')
svntest.actions.run_and_verify_svnmucc(None, expected_output, [],
+ '-m', 'r2',
'propset', 'svn:externals',
'^/A/B/E EX\n^/A/mu muX',
sbox.repo_url + '/A/B/F')
expected_output = svntest.verify.RegexOutput('r3 committed.*')
svntest.actions.run_and_verify_svnmucc(None, expected_output, [],
+ '-m', 'r3',
'propset', 'svn:externals',
'^/A/B/F FX\n^/A/B/lambda lambdaX',
sbox.repo_url + '/A/C')
expected_output = svntest.verify.RegexOutput('r4 committed.*')
svntest.actions.run_and_verify_svnmucc(None, expected_output, [],
+ '-m', 'r4',
'propset', 'pname1', 'pvalue1',
sbox.repo_url + '/A/mu',
'propset', 'pname2', 'pvalue2',
Modified: subversion/branches/tweak-build-take-two/subversion/tests/libsvn_repos/repos-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/tweak-build-take-two/subversion/tests/libsvn_repos/repos-test.c?rev=1425612&r1=1425611&r2=1425612&view=diff
==============================================================================
--- subversion/branches/tweak-build-take-two/subversion/tests/libsvn_repos/repos-test.c (original)
+++ subversion/branches/tweak-build-take-two/subversion/tests/libsvn_repos/repos-test.c Mon Dec 24 09:49:03 2012
@@ -1212,7 +1212,7 @@ authz(apr_pool_t *pool)
svn_error_t *err;
svn_boolean_t access_granted;
apr_pool_t *subpool = svn_pool_create(pool);
- int i;
+
/* Definition of the paths to test and expected replies for each. */
struct check_access_tests test_set[] = {
/* Test that read rules are correctly used. */