You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2010/12/09 17:42:43 UTC

svn commit: r1044028 - in /subversion/trunk/subversion: libsvn_client/ svn/

Author: julianfoad
Date: Thu Dec  9 16:42:42 2010
New Revision: 1044028

URL: http://svn.apache.org/viewvc?rev=1044028&view=rev
Log:
Factor out some code that checks whether the target types are homogeneous.
Move it into two new functions, one each for command line and client API.

* subversion/svn/cl.h,
  subversion/svn/util.c
  (svn_cl__assert_homogeneous_target_type): New function.

* subversion/libsvn_client/client.h
  subversion/libsvn_client/util.c
  (svn_client__assert_homogeneous_target_type): New function.

* subversion/svn/mkdir-cmd.c,
  subversion/svn/delete-cmd.c,
  subversion/svn/lock-cmd.c,
  subversion/svn/unlock-cmd.c
  (svn_cl__mkdir, svn_cl__delete, svn_cl__lock, svn_cl__unlock):
    Replace existing logic with call to new function
    svn_cl__assert_homogeneous_target_type.

* subversion/libsvn_client/delete.c,
  subversion/libsvn_client/locking_commands.c,
  subversion/libsvn_client/add.c
  (svn_client_delete4, organize_lock_targets, svn_client_mkdir4):
    Replace existing logic with call to new function
    svn_client__assert_homogeneous_target_type.

Patch by: Noorul Islam K M <noorul{_AT_}collab.net>

Modified:
    subversion/trunk/subversion/libsvn_client/add.c
    subversion/trunk/subversion/libsvn_client/client.h
    subversion/trunk/subversion/libsvn_client/delete.c
    subversion/trunk/subversion/libsvn_client/locking_commands.c
    subversion/trunk/subversion/libsvn_client/util.c
    subversion/trunk/subversion/svn/cl.h
    subversion/trunk/subversion/svn/delete-cmd.c
    subversion/trunk/subversion/svn/lock-cmd.c
    subversion/trunk/subversion/svn/mkdir-cmd.c
    subversion/trunk/subversion/svn/unlock-cmd.c
    subversion/trunk/subversion/svn/util.c

