Troy,
I have reviewed and tested this patch now. The structure is great: thanks for
moving things into libsvn_client while maintaining backward compatibility. It
works fine. I tweaked a little bit: mainly a doc-string or two, and added
localisation macros around the error message strings.
Committed in r30753.
Thanks very much for doing this.
- Julian
Troy Curtis Jr wrote:
> Here is my first shot at implementing the command-line repository root
> relative url support in libsvn_client. Note to Julian: I chose not to return
> a structure because after looking into it I found that it was a much larger
> job than I wanted to do for relative url support...it was definetly not a
> "gimme". I also found that it did not really gain me (or this patch) much
> benefit.
>
> [[[
> Implement repository root relative url support for the svn command-line
> client. This allows the user to use '^/' in front of any target to
> mean the repository root url. The repository root url is determined by
> checking the other arguments' root urls (if they exist) and using that common
> url. If none is found the root url of the current directory is used. If no
> common repository root url can be found, an error is generated.
>
> * subversion/include/private/svn_opt_private.h
> New file to hold inter-library svn_opt functions.
> (svn_opt__arg_canonicalize_url): New function prototype.
> (svn_opt__arg_canonicalize_path): New function prototype.
>
> * subversion/include/svn_opt.h
> (svn_opt_args_to_target_array3): Change doc string to reflect deprecated
> status.
>
> * subversion/libsvn_subr/opt.c
> (svn_opt__arg_canonicalize_url): New function to canonicalize user input
> urls.
> (svn_opt__arg_canonicalize_path): New function to canonicalize user input
> paths.
> (svn_opt_args_to_target_array3): Replace the inline canonicalization code
> with calls to the new svn_opt__arg_canonicalize_* functions.
>
> * subversion/include/svn_client.h
> (svn_client_args_to_target_array): New function prototype.
>
> * subversion/libsvn_client/cmdline.c
> New file for client library commandline processing functionality.
> (arg_is_repos_relative_url,
> resolve_repos_relative_url,
> check_root_url_of_target): New functions to support
> svn_client_args_to_target_array.
> (svn_client_args_to_target_array): New client function to parse user
> arguments into a target array. Replaces use of
> svn_opt_args_to_target_array3()
>
> * subversion/tests/libsvn_client/client-test.c
> (test_args_to_target_array): New test function.
> (test_funcs): Run new test function.
>
> * subversion/tests/cmdline/special_tests.py
> (warn_on_reserved_name): Modify test to work right with
> svn_client_args_to_target_array.
>
> * subversion/tests/cmdline/basic_tests.py
> (basic_relative_url_multi_repo,
> basic_relative_url_using_other_targets,
> basic_relative_url_using_current_dir): New test functions.
> (test_list): Run new test functions.
>
> * subversion/svn/cl.h
> (svn_cl__args_to_target_array_print_reserved): Add client context parameter.
>
> * subversion/svn/util.c
> (svn_cl__args_to_target_array_print_reserved): Replace call to
> svn_opt_args_to_target_array3() with svn_client_args_to_target_array().
>
> * subversion/svn/update-cmd.c
> (svn_cl__update): Replace svn_opt_args_to_target_array3() with
> svn_cl__args_to_target_array_print_reserved() for consistency with the other
> command line functions.
>
> * subversion/svn/diff-cmd.c
> (svn_cl__diff): Create a client context variable and use it in the
> svn_cl__args_to_target_array_print_reserved() function along with every
> else it is needed.
>
> * subversion/svn/merge-cmd.c,
> subversion/svn/propdel-cmd.c,
> subversion/svn/checkout-cmd.c,
> subversion/svn/move-cmd.c,
> subversion/svn/mkdir-cmd.c,
> subversion/svn/cat-cmd.c,
> subversion/svn/revert-cmd.c,
> subversion/svn/copy-cmd.c,
> subversion/svn/mergeinfo-cmd.c,
> subversion/svn/list-cmd.c,
> subversion/svn/blame-cmd.c,
> subversion/svn/propget-cmd.c,
> subversion/svn/changelist-cmd.c,
> subversion/svn/log-cmd.c,
> subversion/svn/resolved-cmd.c,
> subversion/svn/cleanup-cmd.c,
> subversion/svn/commit-cmd.c,
> subversion/svn/add-cmd.c,
> subversion/svn/propset-cmd.c,
> subversion/svn/switch-cmd.c,
> subversion/svn/delete-cmd.c,
> subversion/svn/import-cmd.c,
> subversion/svn/proplist-cmd.c,
> subversion/svn/export-cmd.c,
> subversion/svn/status-cmd.c,
> subversion/svn/propedit-cmd.c,
> subversion/svn/lock-cmd.c,
> subversion/svn/info-cmd.c,
> subversion/svn/unlock-cmd.c
> Add client context variable to all the calls to
> svn_cl__args_to_target_array_print_reserved().
> ]]]
>
> Troy
>
>
> ------------------------------------------------------------------------
>
> Index: subversion/include/svn_client.h
> ===================================================================
> --- subversion/include/svn_client.h (revision 29840)
> +++ subversion/include/svn_client.h (working copy)
> @@ -889,6 +889,44 @@ typedef struct svn_client_ctx_t
> #define SVN_CLIENT_AUTH_PASSWORD "password"
> /** @} group end: Authentication information file names */
>
> +/** Client argument processing
> + *
> + * @defgroup clnt_cmdline Client command-line processing
> + *
> + * @{
> + */
> +
> +/**
> + * Pull remaining target argument from @a os into @a *targets_p,
> + * converting them to UTF-8, followed by targets from @a known_targets
> + * (which might come from, for example, the "--targets" command line option).
> + *
> + * On each URL target, do some IRI-to-URI encoding and some auto-escaping.
> + * On each local path, canonicalize case and path separators.
> + *
> + * Allocate @a *targets_p and its elements in @a pool.
> + *
> + * @ctx is required for possible repository authentication.
> + *
> + * If a path has the same name as a Subversion working copy
> + * administrative directory, return SVN_ERR_RESERVED_FILENAME_SPECIFIED;
> + * if multiple reserved paths are encountered, return a chain of
> + * errors, all of which are SVN_ERR_RESERVED_FILENAME_SPECIFIED. Do
> + * not return this type of error in a chain with any other type of
> + * error, and if this is the only type of error encountered, complete
> + * the operation before returning the error(s).
> + *
> + * @since New in 1.6
> + */
> +svn_error_t *
> +svn_client_args_to_target_array(apr_array_header_t **targets_p,
> + apr_getopt_t *os,
> + apr_array_header_t *known_targets,
> + svn_client_ctx_t *ctx,
> + apr_pool_t *pool);
> +
> +/** @} group end: Client command-line processing */
> +
> /** @} */
>
> /**
> Index: subversion/include/private/svn_opt_private.h
> ===================================================================
> --- subversion/include/private/svn_opt_private.h (revision 0)
> +++ subversion/include/private/svn_opt_private.h (revision 0)
> @@ -0,0 +1,65 @@
> +/**
> + * @copyright
> + * ====================================================================
> + * Copyright (c) 2008 CollabNet. All rights reserved.
> + *
> + * This software is licensed as described in the file COPYING, which
> + * you should have received as part of this distribution. The terms
> + * are also available at http://subversion.tigris.org/license-1.html.
> + * If newer versions of this license are posted there, you may use a
> + * newer version instead, at your option.
> + *
> + * This software consists of voluntary contributions made by many
> + * individuals. For exact contribution history, see the revision
> + * history and logs, available at http://subversion.tigris.org/.
> + * ====================================================================
> + * @endcopyright
> + *
> + * @file svn_opt_private.h
> + * @brief Subversion-internal option parsing APIs.
> + */
> +
> +#ifndef SVN_OPT_PRIVATE_H
> +#define SVN_OPT_PRIVATE_H
> +
> +#include <apr_pools.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif /* __cplusplus */
> +
> +/* Attempt to transform URL_IN, which is a URL-like user input, into a
> + * valid URL:
> + * - escape IRI characters and some other non-URI characters
> + * - check that only valid URI characters remain
> + * - check that no back-path ("..") components are present
> + * - canonicalize the separator ("/") characters
> + * URL_IN is in UTF-8 encoding and has no peg revision specifier.
> + * Set *URL_OUT to the result, allocated from POOL.
> + */
> +svn_error_t *
> +svn_opt__arg_canonicalize_url(const char **url_out,
> + const char *url_in,
> + apr_pool_t *pool);
> +
> +/*
> + * Attempt to transform PATH_IN, which is a local path-like user input, into a
> + * valid local path:
> + * - Attempt to get the correct capitialization by trying to actually find
> + * the path specified.
> + * - If the path does not exist (which is valid) the given capitialization
> + * is used.
> + * - canonicalize the separator ("/") characters
> + * PATH_IN is in UTF-8 encoding and has no peg revision specifier.
> + * Set *PATH_OUT to the result, allocated from POOL.
> + */
> +svn_error_t *
> +svn_opt__arg_canonicalize_path(const char **path_out,
> + const char *path_in,
> + apr_pool_t *pool);
> +
> +#ifdef __cplusplus
> +}
> +#endif /* __cplusplus */
> +
> +#endif /* SVN_OPT_PRIVATE_H */
> Index: subversion/include/svn_opt.h
> ===================================================================
> --- subversion/include/svn_opt.h (revision 29840)
> +++ subversion/include/svn_opt.h (working copy)
> @@ -489,7 +489,7 @@ svn_opt_resolve_revisions(svn_opt_revision_t *peg_
> * error, and if this is the only type of error encountered, complete
> * the operation before returning the error(s).
> *
> - * @since New in 1.5.
> + * @deprecated Provided for backward compatibility with the 1.5 API.
> */
> svn_error_t *
> svn_opt_args_to_target_array3(apr_array_header_t **targets_p,
> Index: subversion/libsvn_subr/opt.c
> ===================================================================
> --- subversion/libsvn_subr/opt.c (revision 29840)
> +++ subversion/libsvn_subr/opt.c (working copy)
> @@ -37,6 +37,8 @@
> #include "svn_utf.h"
> #include "svn_time.h"
>
> +#include "private/svn_opt_private.h"
> +
> #include "svn_private_config.h"
>
>
> @@ -965,59 +967,14 @@ svn_opt_args_to_target_array3(apr_array_header_t *
> /* URLs and wc-paths get treated differently. */
> if (svn_path_is_url(utf8_target))
> {
> - /* No need to canonicalize a URL's case or path separators. */
> -
> - /* Convert to URI. */
> - target = svn_path_uri_from_iri(utf8_target, pool);
> - /* Auto-escape some ASCII characters. */
> - target = svn_path_uri_autoescape(target, pool);
> -
> - /* The above doesn't guarantee a valid URI. */
> - if (! svn_path_is_uri_safe(target))
> - return svn_error_createf(SVN_ERR_BAD_URL, 0,
> - _("URL '%s' is not properly URI-encoded"),
> - utf8_target);
> -
> - /* Verify that no backpaths are present in the URL. */
> - if (svn_path_is_backpath_present(target))
> - return svn_error_createf(SVN_ERR_BAD_URL, 0,
> - _("URL '%s' contains a '..' element"),
> - utf8_target);
> -
> - /* strip any trailing '/' */
> - target = svn_path_canonicalize(target, pool);
> + SVN_ERR(svn_opt__arg_canonicalize_url(&target, utf8_target, pool));
> }
> else /* not a url, so treat as a path */
> {
> - const char *apr_target;
> const char *base_name;
> - char *truenamed_target; /* APR-encoded */
> - apr_status_t apr_err;
>
> - /* canonicalize case, and change all separators to '/'. */
> - SVN_ERR(svn_path_cstring_from_utf8(&apr_target, utf8_target,
> - pool));
> - apr_err = apr_filepath_merge(&truenamed_target, "", apr_target,
> - APR_FILEPATH_TRUENAME, pool);
> + SVN_ERR(svn_opt__arg_canonicalize_path(&target, utf8_target, pool));
>
> - if (!apr_err)
> - /* We have a canonicalized APR-encoded target now. */
> - apr_target = truenamed_target;
> - else if (APR_STATUS_IS_ENOENT(apr_err))
> - /* It's okay for the file to not exist, that just means we
> - have to accept the case given to the client. We'll use
> - the original APR-encoded target. */
> - ;
> - else
> - return svn_error_createf(apr_err, NULL,
> - _("Error resolving case of '%s'"),
> - svn_path_local_style(utf8_target,
> - pool));
> -
> - /* convert back to UTF-8. */
> - SVN_ERR(svn_path_cstring_to_utf8(&target, apr_target, pool));
> - target = svn_path_canonicalize(target, pool);
> -
> /* If the target has the same name as a Subversion
> working copy administrative dir, skip it. */
> base_name = svn_path_basename(target, pool);
> @@ -1141,7 +1098,69 @@ svn_opt_parse_revprop(apr_hash_t **revprop_table_p
> return SVN_NO_ERROR;
> }
>
> +svn_error_t *
> +svn_opt__arg_canonicalize_url(const char **url_out, const char *url_in,
> + apr_pool_t *pool)
> +{
> + const char *target;
>
> + /* Convert to URI. */
> + target = svn_path_uri_from_iri(url_in, pool);
> + /* Auto-escape some ASCII characters. */
> + target = svn_path_uri_autoescape(target, pool);
> +
> + /* The above doesn't guarantee a valid URI. */
> + if (! svn_path_is_uri_safe(target))
> + return svn_error_createf(SVN_ERR_BAD_URL, 0,
> + _("URL '%s' is not properly URI-encoded"),
> + target);
> +
> + /* Verify that no backpaths are present in the URL. */
> + if (svn_path_is_backpath_present(target))
> + return svn_error_createf(SVN_ERR_BAD_URL, 0,
> + _("URL '%s' contains a '..' element"),
> + target);
> +
> + /* strip any trailing '/' and collapse other redundant elements */
> + target = svn_path_canonicalize(target, pool);
> +
> + *url_out = target;
> + return SVN_NO_ERROR;
> +}
> +
> +svn_error_t *
> +svn_opt__arg_canonicalize_path(const char **path_out, const char *path_in,
> + apr_pool_t *pool)
> +{
> + const char *apr_target;
> + char *truenamed_target; /* APR-encoded */
> + apr_status_t apr_err;
> +
> + /* canonicalize case, and change all separators to '/'. */
> + SVN_ERR(svn_path_cstring_from_utf8(&apr_target, path_in, pool));
> + apr_err = apr_filepath_merge(&truenamed_target, "", apr_target,
> + APR_FILEPATH_TRUENAME, pool);
> +
> + if (!apr_err)
> + /* We have a canonicalized APR-encoded target now. */
> + apr_target = truenamed_target;
> + else if (APR_STATUS_IS_ENOENT(apr_err))
> + /* It's okay for the file to not exist, that just means we
> + have to accept the case given to the client. We'll use
> + the original APR-encoded target. */
> + ;
> + else
> + return svn_error_createf(apr_err, NULL,
> + _("Error resolving case of '%s'"),
> + svn_path_local_style(path_in, pool));
> +
> + /* convert back to UTF-8. */
> + SVN_ERR(svn_path_cstring_to_utf8(path_out, apr_target, pool));
> + *path_out = svn_path_canonicalize(*path_out, pool);
> +
> + return SVN_NO_ERROR;
> +}
> +
> /* Print version info for PGM_NAME. If QUIET is true, print in
> * brief. Else if QUIET is not true, print the version more
> * verbosely, and if FOOTER is non-null, print it following the
> Index: subversion/libsvn_client/cmdline.c
> ===================================================================
> --- subversion/libsvn_client/cmdline.c (revision 0)
> +++ subversion/libsvn_client/cmdline.c (revision 0)
> @@ -0,0 +1,307 @@
> +/*
> + * cmdline.c: command-line processing
> + *
> + * ====================================================================
> + * Copyright (c) 2000-2007 CollabNet. All rights reserved.
> + *
> + * This software is licensed as described in the file COPYING, which
> + * you should have received as part of this distribution. The terms
> + * are also available at http://subversion.tigris.org/license-1.html.
> + * If newer versions of this license are posted there, you may use a
> + * newer version instead, at your option.
> + *
> + * This software consists of voluntary contributions made by many
> + * individuals. For exact contribution history, see the revision
> + * history and logs, available at http://subversion.tigris.org/.
> + * ====================================================================
> + */
> +
> +/* ==================================================================== */
> +
> +
> +/*** Includes. ***/
> +#include "svn_client.h"
> +#include "svn_error.h"
> +#include "svn_path.h"
> +#include "svn_opt.h"
> +#include "svn_utf.h"
> +
> +#include "client.h"
> +
> +#include "private/svn_opt_private.h"
> +
> +
> +/*** Code. ***/
> +
> +#define DEFAULT_ARRAY_SIZE 5
> +
> +/* Return true iff ARG is a repository-relative URL: specifically that
> + * it starts with the characters "^/".
> + * ARG is in UTF-8 encoding.
> + * Do not check whether ARG is properly URI-encoded, canonical, or valid
> + * in any other way. */
> +static svn_boolean_t
> +arg_is_repos_relative_url(const char *arg)
> +{
> + return (0 == strncmp("^/", arg, 2));
> +}
> +
> +/* Set *ABSOLUTE_URL to the absolute URL represented by RELATIVE_URL
> + * relative to REPOS_ROOT_URL.
> + * *ABSOLUTE_URL will end with a peg revision specifier if RELATIVE_URL did.
> + * RELATIVE_URL is in repository-relative syntax:
> + * "^/[REL-URL][@PEG]",
> + * REPOS_ROOT_URL is the absolute URL of the repository root.
> + * All strings are in UTF-8 encoding.
> + * Allocate *ABSOLUTE_URL in POOL.
> + */
> +static svn_error_t *
> +resolve_repos_relative_url(const char **absolute_url,
> + const char *relative_url,
> + const char *repos_root_url,
> + apr_pool_t *pool)
> +{
> + if (! arg_is_repos_relative_url(relative_url))
> + return svn_error_createf(SVN_ERR_BAD_URL, NULL,
> + "Improper relative URL '%s'",
> + relative_url);
> +
> + *absolute_url = svn_path_join(repos_root_url, relative_url + 2, pool);
> +
> + return SVN_NO_ERROR;
> +}
> +
> +
> +/* Attempt to find the root url for TARGET possibly using CTX for
> + * authentication. If one is found and *ROOT_URL is
> + * not NULL, then the root url for TARGET must match the value given in
> + * *ROOT_URL. If *ROOT_URL is NULL then set it with the root url allocated
> + * from POOL as determined from TARGET.
> + *
> + * TARGET is a UTF-8 encoded string that is fully canonicalized and escaped.
> + *
> + * If a root url is not found for TARGET because it does not exist in the
> + * repository, then return with no error.
> + */
> +static svn_error_t *
> +check_root_url_of_target(const char **root_url,
> + const char *target,
> + svn_client_ctx_t *ctx,
> + apr_pool_t *pool)
> +{
> + svn_error_t *error;
> + const char *tmp_root_url;
> + const char *truepath;
> + svn_opt_revision_t opt_rev;
> +
> + SVN_ERR(svn_opt_parse_path(&opt_rev, &truepath, target, pool));
> +
> + if ((error = svn_client__get_repos_root(&tmp_root_url,
> + truepath,
> + &opt_rev,
> + NULL, ctx, pool)))
> + {
> + /* It is OK if the given target does not exist, it just means
> + * we will not be able to determine the root url from this particular
> + * argument.
> + */
> + if ( (error->apr_err == SVN_ERR_ENTRY_NOT_FOUND)
> + || (error->apr_err == SVN_ERR_WC_NOT_DIRECTORY))
> + {
> + svn_error_clear(error);
> + return SVN_NO_ERROR;
> + }
> + else
> + return error;
> + }
> + else if ( (*root_url != NULL)
> + && (strcmp(*root_url, tmp_root_url) != 0))
> + return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
> + "All non-relative targets must have the same root url.");
> + else
> + *root_url = tmp_root_url;
> +
> + return SVN_NO_ERROR;
> +}
> +
> +svn_error_t *
> +svn_client_args_to_target_array(apr_array_header_t **targets_p,
> + apr_getopt_t *os,
> + apr_array_header_t *known_targets,
> + svn_client_ctx_t *ctx,
> + apr_pool_t *pool)
> +{
> + int i;
> + svn_boolean_t rel_url_found = FALSE;
> + const char *root_url = NULL;
> + svn_error_t *err = SVN_NO_ERROR;
> + apr_array_header_t *input_targets =
> + apr_array_make(pool, DEFAULT_ARRAY_SIZE, sizeof(const char *));
> + apr_array_header_t *output_targets =
> + apr_array_make(pool, DEFAULT_ARRAY_SIZE, sizeof(const char *));
> +
> + /* Step 1: create a master array of targets that are in UTF-8
> + encoding, and come from concatenating the targets left by apr_getopt,
> + plus any extra targets (e.g., from the --targets switch.)
> + If any of the targets are relative urls, then set the rel_url_found
> + flag.*/
> +
> + for (; os->ind < os->argc; os->ind++)
> + {
> + /* The apr_getopt targets are still in native encoding. */
> + const char *raw_target = os->argv[os->ind];
> + const char *utf8_target;
> +
> + SVN_ERR(svn_utf_cstring_to_utf8(&utf8_target,
> + raw_target, pool));
> +
> + if (arg_is_repos_relative_url(utf8_target))
> + rel_url_found = TRUE;
> +
> + APR_ARRAY_PUSH(input_targets, const char *) = utf8_target;
> + }
> +
> + if (known_targets)
> + {
> + for (i = 0; i < known_targets->nelts; i++)
> + {
> + /* The --targets array have already been converted to UTF-8,
> + because we needed to split up the list with svn_cstring_split. */
> + const char *utf8_target = APR_ARRAY_IDX(known_targets,
> + i, const char *);
> +
> + if (arg_is_repos_relative_url(utf8_target))
> + rel_url_found = TRUE;
> +
> + APR_ARRAY_PUSH(input_targets, const char *) = utf8_target;
> + }
> + }
> +
> + /* Step 2: process each target. */
> +
> + for (i = 0; i < input_targets->nelts; i++)
> + {
> + const char *utf8_target = APR_ARRAY_IDX(input_targets, i, const char *);
> + const char *peg_start = NULL; /* pointer to the peg revision, if any */
> + const char *target;
> + int j;
> +
> + /* Remove a peg revision, if any, in the target so that it can
> + be properly canonicalized, otherwise the canonicalization
> + does not treat a "._at_BASE" as a "." with a BASE peg revision,
> + and it is not canonicalized to "@BASE". If any peg revision
> + exists, it is appended to the final canonicalized path or
> + URL. Do not use svn_opt_parse_path() because the resulting
> + peg revision is a structure that would have to be converted
> + back into a string. Converting from a string date to the
> + apr_time_t field in the svn_opt_revision_value_t and back to
> + a string would not necessarily preserve the exact bytes of
> + the input date, so its easier just to keep it in string
> + form. */
> + for (j = (strlen(utf8_target) - 1); j >= 0; --j)
> + {
> + /* If we hit a path separator, stop looking. This is OK
> + only because our revision specifiers can't contain
> + '/'. */
> + if (utf8_target[j] == '/')
> + break;
> + if (utf8_target[j] == '@')
> + {
> + peg_start = utf8_target + j;
> + break;
> + }
> + }
> + if (peg_start)
> + utf8_target = apr_pstrmemdup(pool,
> + utf8_target,
> + peg_start - utf8_target);
> +
> + /* Relative urls will be canonicallized when they are resolved later in
> + * the function
> + */
> + if (arg_is_repos_relative_url(utf8_target))
> + {
> + APR_ARRAY_PUSH(output_targets, const char *) = utf8_target;
> + }
> + else
> + {
> + /* URLs and wc-paths get treated differently. */
> + if (svn_path_is_url(utf8_target))
> + {
> + SVN_ERR(svn_opt__arg_canonicalize_url(&target,
> + utf8_target, pool));
> + }
> + else /* not a url, so treat as a path */
> + {
> + const char *base_name;
> +
> + SVN_ERR(svn_opt__arg_canonicalize_path(&target,
> + utf8_target, pool));
> +
> + /* If the target has the same name as a Subversion
> + working copy administrative dir, skip it. */
> + base_name = svn_path_basename(target, pool);
> +
> + if (svn_wc_is_adm_dir(base_name, pool))
> + {
> + err = svn_error_createf(SVN_ERR_RESERVED_FILENAME_SPECIFIED,
> + err,
> + "'%s' ends in a reserved name",
> + target);
> + continue;
> + }
> + }
> +
> + /* Append the peg revision back to the canonicalized target if
> + there was a peg revision. */
> + if (peg_start)
> + target = apr_pstrcat(pool, target, peg_start, NULL);
> +
> + if (rel_url_found)
> + {
> + SVN_ERR(check_root_url_of_target(&root_url, target,
> + ctx, pool));
> + }
> +
> + APR_ARRAY_PUSH(output_targets, const char *) = target;
> + }
> + }
> +
> + /* Only resolve relative urls if there were some actually found earlier. */
> + if (rel_url_found)
> + {
> + /*
> + * Use the current directory's root url if one wasn't found using the
> + * arguments.
> + */
> + if (root_url == NULL)
> + SVN_ERR(svn_client_root_url_from_path(&root_url,
> + svn_path_canonicalize(".", pool),
> + ctx, pool));
> +
> + *targets_p = apr_array_make(pool, output_targets->nelts, sizeof(const char *));
> +
> + for (i = 0; i < output_targets->nelts; i++)
> + {
> + const char *target = APR_ARRAY_IDX(output_targets, i,
> + const char *);
> +
> + if (arg_is_repos_relative_url(target))
> + {
> + const char *abs_target;
> +
> + SVN_ERR(resolve_repos_relative_url(&abs_target, target,
> + root_url, pool));
> +
> + SVN_ERR(svn_opt__arg_canonicalize_url(&target, abs_target,
> + pool));
> + }
> +
> + APR_ARRAY_PUSH(*targets_p, const char *) = target;
> + }
> + }
> + else
> + *targets_p = output_targets;
> +
> + return err;
> +}
> Index: subversion/tests/libsvn_client/client-test.c
> ===================================================================
> --- subversion/tests/libsvn_client/client-test.c (revision 29840)
> +++ subversion/tests/libsvn_client/client-test.c (working copy)
> @@ -20,6 +20,7 @@
> #include "svn_mergeinfo.h"
> #include "../../libsvn_client/mergeinfo.h"
> #include "svn_pools.h"
> +#include "svn_client.h"
>
> #include "../svn_test.h"
>
> @@ -98,11 +99,117 @@ test_elide_mergeinfo_catalog(const char **msg,
> return SVN_NO_ERROR;
> }
>
> +static svn_error_t *
> +test_args_to_target_array(const char **msg,
> + svn_boolean_t msg_only,
> + svn_test_opts_t *opts,
> + apr_pool_t *pool)
> +{
> + apr_size_t i;
> + apr_pool_t *iterpool;
> + svn_client_ctx_t *ctx;
> + static struct {
> + const char *input;
> + const char *output; /* NULL means an error is expected. */
> + } const tests[] = {
> + { ".", "" },
> + { "._at_BASE", "@BASE" },
> + { "foo///bar", "foo/bar" },
> + { "foo///bar_at_13", "foo/bar_at_13" },
> + { "foo///bar_at_HEAD", "foo/bar_at_HEAD" },
> + { "foo///bar@{1999-12-31}", "foo/bar@{1999-12-31}" },
> + { "http://a//b////", "http://a/b" },
> + { "http://a///b@27", "http://a/b@27" },
> + { "http://a/b//@COMMITTED", "http://a/b@COMMITTED" },
> + { "foo///bar_at_1:2", "foo/bar_at_1:2" },
> + { "foo///bar_at_baz", "foo/bar_at_baz" },
> + { "foo///bar@", "foo/bar@" },
> + { "foo///bar///@13", "foo/bar_at_13" },
> + { "foo///bar@@13", "foo/bar@@13" },
> + { "foo///@bar_at_HEAD", "foo/@bar_at_HEAD" },
> + { "foo@///bar", "foo@/bar" },
> + { "foo_at_HEAD///bar", "foo_at_HEAD/bar" },
> + };
> +
> + *msg = "test svn_client_args_to_target_array";
> + if (msg_only)
> + return SVN_NO_ERROR;
> +
> + SVN_ERR(svn_client_create_context(&ctx, pool));
> +
> + iterpool = svn_pool_create(pool);
> +
> + for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
> + {
> + const char *input = tests[i].input;
> + const char *expected_output = tests[i].output;
> + apr_array_header_t *targets;
> + apr_getopt_t *os;
> + const int argc = 2;
> + const char *argv[] = { "opt-test", input, NULL };
> + apr_status_t apr_err;
> + svn_error_t *err;
> +
> + apr_err = apr_getopt_init(&os, iterpool, argc, argv);
> + if (apr_err)
> + return svn_error_wrap_apr(apr_err,
> + "Error initializing command line arguments");
> +
> + err = svn_client_args_to_target_array(&targets, os, NULL, ctx, iterpool);
> +
> + if (expected_output)
> + {
> + const char *actual_output;
> +
> + if (err)
> + return err;
> + if (argc - 1 != targets->nelts)
> + return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
> + "Passed %d target(s) to "
> + "svn_client_args_to_target_array() but "
> + "got %d back.",
> + argc - 1,
> + targets->nelts);
> +
> + actual_output = APR_ARRAY_IDX(targets, 0, const char *);
> +
> + if (! svn_path_is_canonical(actual_output, iterpool))
> + return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
> + "Input '%s' to "
> + "svn_client_args_to_target_array() should "
> + "have returned a canonical path but "
> + "'%s' is not.",
> + input,
> + actual_output);
> +
> + if (strcmp(expected_output, actual_output) != 0)
> + return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
> + "Input '%s' to "
> + "svn_client_args_to_target_array() should "
> + "have returned '%s' but returned '%s'.",
> + input,
> + expected_output,
> + actual_output);
> + }
> + else
> + {
> + if (! err)
> + return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
> + "Unexpected success in passing '%s' "
> + "to svn_client_args_to_target_array().",
> + input);
> + }
> + }
> +
> + return SVN_NO_ERROR;
> +}
> +
> /* ========================================================================== */
>
> struct svn_test_descriptor_t test_funcs[] =
> {
> SVN_TEST_NULL,
> SVN_TEST_PASS(test_elide_mergeinfo_catalog),
> + SVN_TEST_PASS(test_args_to_target_array),
> SVN_TEST_NULL
> };
> Index: subversion/tests/cmdline/special_tests.py
> ===================================================================
> --- subversion/tests/cmdline/special_tests.py (revision 29840)
> +++ subversion/tests/cmdline/special_tests.py (working copy)
> @@ -613,18 +613,18 @@ def warn_on_reserved_name(sbox):
> sbox.build()
> wc_dir = sbox.wc_dir
> if os.path.exists(os.path.join(wc_dir, ".svn")):
> + reserved_path = os.path.join(wc_dir, ".svn")
> + elif os.path.exists(os.path.join(wc_dir, "_svn")):
> reserved_path = os.path.join(wc_dir, "_svn")
> - elif os.path.exists(os.path.join(wc_dir, "_svn")):
> - reserved_path = os.path.join(wc_dir, ".svn")
> else:
> # We don't know how to test this, but have no reason to believe
> # it would fail. (TODO: any way to return 'Skip', though?)
> return
> - svntest.main.file_append(reserved_path, 'expecting rejection')
> svntest.actions.run_and_verify_svn(
> - "Adding a file with a reserved name failed to result in an error",
> - None, ".*Skipping argument: '.+' ends in a reserved name.*",
> - 'add', reserved_path)
> + "Locking a file with a reserved name failed to result in an error",
> + None,
> + ".*Skipping argument: '.+' ends in a reserved name.*",
> + 'lock', reserved_path)
>
>
> ########################################################################
> Index: subversion/tests/cmdline/basic_tests.py
> ===================================================================
> --- subversion/tests/cmdline/basic_tests.py (revision 29840)
> +++ subversion/tests/cmdline/basic_tests.py (working copy)
> @@ -2162,7 +2162,93 @@ def info_nonexisting_file(sbox):
>
>
> #----------------------------------------------------------------------
> +# Relative urls
> +#
> +# Use blame to test three specific cases for relative url support.
> +def basic_relative_url_using_current_dir(sbox):
> + "basic relative url target using current dir"
>
> + # We'll use blame to test relative url parsing
> + sbox.build()
> +
> + # First, make a new revision of iota.
> + iota = os.path.join(sbox.wc_dir, 'iota')
> + svntest.main.file_append(iota, "New contents for iota\n")
> + svntest.main.run_svn(None, 'ci',
> + '-m', '', iota)
> +
> + expected_output = [
> + " 1 jrandom This is the file 'iota'.\n",
> + " 2 jrandom New contents for iota\n",
> + ]
> +
> + orig_dir = os.getcwd()
> + os.chdir(sbox.wc_dir)
> +
> + exit_code, output, error = svntest.actions.run_and_verify_svn(None,
> + expected_output, [],
> + 'blame', '^/iota')
> +
> + os.chdir(orig_dir)
> +
> +def basic_relative_url_using_other_targets(sbox):
> + "basic relative url target using other targets"
> +
> + sbox.build()
> +
> + # First, make a new revision of iota.
> + iota = os.path.join(sbox.wc_dir, 'iota')
> + svntest.main.file_append(iota, "New contents for iota\n")
> + svntest.main.run_svn(None, 'ci',
> + '-m', '', iota)
> +
> + # Now, make a new revision of A/mu .
> + mu = os.path.join(sbox.wc_dir, 'A', 'mu')
> + mu_url = sbox.repo_url + '/A/mu'
> +
> + svntest.main.file_append(mu, "New contents for mu\n")
> + svntest.main.run_svn(None, 'ci',
> + '-m', '', mu)
> +
> +
> + expected_output = [
> + " 1 jrandom This is the file 'iota'.\n",
> + " 2 jrandom New contents for iota\n",
> + " 1 jrandom This is the file 'mu'.\n",
> + " 3 jrandom New contents for mu\n",
> + ]
> +
> + exit_code, output, error = svntest.actions.run_and_verify_svn(None,
> + expected_output, [], 'blame',
> + '^/iota', mu_url)
> +
> +def basic_relative_url_multi_repo(sbox):
> + "basic relative url target with multiple repos"
> +
> + sbox.build()
> + repo_url1 = sbox.repo_url
> + repo_dir1 = sbox.repo_dir
> + wc_dir1 = sbox.wc_dir
> +
> + repo_dir2, repo_url2 = sbox.add_repo_path("other")
> + svntest.main.copy_repos(repo_dir1, repo_dir2, 1, 1)
> + wc_dir2 = sbox.add_wc_path("other")
> + svntest.actions.run_and_verify_svn("Unexpected error during co",
> + svntest.verify.AnyOutput, [], "co",
> + repo_url2,
> + wc_dir2)
> +
> + # Don't bother with making new revisions, the command should not work.
> + iota_url_repo1 = repo_url1 + '/iota'
> + iota_url_repo2 = repo_url2 + '/iota'
> +
> + exit_code, output, error = svntest.actions.run_and_verify_svn(None, [],
> + svntest.verify.AnyOutput, 'blame',
> + '^/A/mu', iota_url_repo1, iota_url_repo2)
> +
> +
> +#----------------------------------------------------------------------
> +
> ########################################################################
> # Run the tests
>
> @@ -2208,6 +2294,9 @@ test_list = [ None,
> XFail(basic_rm_urls_multi_repos),
> automatic_conflict_resolution,
> info_nonexisting_file,
> + basic_relative_url_using_current_dir,
> + basic_relative_url_using_other_targets,
> + basic_relative_url_multi_repo,
> ]
>
> if __name__ == '__main__':
> Index: subversion/svn/merge-cmd.c
> ===================================================================
> --- subversion/svn/merge-cmd.c (revision 29840)
> +++ subversion/svn/merge-cmd.c (working copy)
> @@ -52,7 +52,7 @@ svn_cl__merge(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> /* Parse at least one, and possible two, sources. */
> if (targets->nelts >= 1)
> Index: subversion/svn/cl.h
> ===================================================================
> --- subversion/svn/cl.h (revision 29840)
> +++ subversion/svn/cl.h (working copy)
> @@ -581,6 +581,7 @@ svn_error_t *
> svn_cl__args_to_target_array_print_reserved(apr_array_header_t **targets_p,
> apr_getopt_t *os,
> apr_array_header_t *known_targets,
> + svn_client_ctx_t *ctx,
> apr_pool_t *pool);
>
> #ifdef __cplusplus
> Index: subversion/svn/propdel-cmd.c
> ===================================================================
> --- subversion/svn/propdel-cmd.c (revision 29840)
> +++ subversion/svn/propdel-cmd.c (working copy)
> @@ -58,7 +58,7 @@ svn_cl__propdel(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
>
> /* Add "." if user passed 0 file arguments */
> Index: subversion/svn/checkout-cmd.c
> ===================================================================
> --- subversion/svn/checkout-cmd.c (revision 29840)
> +++ subversion/svn/checkout-cmd.c (working copy)
> @@ -72,7 +72,7 @@ svn_cl__checkout(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> if (! targets->nelts)
> return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
> Index: subversion/svn/move-cmd.c
> ===================================================================
> --- subversion/svn/move-cmd.c (revision 29840)
> +++ subversion/svn/move-cmd.c (working copy)
> @@ -48,7 +48,7 @@ svn_cl__move(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> if (targets->nelts < 2)
> return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
> Index: subversion/svn/mkdir-cmd.c
> ===================================================================
> --- subversion/svn/mkdir-cmd.c (revision 29840)
> +++ subversion/svn/mkdir-cmd.c (working copy)
> @@ -47,7 +47,7 @@ svn_cl__mkdir(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> if (! targets->nelts)
> return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
> Index: subversion/svn/cat-cmd.c
> ===================================================================
> --- subversion/svn/cat-cmd.c (revision 29840)
> +++ subversion/svn/cat-cmd.c (working copy)
> @@ -45,7 +45,7 @@ svn_cl__cat(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> /* Cat cannot operate on an implicit '.' so a filename is required */
> if (! targets->nelts)
> Index: subversion/svn/revert-cmd.c
> ===================================================================
> --- subversion/svn/revert-cmd.c (revision 29840)
> +++ subversion/svn/revert-cmd.c (working copy)
> @@ -45,7 +45,7 @@ svn_cl__revert(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> /* Revert has no implicit dot-target `.', so don't you put that code here! */
> if (! targets->nelts)
> Index: subversion/svn/diff-cmd.c
> ===================================================================
> --- subversion/svn/diff-cmd.c (revision 29840)
> +++ subversion/svn/diff-cmd.c (working copy)
> @@ -147,6 +147,7 @@ svn_cl__diff(apr_getopt_t *os,
> apr_pool_t *pool)
> {
> svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
> + svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
> apr_array_header_t *options;
> apr_array_header_t *targets;
> apr_file_t *outfile, *errfile;
> @@ -190,7 +191,7 @@ svn_cl__diff(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> if (! opt_state->old_target && ! opt_state->new_target
> && (targets->nelts == 2)
> @@ -230,7 +231,7 @@ svn_cl__diff(apr_getopt_t *os,
> const char *));
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&tmp2, os, tmp,
> - pool));
> + ctx, pool));
> SVN_ERR(svn_opt_parse_path(&old_rev, &old_target,
> APR_ARRAY_IDX(tmp2, 0, const char *),
> pool));
> @@ -328,8 +329,7 @@ svn_cl__diff(apr_getopt_t *os,
> opt_state->changelists,
> summarize_func,
> (void *) target1,
> - ((svn_cl__cmd_baton_t *)baton)->ctx,
> - iterpool));
> + ctx, iterpool));
> else
> SVN_ERR(svn_client_diff4
> (options,
> @@ -346,8 +346,7 @@ svn_cl__diff(apr_getopt_t *os,
> outfile,
> errfile,
> opt_state->changelists,
> - ((svn_cl__cmd_baton_t *)baton)->ctx,
> - iterpool));
> + ctx, iterpool));
> }
> else
> {
> @@ -374,8 +373,7 @@ svn_cl__diff(apr_getopt_t *os,
> opt_state->changelists,
> summarize_func,
> (void *) truepath,
> - ((svn_cl__cmd_baton_t *)baton)->ctx,
> - iterpool));
> + ctx, iterpool));
> else
> SVN_ERR(svn_client_diff_peg4
> (options,
> @@ -392,8 +390,7 @@ svn_cl__diff(apr_getopt_t *os,
> outfile,
> errfile,
> opt_state->changelists,
> - ((svn_cl__cmd_baton_t *)baton)->ctx,
> - iterpool));
> + ctx, iterpool));
> }
> }
>
> Index: subversion/svn/copy-cmd.c
> ===================================================================
> --- subversion/svn/copy-cmd.c (revision 29840)
> +++ subversion/svn/copy-cmd.c (working copy)
> @@ -49,7 +49,7 @@ svn_cl__copy(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
> if (targets->nelts < 2)
> return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
>
> Index: subversion/svn/mergeinfo-cmd.c
> ===================================================================
> --- subversion/svn/mergeinfo-cmd.c (revision 29840)
> +++ subversion/svn/mergeinfo-cmd.c (working copy)
> @@ -133,7 +133,7 @@ svn_cl__mergeinfo(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> /* Add "." if user passed 0 arguments. */
> svn_opt_push_implicit_dot_target(targets, pool);
> Index: subversion/svn/list-cmd.c
> ===================================================================
> --- subversion/svn/list-cmd.c (revision 29840)
> +++ subversion/svn/list-cmd.c (working copy)
> @@ -220,7 +220,7 @@ svn_cl__list(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> /* Add "." if user passed 0 arguments */
> svn_opt_push_implicit_dot_target(targets, pool);
> Index: subversion/svn/util.c
> ===================================================================
> --- subversion/svn/util.c (revision 29840)
> +++ subversion/svn/util.c (working copy)
> @@ -1014,10 +1014,12 @@ svn_error_t *
> svn_cl__args_to_target_array_print_reserved(apr_array_header_t **targets,
> apr_getopt_t *os,
> apr_array_header_t *known_targets,
> + svn_client_ctx_t *ctx,
> apr_pool_t *pool)
> {
> - svn_error_t *error = svn_opt_args_to_target_array3(targets, os,
> - known_targets, pool);
> + svn_error_t *error = svn_client_args_to_target_array(targets, os,
> + known_targets,
> + ctx, pool);
> if (error)
> {
> if (error->apr_err == SVN_ERR_RESERVED_FILENAME_SPECIFIED)
> Index: subversion/svn/blame-cmd.c
> ===================================================================
> --- subversion/svn/blame-cmd.c (revision 29840)
> +++ subversion/svn/blame-cmd.c (working copy)
> @@ -204,7 +204,7 @@ svn_cl__blame(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> /* Blame needs a file on which to operate. */
> if (! targets->nelts)
> Index: subversion/svn/propget-cmd.c
> ===================================================================
> --- subversion/svn/propget-cmd.c (revision 29840)
> +++ subversion/svn/propget-cmd.c (working copy)
> @@ -182,7 +182,7 @@ svn_cl__propget(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> /* Add "." if user passed 0 file arguments */
> svn_opt_push_implicit_dot_target(targets, pool);
> Index: subversion/svn/changelist-cmd.c
> ===================================================================
> --- subversion/svn/changelist-cmd.c (revision 29840)
> +++ subversion/svn/changelist-cmd.c (working copy)
> @@ -60,7 +60,7 @@ svn_cl__changelist(apr_getopt_t *os,
> /* Parse the remaining arguments as paths. */
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> /* Changelist has no implicit dot-target `.', so don't you put that
> code here! */
> Index: subversion/svn/log-cmd.c
> ===================================================================
> --- subversion/svn/log-cmd.c (revision 29840)
> +++ subversion/svn/log-cmd.c (working copy)
> @@ -468,7 +468,7 @@ svn_cl__log(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> /* Add "." if user passed 0 arguments */
> svn_opt_push_implicit_dot_target(targets, pool);
> Index: subversion/svn/update-cmd.c
> ===================================================================
> --- subversion/svn/update-cmd.c (revision 29840)
> +++ subversion/svn/update-cmd.c (working copy)
> @@ -46,8 +46,9 @@ svn_cl__update(apr_getopt_t *os,
> svn_depth_t depth;
> svn_boolean_t depth_is_sticky;
>
> - SVN_ERR(svn_opt_args_to_target_array3(&targets, os,
> - opt_state->targets, pool));
> + SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> + opt_state->targets,
> + ctx, pool));
>
> /* Add "." if user passed 0 arguments */
> svn_opt_push_implicit_dot_target(targets, pool);
> Index: subversion/svn/resolved-cmd.c
> ===================================================================
> --- subversion/svn/resolved-cmd.c (revision 29840)
> +++ subversion/svn/resolved-cmd.c (working copy)
> @@ -76,7 +76,7 @@ svn_cl__resolved(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
> if (! targets->nelts)
> return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
>
> Index: subversion/svn/cleanup-cmd.c
> ===================================================================
> --- subversion/svn/cleanup-cmd.c (revision 29840)
> +++ subversion/svn/cleanup-cmd.c (working copy)
> @@ -45,7 +45,7 @@ svn_cl__cleanup(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> /* Add "." if user passed 0 arguments */
> svn_opt_push_implicit_dot_target(targets, pool);
> Index: subversion/svn/commit-cmd.c
> ===================================================================
> --- subversion/svn/commit-cmd.c (revision 29840)
> +++ subversion/svn/commit-cmd.c (working copy)
> @@ -53,7 +53,7 @@ svn_cl__commit(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> /* Add "." if user passed 0 arguments. */
> svn_opt_push_implicit_dot_target(targets, pool);
> Index: subversion/svn/add-cmd.c
> ===================================================================
> --- subversion/svn/add-cmd.c (revision 29840)
> +++ subversion/svn/add-cmd.c (working copy)
> @@ -47,7 +47,7 @@ svn_cl__add(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> if (! targets->nelts)
> return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
> Index: subversion/svn/propset-cmd.c
> ===================================================================
> --- subversion/svn/propset-cmd.c (revision 29840)
> +++ subversion/svn/propset-cmd.c (working copy)
> @@ -93,7 +93,7 @@ svn_cl__propset(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> /* Implicit "." is okay for revision properties; it just helps
> us find the right repository. */
> Index: subversion/svn/switch-cmd.c
> ===================================================================
> --- subversion/svn/switch-cmd.c (revision 29840)
> +++ subversion/svn/switch-cmd.c (working copy)
> @@ -101,7 +101,7 @@ svn_cl__switch(apr_getopt_t *os,
> switch to ("switch_url"). */
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> /* handle only-rewrite case specially */
> if (opt_state->relocate)
> Index: subversion/svn/delete-cmd.c
> ===================================================================
> --- subversion/svn/delete-cmd.c (revision 29840)
> +++ subversion/svn/delete-cmd.c (working copy)
> @@ -46,7 +46,7 @@ svn_cl__delete(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> if (! targets->nelts)
> return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
> Index: subversion/svn/import-cmd.c
> ===================================================================
> --- subversion/svn/import-cmd.c (revision 29840)
> +++ subversion/svn/import-cmd.c (working copy)
> @@ -75,7 +75,7 @@ svn_cl__import(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> if (targets->nelts < 1)
> return svn_error_create
> Index: subversion/svn/proplist-cmd.c
> ===================================================================
> --- subversion/svn/proplist-cmd.c (revision 29840)
> +++ subversion/svn/proplist-cmd.c (working copy)
> @@ -114,7 +114,7 @@ svn_cl__proplist(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> /* Add "." if user passed 0 file arguments */
> svn_opt_push_implicit_dot_target(targets, pool);
> Index: subversion/svn/export-cmd.c
> ===================================================================
> --- subversion/svn/export-cmd.c (revision 29840)
> +++ subversion/svn/export-cmd.c (working copy)
> @@ -48,7 +48,7 @@ svn_cl__export(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> /* We want exactly 1 or 2 targets for this subcommand. */
> if (targets->nelts < 1)
> Index: subversion/svn/status-cmd.c
> ===================================================================
> --- subversion/svn/status-cmd.c (revision 29840)
> +++ subversion/svn/status-cmd.c (working copy)
> @@ -218,7 +218,7 @@ svn_cl__status(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> /* Add "." if user passed 0 arguments */
> svn_opt_push_implicit_dot_target(targets, pool);
> Index: subversion/svn/propedit-cmd.c
> ===================================================================
> --- subversion/svn/propedit-cmd.c (revision 29840)
> +++ subversion/svn/propedit-cmd.c (working copy)
> @@ -68,7 +68,7 @@ svn_cl__propedit(apr_getopt_t *os,
> /* Suck up all the remaining arguments into a targets array */
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> if (opt_state->revprop) /* operate on a revprop */
> {
> Index: subversion/svn/lock-cmd.c
> ===================================================================
> --- subversion/svn/lock-cmd.c (revision 29840)
> +++ subversion/svn/lock-cmd.c (working copy)
> @@ -87,7 +87,7 @@ svn_cl__lock(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> /* We only support locking files, so '.' is not valid. */
> if (! targets->nelts)
> Index: subversion/svn/info-cmd.c
> ===================================================================
> --- subversion/svn/info-cmd.c (revision 29840)
> +++ subversion/svn/info-cmd.c (working copy)
> @@ -452,7 +452,7 @@ svn_cl__info(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> /* Add "." if user passed 0 arguments. */
> svn_opt_push_implicit_dot_target(targets, pool);
> Index: subversion/svn/unlock-cmd.c
> ===================================================================
> --- subversion/svn/unlock-cmd.c (revision 29840)
> +++ subversion/svn/unlock-cmd.c (working copy)
> @@ -46,7 +46,7 @@ svn_cl__unlock(apr_getopt_t *os,
>
> SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
> opt_state->targets,
> - pool));
> + ctx, pool));
>
> /* We don't support unlock on directories, so "." is not relevant. */
> if (! targets->nelts)
>
>
> ------------------------------------------------------------------------
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_subversion.tigris.org
> For additional commands, e-mail: dev-help_at_subversion.tigris.org
--
http://www.foad.me.uk/
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe_at_subversion.tigris.org
For additional commands, e-mail: dev-help_at_subversion.tigris.org
Received on 2008-04-22 17:22:43 CEST