It's possible to compare branches in the repository using
$ svn diff ^/repo/branches/foo ^/repo/branches/bar
but that only works if the current directory is a working copy because
libsvn_client/cmdline.c:svn_client_args_to_target_array converts
relative URLs to full URLs using the hardcoded path "". Since I
regularly have my current working directory outside a working copy
this is inconvenient.
I'd like to be able to do
$ svn diff ^/repo/branches/foo ^/repo/branches/bar path/to/wc
and it turns out to be quite simple from a code point of view. It is,
of course, an extension to our rather complex diff UI. What do people
think?
Add 'svn diff URL URL [WC]' as an extension to 'svn diff URL URL'.
* subversion/svn/diff-cmd.c:
(svn_cl_diff): Recognise 'svn diff URL URL [WC]'.
* subversion/svn/main.c
(svn_cl__cmd_table): Extend diff help text.
* subversion/include/svn_client.h
(svn_client_args_to_target_array): Tweak doc string.
* subversion/libsvn_client/cmdline.c
(svn_client_args_to_target_array): Convert relative urls using the first
path given and only use "" if there are no paths.
Index: subversion/svn/diff-cmd.c
===================================================================
--- subversion/svn/diff-cmd.c (revision 886136)
+++ subversion/svn/diff-cmd.c (working copy)
@@ -196,13 +196,20 @@
ctx, pool));
if (! opt_state->old_target && ! opt_state->new_target
- && (targets->nelts == 2)
- && svn_path_is_url(APR_ARRAY_IDX(targets, 0, const char *))
- && svn_path_is_url(APR_ARRAY_IDX(targets, 1, const char *))
+ && ((targets->nelts == 2
+ && svn_path_is_url(APR_ARRAY_IDX(targets, 0, const char *))
+ && svn_path_is_url(APR_ARRAY_IDX(targets, 1, const char *)))
+ ||
+ (targets->nelts == 3
+ && svn_path_is_url(APR_ARRAY_IDX(targets, 0, const char *))
+ && svn_path_is_url(APR_ARRAY_IDX(targets, 1, const char *))
+ && !svn_path_is_url(APR_ARRAY_IDX(targets, 2, const char *))))
&& opt_state->start_revision.kind == svn_opt_revision_unspecified
&& opt_state->end_revision.kind == svn_opt_revision_unspecified)
{
- /* The 'svn diff OLD_URL[@OLDREV] NEW_URL[@NEWREV]' case matches. */
+ /* Either 'svn diff OLD_URL[@OLDREV] NEW_URL[@NEWREV]'
+ or 'svn diff OLD_URL[@OLDREV] NEW_URL[@NEWREV] wc'
+ matches. */
SVN_ERR(svn_opt_parse_path(&opt_state->start_revision, &old_target,
APR_ARRAY_IDX(targets, 0, const char *),
@@ -222,8 +229,8 @@
apr_array_header_t *tmp, *tmp2;
svn_opt_revision_t old_rev, new_rev;
- /* The 'svn diff --old=OLD[@OLDREV] [--new=NEW[@NEWREV]]
- [PATH...]' case matches. */
+ /* The 'svn diff --old=OLD[@OLDREV] [--new=NEW[@NEWREV]] [PATH...]'
+ case matches. */
tmp = apr_array_make(pool, 2, sizeof(const char *));
APR_ARRAY_PUSH(tmp, const char *) = (opt_state->old_target);
Index: subversion/svn/main.c
===================================================================
--- subversion/svn/main.c (revision 886136)
+++ subversion/svn/main.c (working copy)
@@ -473,7 +473,7 @@
"usage: 1. diff [-c M | -r N[:M]] [TARGET[@REV]...]\n"
" 2. diff [-r N[:M]] --old=OLD-TGT[@OLDREV] [--new=NEW-TGT[@NEWREV]] \\\n"
" [PATH...]\n"
- " 3. diff OLD-URL[@OLDREV] NEW-URL[@NEWREV]\n"
+ " 3. diff OLD-URL[@OLDREV] NEW-URL[@NEWREV] [PATH]\n"
"\n"
" 1. Display the changes made to TARGETs as they are seen in REV between\n"
" two revisions. TARGETs may be all working copy paths or all URLs.\n"
@@ -490,6 +490,8 @@
" to N, -r N:M makes OLDREV default to N and NEWREV default to M.\n"
"\n"
" 3. Shorthand for 'svn diff --old=OLD-URL[@OLDREV] --new=NEW-URL[@NEWREV]'\n"
+ " Relative URLs are converted to full URLs using either PATH, if given,\n"
+ " or the current directory.\n"
"\n"
" Use just 'svn diff' to display local modifications in a working copy.\n"),
{'r', 'c', opt_old_cmd, opt_new_cmd, 'N', opt_depth, opt_diff_cmd, 'x',
Index: subversion/include/svn_client.h
===================================================================
--- subversion/include/svn_client.h (revision 886136)
+++ subversion/include/svn_client.h (working copy)
@@ -994,6 +994,8 @@
* (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.
+ * Relative URLs are converted to full URLs using the first non-URL path,
+ * or the current directory if only URLs are supplied.
* On each local path, canonicalize case and path separators.
*
* Allocate @a *targets_p and its elements in @a pool.
Index: subversion/libsvn_client/cmdline.c
===================================================================
--- subversion/libsvn_client/cmdline.c (revision 886136)
+++ subversion/libsvn_client/cmdline.c (working copy)
@@ -281,7 +281,21 @@
* arguments.
*/
if (root_url == NULL)
- SVN_ERR(svn_client_root_url_from_path(&root_url, "", ctx, pool));
+ {
+ const char *path_for_root_url = "";
+ 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))
+ {
+ path_for_root_url = target;
+ break;
+ }
+ }
+ SVN_ERR(svn_client_root_url_from_path(&root_url, path_for_root_url,
+ ctx, pool));
+ }
*targets_p = apr_array_make(pool, output_targets->nelts,
sizeof(const char *));
--
Philip
------------------------------------------------------
http://subversion.tigris.org/ds/viewMessage.do?dsForumId=462&dsMessageId=2426641
Please start new threads on the <dev_at_subversion.apache.org> mailing list.
To subscribe to the new list, send an empty e-mail to <dev-subscribe_at_subversion.apache.org>.
Received on 2009-12-03 12:01:12 CET