Modified: subversion/trunk/subversion/libsvn_client/add.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/add.c?rev=1044028&r1=1044027&r2=1044028&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/add.c (original)
+++ subversion/trunk/subversion/libsvn_client/add.c Thu Dec  9 16:42:42 2010
@@ -865,27 +865,10 @@ svn_client_mkdir4(const apr_array_header
                   svn_client_ctx_t *ctx,
                   apr_pool_t *pool)
 {
-  svn_boolean_t wc_present = FALSE, url_present = FALSE;
-  int i;
-
   if (! paths->nelts)
     return SVN_NO_ERROR;
 
-  /* Check to see if at least one of our paths is a working copy
-     path or a repository url. */
-  for (i = 0; i < paths->nelts; ++i)
-    {
-      const char *path = APR_ARRAY_IDX(paths, i, const char *);
-      if (! svn_path_is_url(path))
-       wc_present = TRUE;
-      else
-       url_present = TRUE;
-    }
-
-  if (url_present && wc_present)
-    return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
-                             _("Cannot mix repository and working copy "
-                               "targets"));
+  SVN_ERR(svn_client__assert_homogeneous_target_type(paths));
 
   if (svn_path_is_url(APR_ARRAY_IDX(paths, 0, const char *)))
     {
@@ -896,6 +879,7 @@ svn_client_mkdir4(const apr_array_header
     {
       /* This is a regular "mkdir" + "svn add" */
       apr_pool_t *subpool = svn_pool_create(pool);
+      int i;
 
       for (i = 0; i < paths->nelts; i++)
         {

Modified: subversion/trunk/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/client.h?rev=1044028&r1=1044027&r2=1044028&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/client.h (original)
+++ subversion/trunk/subversion/libsvn_client/client.h Thu Dec  9 16:42:42 2010
@@ -1107,8 +1107,10 @@ const svn_opt_revision_t *
 svn_cl__rev_default_to_peg(const svn_opt_revision_t *revision,
                            const svn_opt_revision_t *peg_revision);
 
-
-
+/* Return an error if TARGETS contains a mixture of URLs and paths; otherwise
+ * return SVN_NO_ERROR. */
+svn_error_t *
+svn_client__assert_homogeneous_target_type(const apr_array_header_t *targets);
 
 #ifdef __cplusplus
 }

Modified: subversion/trunk/subversion/libsvn_client/delete.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/delete.c?rev=1044028&r1=1044027&r2=1044028&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/delete.c (original)
+++ subversion/trunk/subversion/libsvn_client/delete.c Thu Dec  9 16:42:42 2010
@@ -328,17 +328,8 @@ svn_client_delete4(const apr_array_heade
   if (! paths->nelts)
     return SVN_NO_ERROR;
 
-  /* Check that all targets are of the same type. */
+  SVN_ERR(svn_client__assert_homogeneous_target_type(paths));
   is_url = svn_path_is_url(APR_ARRAY_IDX(paths, 0, const char *));
-  for (i = 1; i < paths->nelts; i++)
-    {
-      const char *path = APR_ARRAY_IDX(paths, i, const char *);
-      if (is_url != svn_path_is_url(path))
-        return svn_error_return(
-                 svn_error_create(SVN_ERR_ILLEGAL_TARGET, NULL,
-                                  _("Cannot mix repository and working copy "
-                                    "targets")));
-    }
 
   if (is_url)
     {

Modified: subversion/trunk/subversion/libsvn_client/locking_commands.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/locking_commands.c?rev=1044028&r1=1044027&r2=1044028&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/locking_commands.c (original)
+++ subversion/trunk/subversion/libsvn_client/locking_commands.c Thu Dec  9 16:42:42 2010
@@ -182,25 +182,8 @@ organize_lock_targets(const char **commo
   apr_hash_t *rel_targets_ret = apr_hash_make(pool);
   apr_pool_t *subpool = svn_pool_create(pool);
   svn_boolean_t url_mode;
-  svn_boolean_t wc_present = FALSE, url_present = FALSE;
 
-  /* Check to see if at least one of our paths is a working copy
-   * path or a repository url. */
-  for (i = 0; i < targets->nelts; ++i)
-    {
-      const char *target = APR_ARRAY_IDX(targets, i, const char *);
-      if (! svn_path_is_url(target))
-       wc_present = TRUE;
-      else
-       url_present = TRUE;
-    }
-
-  if (url_present && wc_present)
-    return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
-                             _("Cannot mix repository and working copy "
-                               "targets"));
-
-  /* All targets must be either urls or paths */
+  SVN_ERR(svn_client__assert_homogeneous_target_type(targets));
 
   url_mode = ((targets->nelts >= 1) &&
               svn_path_is_url(APR_ARRAY_IDX(targets, 0, const char *)));

Modified: subversion/trunk/subversion/libsvn_client/util.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/util.c?rev=1044028&r1=1044027&r2=1044028&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/util.c (original)
+++ subversion/trunk/subversion/libsvn_client/util.c Thu Dec  9 16:42:42 2010
@@ -320,3 +320,26 @@ svn_cl__rev_default_to_peg(const svn_opt
     return peg_revision;
   return revision;
 }
+
+svn_error_t *
+svn_client__assert_homogeneous_target_type(const apr_array_header_t *targets)
+{
+  svn_boolean_t wc_present = FALSE, url_present = FALSE;
+  int i;
+
+  for (i = 0; i < targets->nelts; ++i)
+    {
+      const char *target = APR_ARRAY_IDX(targets, i, const char *);
+      if (! svn_path_is_url(target))
+        wc_present = TRUE;
+      else
+        url_present = TRUE;
+    }
+
+  if (url_present && wc_present)
+    return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+                             _("Cannot mix repository and working copy "
+                               "targets"));
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/trunk/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl.h?rev=1044028&r1=1044027&r2=1044028&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/cl.h (original)
+++ subversion/trunk/subversion/svn/cl.h Thu Dec  9 16:42:42 2010
@@ -817,6 +817,11 @@ svn_cl__opt_parse_path(svn_opt_revision_
                        const char *path,
                        apr_pool_t *pool);
 
+/* Return an error if TARGETS contains a mixture of URLs and paths; otherwise
+ * return SVN_NO_ERROR. */
+svn_error_t *
+svn_cl__assert_homogeneous_target_type(const apr_array_header_t *targets);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/trunk/subversion/svn/delete-cmd.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/delete-cmd.c?rev=1044028&r1=1044027&r2=1044028&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/delete-cmd.c (original)
+++ subversion/trunk/subversion/svn/delete-cmd.c Thu Dec  9 16:42:42 2010
@@ -48,7 +48,6 @@ svn_cl__delete(apr_getopt_t *os,
   apr_array_header_t *targets;
   svn_error_t *err;
   svn_boolean_t is_url;
-  int i;
 
   SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                       opt_state->targets,
@@ -57,17 +56,8 @@ svn_cl__delete(apr_getopt_t *os,
   if (! targets->nelts)
     return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
 
-  /* Check that all targets are of the same type. */
+  SVN_ERR(svn_cl__assert_homogeneous_target_type(targets));
   is_url = svn_path_is_url(APR_ARRAY_IDX(targets, 0, const char *));
-  for (i = 1; i < targets->nelts; i++)
-    {
-      const char *target = APR_ARRAY_IDX(targets, i, const char *);
-      if (is_url != svn_path_is_url(target))
-        return svn_error_return(
-                 svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                  _("Cannot mix repository and working copy "
-                                    "targets")));
-    }
 
   if (! is_url)
     {

Modified: subversion/trunk/subversion/svn/lock-cmd.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/lock-cmd.c?rev=1044028&r1=1044027&r2=1044028&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/lock-cmd.c (original)
+++ subversion/trunk/subversion/svn/lock-cmd.c Thu Dec  9 16:42:42 2010
@@ -89,8 +89,6 @@ svn_cl__lock(apr_getopt_t *os,
   svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
   apr_array_header_t *targets;
   const char *comment;
-  svn_boolean_t wc_present = FALSE, url_present = FALSE;
-  int i;
 
   SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                       opt_state->targets,
@@ -100,21 +98,7 @@ svn_cl__lock(apr_getopt_t *os,
   if (! targets->nelts)
     return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
 
-  /* Check to see if at least one of our paths is a working copy
-   * path or a repository url. */
-  for (i = 0; i < targets->nelts; ++i)
-    {
-      const char *target = APR_ARRAY_IDX(targets, i, const char *);
-      if (! svn_path_is_url(target))
-       wc_present = TRUE;
-      else
-       url_present = TRUE;
-    }
-
-  if (url_present && wc_present)
-    return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                        _("Cannot mix repository and working copy "
-                          "targets"));
+  SVN_ERR(svn_cl__assert_homogeneous_target_type(targets));
 
   /* Get comment. */
   SVN_ERR(get_comment(&comment, ctx, opt_state, pool));

Modified: subversion/trunk/subversion/svn/mkdir-cmd.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/mkdir-cmd.c?rev=1044028&r1=1044027&r2=1044028&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/mkdir-cmd.c (original)
+++ subversion/trunk/subversion/svn/mkdir-cmd.c Thu Dec  9 16:42:42 2010
@@ -48,8 +48,6 @@ svn_cl__mkdir(apr_getopt_t *os,
   svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
   apr_array_header_t *targets;
   svn_error_t *err;
-  svn_boolean_t wc_present = FALSE, url_present = FALSE;
-  int i;
 
   SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                       opt_state->targets,
@@ -58,21 +56,7 @@ svn_cl__mkdir(apr_getopt_t *os,
   if (! targets->nelts)
     return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
 
-  /* Check to see if at least one of our paths is a working copy
-     path or a repository url. */
-  for (i = 0; i < targets->nelts; ++i)
-    {
-      const char *target = APR_ARRAY_IDX(targets, i, const char *);
-      if (! svn_path_is_url(target))
-        wc_present = TRUE;
-      else
-        url_present = TRUE;
-    }
-
-  if (url_present && wc_present)
-    return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                        _("Cannot mix repository and working copy "
-                          "targets"));
+  SVN_ERR(svn_cl__assert_homogeneous_target_type(targets));
 
   if (! svn_path_is_url(APR_ARRAY_IDX(targets, 0, const char *)))
     {

Modified: subversion/trunk/subversion/svn/unlock-cmd.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/unlock-cmd.c?rev=1044028&r1=1044027&r2=1044028&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/unlock-cmd.c (original)
+++ subversion/trunk/subversion/svn/unlock-cmd.c Thu Dec  9 16:42:42 2010
@@ -49,8 +49,6 @@ svn_cl__unlock(apr_getopt_t *os,
   svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
   svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
   apr_array_header_t *targets;
-  svn_boolean_t wc_present = FALSE, url_present = FALSE;
-  int i;
 
   SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                       opt_state->targets,
@@ -62,22 +60,7 @@ svn_cl__unlock(apr_getopt_t *os,
 
   SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, scratch_pool));
 
-  /* Check to see if at least one of our paths is a working copy
-   * path or a repository url. */
-  for (i = 0; i < targets->nelts; ++i)
-    {
-      const char *target = APR_ARRAY_IDX(targets, i, const char *);
-
-      if (! svn_path_is_url(target))
-        wc_present = TRUE;
-      else
-        url_present = TRUE;
-    }
-
-  if (url_present && wc_present)
-    return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                             _("Cannot mix repository and working copy "
-                               "targets"));
+  SVN_ERR(svn_cl__assert_homogeneous_target_type(targets));
 
   return svn_error_return(
     svn_client_unlock(targets, opt_state->force, ctx, scratch_pool));

Modified: subversion/trunk/subversion/svn/util.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/util.c?rev=1044028&r1=1044027&r2=1044028&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/util.c (original)
+++ subversion/trunk/subversion/svn/util.c Thu Dec  9 16:42:42 2010
@@ -1345,3 +1345,26 @@ svn_cl__opt_parse_path(svn_opt_revision_
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_cl__assert_homogeneous_target_type(const apr_array_header_t *targets)
+{
+  svn_boolean_t wc_present = FALSE, url_present = FALSE;
+  int i;
+
+  for (i = 0; i < targets->nelts; ++i)
+    {
+      const char *target = APR_ARRAY_IDX(targets, i, const char *);
+      if (! svn_path_is_url(target))
+        wc_present = TRUE;
+      else
+        url_present = TRUE;
+    }
+
+  if (url_present && wc_present)
+    return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                             _("Cannot mix repository and working copy "
+                               "targets"));
+
+  return SVN_NO_ERROR;
+}



Re: svn commit: r1044028 - in /subversion/trunk/subversion: libsvn_client/ svn/

Posted by Branko Čibej <br...@xbc.nu>.
On 10.12.2010 20:31, Noorul Islam K M wrote:
> Daniel Shahaf <d....@daniel.shahaf.name> writes:
>
>> I don't really mind having the input checks both at the client library
>> and in the cmdline client --- though, of course, having them just in the
>> former should be sufficient --- but this time it's straight code
>> duplication:
>>
> Even though both the message are same, the error type is different. In
> command line we use SVN_ERR_CL_ARG_PARSING_ERROR and in client API 
> SVN_ERR_ILLEGAL_TARGET. The reason to check both at command line and
> client API is that, this will protect users who directly use API calls. 
>
> Thanks and Regards
> Noorul

That code should be only in libsvn_client, IMHO. If the client wants to
wrap the generic error with its own specific one, it can; but there's no
need for the code to be in more than one place.

-- Brane

Re: svn commit: r1044028 - in /subversion/trunk/subversion: libsvn_client/ svn/

Posted by Julian Foad <ju...@wandisco.com>.
On Fri, 2010-12-10, C. Michael Pilato wrote:
> On 12/10/2010 02:31 PM, Noorul Islam K M wrote:
> > Daniel Shahaf <d....@daniel.shahaf.name> writes:
> > 
> >> I don't really mind having the input checks both at the client library
> >> and in the cmdline client --- though, of course, having them just in the
> >> former should be sufficient --- but this time it's straight code
> >> duplication:

FWIW, my thought on committing this was that it's less duplication than
what was there before.

> > Even though both the message are same, the error type is different. In
> > command line we use SVN_ERR_CL_ARG_PARSING_ERROR and in client API 
> > SVN_ERR_ILLEGAL_TARGET. The reason to check both at command line and
> > client API is that, this will protect users who directly use API calls. 
> 
> r1044486 should address the duplication while preserving the distinct error
> codes.

Thanks, Mike, for completing the de-duplification.

- Julian


Re: svn commit: r1044028 - in /subversion/trunk/subversion: libsvn_client/ svn/

Posted by "C. Michael Pilato" <cm...@collab.net>.
On 12/10/2010 02:31 PM, Noorul Islam K M wrote:
> Daniel Shahaf <d....@daniel.shahaf.name> writes:
> 
>> I don't really mind having the input checks both at the client library
>> and in the cmdline client --- though, of course, having them just in the
>> former should be sufficient --- but this time it's straight code
>> duplication:
>>
> 
> Even though both the message are same, the error type is different. In
> command line we use SVN_ERR_CL_ARG_PARSING_ERROR and in client API 
> SVN_ERR_ILLEGAL_TARGET. The reason to check both at command line and
> client API is that, this will protect users who directly use API calls. 

r1044486 should address the duplication while preserving the distinct error
codes.

-- 
C. Michael Pilato <cm...@collab.net>
CollabNet   <>   www.collab.net   <>   Distributed Development On Demand


Re: svn commit: r1044028 - in /subversion/trunk/subversion: libsvn_client/ svn/

Posted by Noorul Islam K M <no...@collab.net>.
Daniel Shahaf <d....@daniel.shahaf.name> writes:

> I don't really mind having the input checks both at the client library
> and in the cmdline client --- though, of course, having them just in the
> former should be sufficient --- but this time it's straight code
> duplication:
>

Even though both the message are same, the error type is different. In
command line we use SVN_ERR_CL_ARG_PARSING_ERROR and in client API 
SVN_ERR_ILLEGAL_TARGET. The reason to check both at command line and
client API is that, this will protect users who directly use API calls. 

Thanks and Regards
Noorul

Re: svn commit: r1044028 - in /subversion/trunk/subversion: libsvn_client/ svn/

Posted by "C. Michael Pilato" <cm...@collab.net>.
On 12/10/2010 01:51 PM, Daniel Shahaf wrote:
> I don't really mind having the input checks both at the client library
> and in the cmdline client --- though, of course, having them just in the
> former should be sufficient --- but this time it's straight code
> duplication:

I'm on this.

-- 
C. Michael Pilato <cm...@collab.net>
CollabNet   <>   www.collab.net   <>   Distributed Development On Demand


Re: svn commit: r1044028 - in /subversion/trunk/subversion: libsvn_client/ svn/

Posted by Daniel Shahaf <d....@daniel.shahaf.name>.
I don't really mind having the input checks both at the client library
and in the cmdline client --- though, of course, having them just in the
former should be sufficient --- but this time it's straight code
duplication:

julianfoad@apache.org wrote on Thu, Dec 09, 2010 at 16:42:43 -0000:
> Author: julianfoad
> Date: Thu Dec  9 16:42:42 2010
> New Revision: 1044028
> 
> URL: http://svn.apache.org/viewvc?rev=1044028&view=rev
> Log:
> Factor out some code that checks whether the target types are homogeneous.
> Move it into two new functions, one each for command line and client API.
> 

Exhibit A:

> Modified: subversion/trunk/subversion/libsvn_client/util.c
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/util.c?rev=1044028&r1=1044027&r2=1044028&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/libsvn_client/util.c (original)
> +++ subversion/trunk/subversion/libsvn_client/util.c Thu Dec  9 16:42:42 2010
> @@ -320,3 +320,26 @@ svn_cl__rev_default_to_peg(const svn_opt
>      return peg_revision;
>    return revision;
>  }
> +
> +svn_error_t *
> +svn_client__assert_homogeneous_target_type(const apr_array_header_t *targets)
> +{
> +  svn_boolean_t wc_present = FALSE, url_present = FALSE;
> +  int i;
> +
> +  for (i = 0; i < targets->nelts; ++i)
> +    {
> +      const char *target = APR_ARRAY_IDX(targets, i, const char *);
> +      if (! svn_path_is_url(target))
> +        wc_present = TRUE;
> +      else
> +        url_present = TRUE;
> +    }
> +
> +  if (url_present && wc_present)
> +    return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
> +                             _("Cannot mix repository and working copy "
> +                               "targets"));
> +
> +  return SVN_NO_ERROR;
> +}
> 

Exhibit B:

> Modified: subversion/trunk/subversion/svn/util.c
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/util.c?rev=1044028&r1=1044027&r2=1044028&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/svn/util.c (original)
> +++ subversion/trunk/subversion/svn/util.c Thu Dec  9 16:42:42 2010
> @@ -1345,3 +1345,26 @@ svn_cl__opt_parse_path(svn_opt_revision_
>  
>    return SVN_NO_ERROR;
>  }
> +
> +svn_error_t *
> +svn_cl__assert_homogeneous_target_type(const apr_array_header_t *targets)
> +{
> +  svn_boolean_t wc_present = FALSE, url_present = FALSE;
> +  int i;
> +
> +  for (i = 0; i < targets->nelts; ++i)
> +    {
> +      const char *target = APR_ARRAY_IDX(targets, i, const char *);
> +      if (! svn_path_is_url(target))
> +        wc_present = TRUE;
> +      else
> +        url_present = TRUE;
> +    }
> +
> +  if (url_present && wc_present)
> +    return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
> +                             _("Cannot mix repository and working copy "
> +                               "targets"));
> +
> +  return SVN_NO_ERROR;
> +}
> 
> 

I see no good reason for this duplication, and it should be easy to
eliminate it.

Daniel