You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/08/11 00:07:31 UTC

svn commit: r984234 [17/20] - in /subversion/branches/ignore-mergeinfo: ./ build/ build/ac-macros/ build/generator/ notes/ notes/api-errata/ notes/obliterate/ notes/obliterate/fspec-cc1/ notes/rename-tracking/ notes/svnpatch/ notes/tree-conflicts/ note...

Modified: subversion/branches/ignore-mergeinfo/subversion/svn/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/svn/status.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/svn/status.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/svn/status.c Tue Aug 10 22:07:24 2010
@@ -60,10 +60,31 @@ generate_status_code(enum svn_wc_status_
     }
 }
 
+/* Return the combined STATUS as shown in 'svn status' based
+   on the node status and text status */
+static enum svn_wc_status_kind
+combined_status(const svn_client_status_t *status)
+{
+  enum svn_wc_status_kind new_status = status->node_status;
+
+  switch (status->node_status)
+    {
+      case svn_wc_status_modified:
+      case svn_wc_status_conflicted:
+        /* This value might be the property status */
+        new_status = status->text_status;
+        break;
+      default:
+        break;
+    }
+
+  return new_status;
+}
+
 /* Return the single character representation of the switched column
    status. */
 static char
-generate_switch_column_code(const svn_wc_status3_t *status)
+generate_switch_column_code(const svn_client_status_t *status)
 {
   if (status->switched)
     return 'S';
@@ -105,17 +126,21 @@ print_status(const char *path,
              svn_boolean_t detailed,
              svn_boolean_t show_last_committed,
              svn_boolean_t repos_locks,
-             const svn_wc_status3_t *status,
+             const svn_client_status_t *status,
              unsigned int *text_conflicts,
              unsigned int *prop_conflicts,
              unsigned int *tree_conflicts,
              svn_client_ctx_t *ctx,
              apr_pool_t *pool)
 {
-  enum svn_wc_status_kind text_status = status->text_status;
+  enum svn_wc_status_kind node_status = status->node_status;
+  enum svn_wc_status_kind prop_status = status->prop_status;
   char tree_status_code = ' ';
   const char *tree_desc_line = "";
 
+  if (node_status == svn_wc_status_added)
+      prop_status = svn_wc_status_none;
+
   /* To indicate this node is the victim of a tree conflict, we show
      'C' in the tree-conflict column, overriding any other status.
      We also print a separate line describing the nature of the tree
@@ -123,13 +148,11 @@ print_status(const char *path,
   if (status->conflicted)
     {
       const char *desc;
-      const char *local_abspath;
+      const char *local_abspath = status->local_abspath;
       svn_boolean_t text_conflicted;
       svn_boolean_t prop_conflicted;
       svn_boolean_t tree_conflicted;
 
-      SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
-
       SVN_ERR(svn_wc__node_check_conflicts(&prop_conflicted,
                                            &text_conflicted,
                                            &tree_conflicted, ctx->wc_ctx,
@@ -166,25 +189,22 @@ print_status(const char *path,
          ### revision=0.  This is wrong, and we're trying to remedy that,
          ### but for the sake of test suite and code sanity now in WC-NG,
          ### we'll just maintain the old behavior. */
-      if (! status->entry)
+      if (! status->versioned)
         working_rev = "";
+      else if (status->copied)
+        working_rev = "-";
       else if (! SVN_IS_VALID_REVNUM(status->revision))
         {
-          if (status->copied)
-            working_rev = "-";
-          else if (text_status == svn_wc_status_added
-              || text_status == svn_wc_status_replaced)
+          if (node_status == svn_wc_status_added ||
+              node_status == svn_wc_status_replaced)
             working_rev = "0";
           else
             working_rev = " ? ";
         }
-      else if (status->copied)
-        working_rev = "-";
       else
         working_rev = apr_psprintf(pool, "%ld", status->revision);
 
-      if (status->repos_text_status != svn_wc_status_none
-          || status->repos_prop_status != svn_wc_status_none)
+      if (status->repos_node_status != svn_wc_status_none)
         ood_status = '*';
       else
         ood_status = ' ';
@@ -193,9 +213,9 @@ print_status(const char *path,
         {
           if (status->repos_lock)
             {
-              if (status->lock_token)
+              if (status->lock)
                 {
-                  if (strcmp(status->repos_lock->token, status->lock_token)
+                  if (strcmp(status->repos_lock->token, status->lock->token)
                       == 0)
                     lock_status = 'K';
                   else
@@ -204,13 +224,13 @@ print_status(const char *path,
               else
                 lock_status = 'O';
             }
-          else if (status->lock_token)
+          else if (status->lock)
             lock_status = 'B';
           else
             lock_status = ' ';
         }
       else
-        lock_status = (status->lock_token) ? 'K' : ' ';
+        lock_status = (status->lock) ? 'K' : ' ';
 
       if (show_last_committed)
         {
@@ -219,14 +239,14 @@ print_status(const char *path,
 
           if (SVN_IS_VALID_REVNUM(status->changed_rev))
             commit_rev = apr_psprintf(pool, "%ld", status->changed_rev);
-          else if (status->entry)
+          else if (status->versioned)
             commit_rev = " ? ";
           else
             commit_rev = "";
 
           if (status->changed_author)
             commit_author = status->changed_author;
-          else if (status->entry)
+          else if (status->versioned)
             commit_author = " ? ";
           else
             commit_author = "";
@@ -234,8 +254,8 @@ print_status(const char *path,
           SVN_ERR
             (svn_cmdline_printf(pool,
                                 "%c%c%c%c%c%c%c %c   %6s   %6s %-12s %s%s\n",
-                                generate_status_code(text_status),
-                                generate_status_code(status->prop_status),
+                                generate_status_code(combined_status(status)),
+                                generate_status_code(prop_status),
                                 status->locked ? 'L' : ' ',
                                 status->copied ? '+' : ' ',
                                 generate_switch_column_code(status),
@@ -249,10 +269,10 @@ print_status(const char *path,
                                 tree_desc_line));
         }
       else
-        SVN_ERR
-          (svn_cmdline_printf(pool, "%c%c%c%c%c%c%c %c   %6s   %s%s\n",
-                              generate_status_code(text_status),
-                              generate_status_code(status->prop_status),
+        SVN_ERR(
+           svn_cmdline_printf(pool, "%c%c%c%c%c%c%c %c   %6s   %s%s\n",
+                              generate_status_code(combined_status(status)),
+                              generate_status_code(prop_status),
                               status->locked ? 'L' : ' ',
                               status->copied ? '+' : ' ',
                               generate_switch_column_code(status),
@@ -264,14 +284,14 @@ print_status(const char *path,
                               tree_desc_line));
     }
   else
-    SVN_ERR
-      (svn_cmdline_printf(pool, "%c%c%c%c%c%c%c %s%s\n",
-                          generate_status_code(text_status),
-                          generate_status_code(status->prop_status),
+    SVN_ERR(
+       svn_cmdline_printf(pool, "%c%c%c%c%c%c%c %s%s\n",
+                          generate_status_code(combined_status(status)),
+                          generate_status_code(prop_status),
                           status->locked ? 'L' : ' ',
                           status->copied ? '+' : ' ',
                           generate_switch_column_code(status),
-                          ((status->lock_token)
+                          ((status->lock)
                            ? 'K' : ' '),
                           tree_status_code,
                           path,
@@ -283,32 +303,35 @@ print_status(const char *path,
 
 svn_error_t *
 svn_cl__print_status_xml(const char *path,
-                         const svn_wc_status3_t *status,
+                         const svn_client_status_t *status,
                          svn_client_ctx_t *ctx,
                          apr_pool_t *pool)
 {
   svn_stringbuf_t *sb = svn_stringbuf_create("", pool);
   apr_hash_t *att_hash;
-  const char *local_abspath;
-  svn_boolean_t tree_conflicted;
+  const char *local_abspath = status->local_abspath;
+  svn_boolean_t tree_conflicted = FALSE;
 
-  if (status->text_status == svn_wc_status_none
-      && status->repos_text_status == svn_wc_status_none)
+  if (status->node_status == svn_wc_status_none)
     return SVN_NO_ERROR;
 
-  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
-  SVN_ERR(svn_wc__node_check_conflicts(NULL, NULL, &tree_conflicted,
-                                       ctx->wc_ctx, local_abspath, pool,
-                                       pool));
+  if (status->conflicted)
+    SVN_ERR(svn_wc__node_check_conflicts(NULL, NULL, &tree_conflicted,
+                                         ctx->wc_ctx, local_abspath, pool,
+                                         pool));
 
   svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "entry",
                         "path", svn_dirent_local_style(path, pool), NULL);
 
   att_hash = apr_hash_make(pool);
   apr_hash_set(att_hash, "item", APR_HASH_KEY_STRING,
-               generate_status_desc(status->text_status));
+               generate_status_desc(combined_status(status)));
+
   apr_hash_set(att_hash, "props", APR_HASH_KEY_STRING,
-               generate_status_desc(status->prop_status));
+               generate_status_desc(
+                     (status->node_status != svn_wc_status_deleted)
+                                          ? status->prop_status
+                                          : svn_wc_status_none));
   if (status->locked)
     apr_hash_set(att_hash, "wc-locked", APR_HASH_KEY_STRING, "true");
   if (status->copied)
@@ -317,7 +340,7 @@ svn_cl__print_status_xml(const char *pat
     apr_hash_set(att_hash, "switched", APR_HASH_KEY_STRING, "true");
   if (status->file_external)
     apr_hash_set(att_hash, "file-external", APR_HASH_KEY_STRING, "true");
-  if (status->entry && ! status->entry->copied)
+  if (status->versioned && ! status->copied)
     apr_hash_set(att_hash, "revision", APR_HASH_KEY_STRING,
                  apr_psprintf(pool, "%ld", status->revision));
   if (tree_conflicted)
@@ -330,40 +353,39 @@ svn_cl__print_status_xml(const char *pat
     {
       svn_cl__print_xml_commit(&sb, status->changed_rev,
                                status->changed_author,
-                               svn_time_to_cstring(status->entry->cmt_date,
+                               svn_time_to_cstring(status->changed_date,
                                                    pool),
                                pool);
     }
 
-  if (status->lock_token)
+  if (status->lock)
     {
       svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "lock", NULL);
 
-      svn_cl__xml_tagged_cdata(&sb, pool, "token", status->lock_token);
+      svn_cl__xml_tagged_cdata(&sb, pool, "token", status->lock->token);
 
       /* If lock_owner is NULL, assume WC is corrupt. */
-      if (status->lock_owner)
+      if (status->lock->owner)
         svn_cl__xml_tagged_cdata(&sb, pool, "owner",
-                                 status->lock_owner);
+                                 status->lock->owner);
       else
         return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
                                  _("'%s' has lock token, but no lock owner"),
                                  svn_dirent_local_style(path, pool));
 
       svn_cl__xml_tagged_cdata(&sb, pool, "comment",
-                               status->lock_comment);
+                               status->lock->comment);
 
       svn_cl__xml_tagged_cdata(&sb, pool, "created",
                                svn_time_to_cstring
-                               (status->lock_creation_date, pool));
+                               (status->lock->creation_date, pool));
 
       svn_xml_make_close_tag(&sb, pool, "lock");
     }
 
   svn_xml_make_close_tag(&sb, pool, "wc-status");
 
-  if (status->repos_text_status != svn_wc_status_none
-      || status->repos_prop_status != svn_wc_status_none
+  if (status->repos_node_status != svn_wc_status_none
       || status->repos_lock)
     {
       svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "repos-status",
@@ -411,7 +433,7 @@ svn_cl__print_status_xml(const char *pat
 /* Called by status-cmd.c */
 svn_error_t *
 svn_cl__print_status(const char *path,
-                     const svn_wc_status3_t *status,
+                     const svn_client_status_t *status,
                      svn_boolean_t detailed,
                      svn_boolean_t show_last_committed,
                      svn_boolean_t skip_unrecognized,
@@ -422,17 +444,10 @@ svn_cl__print_status(const char *path,
                      svn_client_ctx_t *ctx,
                      apr_pool_t *pool)
 {
-  const char *local_abspath;
-  svn_boolean_t tree_conflicted;
-
-  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
-  SVN_ERR(svn_wc__node_check_conflicts(NULL, NULL, &tree_conflicted,
-                                       ctx->wc_ctx, local_abspath, pool,
-                                       pool));
   if (! status
-      || (skip_unrecognized && !(status->entry || tree_conflicted))
-      || (status->text_status == svn_wc_status_none
-          && status->repos_text_status == svn_wc_status_none))
+      || (skip_unrecognized && !(status->versioned || status->conflicted))
+      || (status->node_status == svn_wc_status_none
+          && status->repos_node_status == svn_wc_status_none))
     return SVN_NO_ERROR;
 
   return print_status(svn_dirent_local_style(path, pool),

Modified: subversion/branches/ignore-mergeinfo/subversion/svn/unlock-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/svn/unlock-cmd.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/svn/unlock-cmd.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/svn/unlock-cmd.c Tue Aug 10 22:07:24 2010
@@ -60,7 +60,7 @@ svn_cl__unlock(apr_getopt_t *os,
   SVN_ERR(svn_cl__get_notifier(&ctx->notify_func2, &ctx->notify_baton2, FALSE,
                                FALSE, FALSE, scratch_pool));
 
-  SVN_ERR(svn_opt_eat_peg_revisions(&targets, targets, scratch_pool));
+  SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, scratch_pool));
 
   return svn_error_return(
     svn_client_unlock(targets, opt_state->force, ctx, scratch_pool));

Modified: subversion/branches/ignore-mergeinfo/subversion/svn/update-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/svn/update-cmd.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/svn/update-cmd.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/svn/update-cmd.c Tue Aug 10 22:07:24 2010
@@ -58,7 +58,7 @@ svn_cl__update(apr_getopt_t *os,
   /* Add "." if user passed 0 arguments */
   svn_opt_push_implicit_dot_target(targets, scratch_pool);
 
-  SVN_ERR(svn_opt_eat_peg_revisions(&targets, targets, scratch_pool));
+  SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, scratch_pool));
 
   /* If using changelists, convert targets into a set of paths that
      match the specified changelist(s). */

Modified: subversion/branches/ignore-mergeinfo/subversion/svn/upgrade-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/svn/upgrade-cmd.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/svn/upgrade-cmd.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/svn/upgrade-cmd.c Tue Aug 10 22:07:24 2010
@@ -61,7 +61,7 @@ svn_cl__upgrade(apr_getopt_t *os,
     SVN_ERR(svn_cl__get_notifier(&ctx->notify_func2, &ctx->notify_baton2,
                                  FALSE, FALSE, FALSE, scratch_pool));
 
-  SVN_ERR(svn_opt_eat_peg_revisions(&targets, targets, scratch_pool));
+  SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, scratch_pool));
 
   iterpool = svn_pool_create(scratch_pool);
   for (i = 0; i < targets->nelts; i++)

Modified: subversion/branches/ignore-mergeinfo/subversion/svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/svn/util.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/svn/util.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/svn/util.c Tue Aug 10 22:07:24 2010
@@ -60,6 +60,7 @@
 #include "cl.h"
 
 #include "private/svn_token.h"
+#include "private/svn_opt_private.h"
 
 
 
@@ -166,7 +167,7 @@ svn_cl__edit_file_externally(const char 
   int sys_err;
   apr_status_t apr_err;
 
-  svn_dirent_split(path, &base_dir, &file_name, pool);
+  svn_dirent_split(&base_dir, &file_name, path, pool);
 
   SVN_ERR(find_editor_binary(&editor, editor_cmd, config));
 
@@ -1294,5 +1295,34 @@ svn_cl__path_join(const char *base,
                   const char *component,
                   apr_pool_t *pool)
 {
-  return svn_path_join(base, component, pool);
+  if (svn_path_is_url(base))
+    return svn_uri_join(base, component, pool);
+  else
+    return svn_dirent_join(base, component, pool);
+}
+
+svn_error_t *
+svn_cl__eat_peg_revisions(apr_array_header_t **true_targets_p,
+                          const apr_array_header_t *targets,
+                          apr_pool_t *pool)
+{
+  int i;
+  apr_array_header_t *true_targets;
+
+  true_targets = apr_array_make(pool, targets->nelts, sizeof(const char *));
+
+  for (i = 0; i < targets->nelts; i++)
+    {
+      const char *target = APR_ARRAY_IDX(targets, i, const char *);
+      const char *true_target;
+
+      SVN_ERR(svn_opt__split_arg_at_peg_revision(&true_target, NULL,
+                                                 target, pool));
+      APR_ARRAY_PUSH(true_targets, const char *) = true_target;
+    }
+
+  SVN_ERR_ASSERT(true_targets_p);
+  *true_targets_p = true_targets;
+
+  return SVN_NO_ERROR;
 }

Modified: subversion/branches/ignore-mergeinfo/subversion/svnadmin/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/svnadmin/main.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/svnadmin/main.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/svnadmin/main.c Tue Aug 10 22:07:24 2010
@@ -413,7 +413,7 @@ static const svn_opt_subcommand_desc2_t 
    ("usage: svnadmin pack REPOS_PATH\n\n"
     "Possibly compact the repository into a more efficient storage model.\n"
     "This may not apply to all repositories, in which case, exit.\n"),
-   {0} },
+   {'q'} },
 
   {"recover", subcommand_recover, {0}, N_
    ("usage: svnadmin recover REPOS_PATH\n\n"
@@ -530,17 +530,16 @@ get_revnum(svn_revnum_t *revnum, const s
   else if (revision->kind == svn_opt_revision_head)
     *revnum = youngest;
   else if (revision->kind == svn_opt_revision_date)
-    SVN_ERR(svn_repos_dated_revision
-            (revnum, repos, revision->value.date, pool));
+    SVN_ERR(svn_repos_dated_revision(revnum, repos, revision->value.date,
+                                     pool));
   else if (revision->kind == svn_opt_revision_unspecified)
     *revnum = SVN_INVALID_REVNUM;
   else
-    return svn_error_create
-      (SVN_ERR_CL_ARG_PARSING_ERROR, NULL, _("Invalid revision specifier"));
+    return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                            _("Invalid revision specifier"));
 
   if (*revnum > youngest)
-    return svn_error_createf
-      (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+    return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
        _("Revisions must not be greater than the youngest revision (%ld)"),
        youngest);
 
@@ -627,8 +626,7 @@ subcommand_deltify(apr_getopt_t *os, voi
     end = start;
 
   if (start > end)
-    return svn_error_create
-      (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+    return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
        _("First revision cannot be higher than second"));
 
   /* Loop over the requested revision range, performing the
@@ -650,35 +648,162 @@ subcommand_deltify(apr_getopt_t *os, voi
 }
 
 
-/* Baton for repos_progress_handler */
-struct progress_baton
-{
-  svn_boolean_t dumping;
-  svn_stream_t *progress_stream;
-};
-
-/* Implementation of svn_repos_progress_func_t to wrap the output to a
+/* Implementation of svn_repos_notify_func_t to wrap the output to a
    response stream for svn_repos_dump_fs2() and svn_repos_verify_fs() */
-static svn_error_t *
-repos_progress_handler(void * baton,
-                       svn_revnum_t revision,
-                       const char *warning_text,
-                       apr_pool_t *scratch_pool)
-{
-  struct progress_baton *pb = baton;
+static void
+repos_notify_handler(void *baton,
+                     const svn_repos_notify_t *notify,
+                     apr_pool_t *scratch_pool)
+{
+  svn_stream_t *feedback_stream = baton;
+  apr_size_t len;
+
+  switch (notify->action)
+  {
+    case svn_repos_notify_warning:
+      len = strlen(notify->warning);
+      svn_error_clear(svn_stream_write(feedback_stream, notify->warning,
+                                       &len));
+      return;
+
+    case svn_repos_notify_dump_rev_end:
+      svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+                                        _("* Dumped revision %ld.\n"),
+                                        notify->revision));
+      return;
+
+    case svn_repos_notify_verify_rev_end:
+      svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+                                        _("* Verified revision %ld.\n"),
+                                        notify->revision));
+      return;
+
+    case svn_repos_notify_pack_shard_start:
+      {
+        const char *shardstr = apr_psprintf(scratch_pool,
+                                            "%" APR_INT64_T_FMT,
+                                            notify->shard);
+        svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+                                          _("Packing revisions in shard %s..."),
+                                          shardstr));
+      }
+      return;
+
+    case svn_repos_notify_pack_shard_end:
+      svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+                                        _("done.\n")));
+      return;
+
+    case svn_repos_notify_pack_shard_start_revprop:
+      {
+        const char *shardstr = apr_psprintf(scratch_pool,
+                                            "%" APR_INT64_T_FMT,
+                                            notify->shard);
+        svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+                                          _("Packing revprops in shard %s..."),
+                                          shardstr));
+      }
+      return;
+
+    case svn_repos_notify_pack_shard_end_revprop:
+      svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+                                        _("done.\n")));
+      return;
 
-  if (warning_text != NULL)
-    {
-      apr_size_t len = strlen(warning_text);
-      return svn_error_return(svn_stream_write(pb->progress_stream,
-                                               warning_text, &len));
-    }
+    case svn_repos_notify_load_txn_committed:
+      if (notify->old_revision == SVN_INVALID_REVNUM)
+        {
+          svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+                            _("\n------- Committed revision %ld >>>\n\n"),
+                            notify->new_revision));
+        }
+      else
+        {
+          svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+                            _("\n------- Committed new rev %ld"
+                              " (loaded from original rev %ld"
+                              ") >>>\n\n"), notify->new_revision,
+                              notify->old_revision));
+        }
+      return;
+
+    case svn_repos_notify_load_node_start:
+      {
+        switch (notify->node_action)
+        {
+          case svn_node_action_change:
+            svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+                                  _("     * editing path : %s ..."),
+                                  notify->path));
+            break;
+          
+          case svn_node_action_delete:
+            svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+                                  _("     * deleting path : %s ..."),
+                                  notify->path));
+            break;
+          
+          case svn_node_action_add:
+            svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+                                  _("     * adding path : %s ..."),
+                                  notify->path));
+            break;
+          
+          case svn_node_action_replace:
+            svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+                                  _("     * replacing path : %s ..."),
+                                  notify->path));
+            break;
+          
+        }
+      }
+      return;
+
+    case svn_repos_notify_load_node_done:
+      len = 7;
+      svn_error_clear(svn_stream_write(feedback_stream, _(" done.\n"), &len));
+      return;
+
+    case svn_repos_notify_load_copied_node:
+      len = 9;
+      svn_error_clear(svn_stream_write(feedback_stream, "COPIED...", &len));
+      return;
+
+    case svn_repos_notify_load_txn_start:
+      svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+                                _("<<< Started new transaction, based on "
+                                  "original revision %ld\n"),
+                                notify->old_revision));
+      return;
+
+    case svn_repos_notify_load_normalized_mergeinfo:
+      svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+                                _(" removing '\\r' from %s ..."),
+                                SVN_PROP_MERGEINFO));
+      return;
+
+    case svn_repos_notify_mutex_acquired:
+      /* Enable cancellation signal handlers. */
+      setup_cancellation_signals(signal_handler);
+      return;
 
-  return svn_error_return(svn_stream_printf(pb->progress_stream, scratch_pool,
-                              pb->dumping
-                              ? _("* Dumped revision %ld.\n")
-                              : _("* Verified revision %ld.\n"),
-                              revision));
+    case svn_repos_notify_recover_start:
+      svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+                             _("Repository lock acquired.\n"
+                               "Please wait; recovering the"
+                               " repository may take some time...\n")));
+      return;
+
+    case svn_repos_notify_upgrade_start:
+      svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+                             _("Repository lock acquired.\n"
+                               "Please wait; upgrading the"
+                               " repository may take some time...\n")));
+      return;
+
+    default:
+      return;
+  }
 }
 
 
@@ -732,7 +857,7 @@ subcommand_dump(apr_getopt_t *os, void *
   svn_stream_t *stdout_stream;
   svn_revnum_t lower = SVN_INVALID_REVNUM, upper = SVN_INVALID_REVNUM;
   svn_revnum_t youngest;
-  struct progress_baton pb = { 0 };
+  svn_stream_t *progress_stream = NULL;
 
   SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
   fs = svn_repos_fs(repos);
@@ -756,22 +881,19 @@ subcommand_dump(apr_getopt_t *os, void *
     }
 
   if (lower > upper)
-    return svn_error_create
-      (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+    return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
        _("First revision cannot be higher than second"));
 
   SVN_ERR(create_stdio_stream(&stdout_stream, apr_file_open_stdout, pool));
 
   /* Progress feedback goes to STDERR, unless they asked to suppress it. */
   if (! opt_state->quiet)
-    pb.progress_stream = recode_stream_create(stderr, pool);
+    progress_stream = recode_stream_create(stderr, pool);
 
-  pb.dumping = TRUE;
   SVN_ERR(svn_repos_dump_fs3(repos, stdout_stream, lower, upper,
                              opt_state->incremental, opt_state->use_deltas,
-                             !opt_state->quiet ? repos_progress_handler : NULL,
-                             !opt_state->quiet ? &pb : NULL,
-                             check_cancel, NULL, pool));
+                             !opt_state->quiet ? repos_notify_handler : NULL,
+                             progress_stream, check_cancel, NULL, pool));
 
   return SVN_NO_ERROR;
 }
@@ -825,11 +947,12 @@ subcommand_load(apr_getopt_t *os, void *
   if (! opt_state->quiet)
     stdout_stream = recode_stream_create(stdout, pool);
 
-  SVN_ERR(svn_repos_load_fs2(repos, stdin_stream, stdout_stream,
+  SVN_ERR(svn_repos_load_fs3(repos, stdin_stream,
                              opt_state->uuid_action, opt_state->parent_dir,
                              opt_state->use_pre_commit_hook,
                              opt_state->use_post_commit_hook,
-                             check_cancel, NULL, pool));
+                             !opt_state->quiet ? repos_notify_handler : NULL,
+                             stdout_stream, check_cancel, NULL, pool));
 
   return SVN_NO_ERROR;
 }
@@ -860,25 +983,6 @@ subcommand_lstxns(apr_getopt_t *os, void
 }
 
 
-/* A callback which is called when the recovery starts. */
-static svn_error_t *
-recovery_started(void *baton)
-{
-  apr_pool_t *pool = (apr_pool_t *)baton;
-
-  SVN_ERR(svn_cmdline_printf(pool,
-                             _("Repository lock acquired.\n"
-                               "Please wait; recovering the"
-                               " repository may take some time...\n")));
-  SVN_ERR(svn_cmdline_fflush(stdout));
-
-  /* Enable cancellation signal handlers. */
-  setup_cancellation_signals(signal_handler);
-
-  return SVN_NO_ERROR;
-}
-
-
 /* This implements `svn_opt_subcommand_t'. */
 static svn_error_t *
 subcommand_recover(apr_getopt_t *os, void *baton, apr_pool_t *pool)
@@ -887,14 +991,17 @@ subcommand_recover(apr_getopt_t *os, voi
   svn_repos_t *repos;
   svn_error_t *err;
   struct svnadmin_opt_state *opt_state = baton;
+  svn_stream_t *stdout_stream;
+
+  SVN_ERR(create_stdio_stream(&stdout_stream, apr_file_open_stdout, pool));
 
   /* Restore default signal handlers until after we have acquired the
    * exclusive lock so that the user interrupt before we actually
    * touch the repository. */
   setup_cancellation_signals(SIG_DFL);
 
-  err = svn_repos_recover3(opt_state->repository_path, TRUE,
-                           recovery_started, pool,
+  err = svn_repos_recover4(opt_state->repository_path, TRUE,
+                           repos_notify_handler, stdout_stream,
                            check_cancel, NULL, pool);
   if (err)
     {
@@ -911,8 +1018,8 @@ subcommand_recover(apr_getopt_t *os, voi
                                  _("Waiting on repository lock; perhaps"
                                    " another process has it open?\n")));
       SVN_ERR(svn_cmdline_fflush(stdout));
-      SVN_ERR(svn_repos_recover3(opt_state->repository_path, FALSE,
-                                 recovery_started, pool,
+      SVN_ERR(svn_repos_recover4(opt_state->repository_path, FALSE,
+                                 repos_notify_handler, stdout_stream,
                                  check_cancel, NULL, pool));
     }
 
@@ -1032,9 +1139,8 @@ subcommand_rmtxns(apr_getopt_t *os, void
         }
       else if (! opt_state->quiet)
         {
-          SVN_ERR
-            (svn_cmdline_printf(subpool, _("Transaction '%s' removed.\n"),
-                                txn_name));
+          SVN_ERR(svn_cmdline_printf(subpool, _("Transaction '%s' removed.\n"),
+                                     txn_name));
         }
     }
 
@@ -1074,18 +1180,19 @@ set_revprop(const char *prop_name, const
   if (opt_state->use_pre_revprop_change_hook ||
       opt_state->use_post_revprop_change_hook)
     {
-      SVN_ERR(svn_repos_fs_change_rev_prop3
-              (repos, opt_state->start_revision.value.number,
-               NULL, prop_name, prop_value,
-               opt_state->use_pre_revprop_change_hook,
-               opt_state->use_post_revprop_change_hook, NULL, NULL, pool));
+      SVN_ERR(svn_repos_fs_change_rev_prop3(repos,
+                            opt_state->start_revision.value.number,
+                            NULL, prop_name, prop_value,
+                            opt_state->use_pre_revprop_change_hook,
+                            opt_state->use_post_revprop_change_hook, NULL,
+                            NULL, pool));
     }
   else
     {
       svn_fs_t *fs = svn_repos_fs(repos);
-      SVN_ERR(svn_fs_change_rev_prop
-              (fs, opt_state->start_revision.value.number,
-               prop_name, prop_value, pool));
+      SVN_ERR(svn_fs_change_rev_prop2(fs,
+                                      opt_state->start_revision.value.number,
+                                      prop_name, NULL, prop_value, pool));
     }
 
   return SVN_NO_ERROR;
@@ -1174,33 +1281,6 @@ subcommand_setlog(apr_getopt_t *os, void
                      opt_state, pool);
 }
 
-/* This implements svn_fs_pack_notify_t */
-static svn_error_t *
-pack_notify(void *baton,
-            apr_int64_t shard,
-            svn_fs_pack_notify_action_t action,
-            apr_pool_t *pool)
-{
-  switch (action)
-    {
-      case svn_fs_pack_notify_start:
-        {
-          const char *shardstr = apr_psprintf(pool, "%" APR_INT64_T_FMT, shard);
-          SVN_ERR(svn_cmdline_printf(pool, _("Packing shard %s..."), shardstr));
-        }
-        break;
-
-      case svn_fs_pack_notify_end:
-        SVN_ERR(svn_cmdline_printf(pool, _("done.\n")));
-        break;
-
-      default:
-        return SVN_NO_ERROR;
-    }
-
-  return svn_cmdline_fflush(stdout);
-}
-
 
 /* This implements 'svn_opt_subcommand_t'. */
 static svn_error_t *
@@ -1208,10 +1288,17 @@ subcommand_pack(apr_getopt_t *os, void *
 {
   struct svnadmin_opt_state *opt_state = baton;
   svn_repos_t *repos;
+  svn_stream_t *progress_stream = NULL;
 
   SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
 
-  return svn_repos_fs_pack(repos, pack_notify, NULL, check_cancel, NULL, pool);
+  /* Progress feedback goes to STDOUT, unless they asked to suppress it. */
+  if (! opt_state->quiet)
+    progress_stream = recode_stream_create(stderr, pool);
+
+  return svn_error_return(
+    svn_repos_fs_pack2(repos, !opt_state->quiet ? repos_notify_handler : NULL,
+                       progress_stream, check_cancel, NULL, pool));
 }
 
 
@@ -1223,7 +1310,7 @@ subcommand_verify(apr_getopt_t *os, void
   svn_repos_t *repos;
   svn_fs_t *fs;
   svn_revnum_t youngest, lower, upper;
-  struct progress_baton pb = { 0 };
+  svn_stream_t *progress_stream;
 
   SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
   fs = svn_repos_fs(repos);
@@ -1241,13 +1328,12 @@ subcommand_verify(apr_getopt_t *os, void
     }
 
   if (! opt_state->quiet)
-    pb.progress_stream = recode_stream_create(stderr, pool);
+    progress_stream = recode_stream_create(stderr, pool);
 
   return svn_repos_verify_fs2(repos, lower, upper,
                               !opt_state->quiet
-                                ? repos_progress_handler : NULL,
-                              !opt_state->quiet ? &pb : NULL,
-                              check_cancel, NULL, pool);
+                                ? repos_notify_handler : NULL,
+                              progress_stream, check_cancel, NULL, pool);
 }
 
 
@@ -1405,37 +1491,21 @@ subcommand_rmlocks(apr_getopt_t *os, voi
 }
 
 
-/* A callback which is called when the upgrade starts. */
-static svn_error_t *
-upgrade_started(void *baton)
-{
-  apr_pool_t *pool = (apr_pool_t *)baton;
-
-  SVN_ERR(svn_cmdline_printf(pool,
-                             _("Repository lock acquired.\n"
-                               "Please wait; upgrading the"
-                               " repository may take some time...\n")));
-  SVN_ERR(svn_cmdline_fflush(stdout));
-
-  /* Enable cancellation signal handlers. */
-  setup_cancellation_signals(signal_handler);
-
-  return SVN_NO_ERROR;
-}
-
-
 /* This implements `svn_opt_subcommand_t'. */
 static svn_error_t *
 subcommand_upgrade(apr_getopt_t *os, void *baton, apr_pool_t *pool)
 {
   svn_error_t *err;
   struct svnadmin_opt_state *opt_state = baton;
+  svn_stream_t *stdout_stream;
+
+  SVN_ERR(create_stdio_stream(&stdout_stream, apr_file_open_stdout, pool));
 
   /* Restore default signal handlers. */
   setup_cancellation_signals(SIG_DFL);
 
-  err = svn_repos_upgrade(opt_state->repository_path, TRUE,
-                          upgrade_started, pool, pool);
+  err = svn_repos_upgrade2(opt_state->repository_path, TRUE,
+                           repos_notify_handler, stdout_stream, pool);
   if (err)
     {
       if (APR_STATUS_IS_EAGAIN(err->apr_err))
@@ -1452,20 +1522,21 @@ subcommand_upgrade(apr_getopt_t *os, voi
                                      _("Waiting on repository lock; perhaps"
                                        " another process has it open?\n")));
           SVN_ERR(svn_cmdline_fflush(stdout));
-          SVN_ERR(svn_repos_upgrade(opt_state->repository_path, FALSE,
-                                    upgrade_started, pool, pool));
+          SVN_ERR(svn_repos_upgrade2(opt_state->repository_path, FALSE,
+                                     repos_notify_handler, stdout_stream,
+                                     pool));
         }
       else if (err->apr_err == SVN_ERR_FS_UNSUPPORTED_UPGRADE)
         {
-          return svn_error_quick_wrap
-            (err, _("Upgrade of this repository's underlying versioned "
+          return svn_error_quick_wrap(err,
+                    _("Upgrade of this repository's underlying versioned "
                     "filesystem is not supported; consider "
                     "dumping and loading the data elsewhere"));
         }
       else if (err->apr_err == SVN_ERR_REPOS_UNSUPPORTED_UPGRADE)
         {
-          return svn_error_quick_wrap
-            (err, _("Upgrade of this repository is not supported; consider "
+          return svn_error_quick_wrap(err,
+                    _("Upgrade of this repository is not supported; consider "
                     "dumping and loading the data elsewhere"));
         }
     }
@@ -1563,8 +1634,7 @@ main(int argc, const char *argv[])
         {
           if (opt_state.start_revision.kind != svn_opt_revision_unspecified)
             {
-              err = svn_error_create
-                (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+              err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                  _("Multiple revision arguments encountered; "
                    "try '-r N:M' instead of '-r N -r M'"));
               return svn_cmdline_handle_exit_error(err, pool, "svnadmin: ");
@@ -1577,10 +1647,9 @@ main(int argc, const char *argv[])
                                             pool);
 
               if (! err)
-                err = svn_error_createf
-                  (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                   _("Syntax error in revision argument '%s'"),
-                   utf8_opt_arg);
+                err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                        _("Syntax error in revision argument '%s'"),
+                        utf8_opt_arg);
               return svn_cmdline_handle_exit_error(err, pool, "svnadmin: ");
             }
         }
@@ -1697,9 +1766,8 @@ main(int argc, const char *argv[])
             }
           else
             {
-              svn_error_clear
-                (svn_cmdline_fprintf(stderr, pool,
-                                     _("subcommand argument required\n")));
+              svn_error_clear(svn_cmdline_fprintf(stderr, pool,
+                                        _("subcommand argument required\n")));
               subcommand_help(NULL, NULL, pool);
               svn_pool_destroy(pool);
               return EXIT_FAILURE;
@@ -1715,10 +1783,9 @@ main(int argc, const char *argv[])
               err = svn_utf_cstring_to_utf8(&first_arg_utf8, first_arg, pool);
               if (err)
                 return svn_cmdline_handle_exit_error(err, pool, "svnadmin: ");
-              svn_error_clear
-                (svn_cmdline_fprintf(stderr, pool,
-                                     _("Unknown command: '%s'\n"),
-                                     first_arg_utf8));
+              svn_error_clear(svn_cmdline_fprintf(stderr, pool,
+                                                  _("Unknown command: '%s'\n"),
+                                                  first_arg_utf8));
               subcommand_help(NULL, NULL, pool);
               svn_pool_destroy(pool);
               return EXIT_FAILURE;
@@ -1772,9 +1839,8 @@ main(int argc, const char *argv[])
           if (subcommand->name[0] == '-')
             subcommand_help(NULL, NULL, pool);
           else
-            svn_error_clear
-              (svn_cmdline_fprintf
-               (stderr, pool, _("Subcommand '%s' doesn't accept option '%s'\n"
+            svn_error_clear(svn_cmdline_fprintf(stderr, pool
+                            , _("Subcommand '%s' doesn't accept option '%s'\n"
                                 "Type 'svnadmin help %s' for usage.\n"),
                 subcommand->name, optstr, subcommand->name));
           svn_pool_destroy(pool);

Modified: subversion/branches/ignore-mergeinfo/subversion/svnserve/serve.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/svnserve/serve.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/svnserve/serve.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/svnserve/serve.c Tue Aug 10 22:07:24 2010
@@ -175,6 +175,21 @@ error_create_and_log(apr_status_t apr_er
   return err;
 }
 
+/* Log a failure ERR, transmit ERR back to the client (as part of a
+   "failure" notification), consume ERR, and flush the connection. */
+static svn_error_t *
+log_fail_and_flush(svn_error_t *err, server_baton_t *server,
+                   svn_ra_svn_conn_t *conn, apr_pool_t *pool)
+{
+  svn_error_t *io_err;
+
+  log_server_error(err, server, conn, pool);
+  io_err = svn_ra_svn_write_cmd_failure(conn, pool, err);
+  svn_error_clear(err);
+  SVN_ERR(io_err);
+  return svn_ra_svn_flush(conn, pool);
+}
+
 /* Log a client command. */
 static svn_error_t *log_command(server_baton_t *b,
                                 svn_ra_svn_conn_t *conn,
@@ -2139,16 +2154,22 @@ static svn_error_t *get_location_segment
   if (SVN_IS_VALID_REVNUM(start_rev)
       && SVN_IS_VALID_REVNUM(end_rev)
       && (end_rev > start_rev))
-    return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
-                             "Get-location-segments end revision must not be "
-                             "younger than start revision");
+    {
+      err = svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
+                              "Get-location-segments end revision must not be "
+                              "younger than start revision");
+      return log_fail_and_flush(err, b, conn, pool);
+    }
 
   if (SVN_IS_VALID_REVNUM(peg_revision)
       && SVN_IS_VALID_REVNUM(start_rev)
       && (start_rev > peg_revision))
-    return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
-                             "Get-location-segments start revision must not "
-                             "be younger than peg revision");
+    {
+      err = svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
+                              "Get-location-segments start revision must not "
+                              "be younger than peg revision");
+      return log_fail_and_flush(err, b, conn, pool);
+    }
 
   SVN_ERR(trivial_auth_request(conn, pool, b));
   SVN_ERR(log_command(baton, conn, pool, "%s",
@@ -2572,21 +2593,34 @@ static svn_error_t *get_locks(svn_ra_svn
   server_baton_t *b = baton;
   const char *path;
   const char *full_path;
+  const char *depth_word;
+  svn_depth_t depth;
   apr_hash_t *locks;
   apr_hash_index_t *hi;
+  svn_error_t *err;
 
-  SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "c", &path));
+  SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "c?(?w)", &path, &depth_word));
 
-  full_path = svn_uri_join(b->fs_path->data, svn_uri_canonicalize(path,
-                                                                  pool),
-                           pool);
+  depth = depth_word ? svn_depth_from_word(depth_word) : svn_depth_infinity;
+  if ((depth != svn_depth_empty) &&
+      (depth != svn_depth_files) &&
+      (depth != svn_depth_immediates) &&
+      (depth != svn_depth_infinity))
+    {
+      err = svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
+                             "Invalid 'depth' specified in get-locks request");
+      return log_fail_and_flush(err, b, conn, pool);
+    }
+
+  full_path = svn_uri_join(b->fs_path->data,
+                           svn_uri_canonicalize(path, pool), pool);
 
   SVN_ERR(trivial_auth_request(conn, pool, b));
 
   SVN_ERR(log_command(b, conn, pool, "get-locks %s",
                       svn_path_uri_encode(full_path, pool)));
-  SVN_CMD_ERR(svn_repos_fs_get_locks(&locks, b->repos, full_path,
-                                     authz_check_access_cb_func(b), b, pool));
+  SVN_CMD_ERR(svn_repos_fs_get_locks2(&locks, b->repos, full_path, depth,
+                                      authz_check_access_cb_func(b), b, pool));
 
   SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "w((!", "success"));
   for (hi = apr_hash_first(pool, locks); hi; hi = apr_hash_next(hi))

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/authz_tests.py?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/authz_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/authz_tests.py Tue Aug 10 22:07:24 2010
@@ -973,6 +973,55 @@ def multiple_matches(sbox):
                        '-m', 'second copy',
                        root_url, root_url + '/second')
 
+def wc_wc_copy(sbox):
+  "wc-to-wc copy with absent nodes"
+
+  sbox.build(create_wc = False)
+  local_dir = sbox.wc_dir
+  write_restrictive_svnserve_conf(sbox.repo_dir)
+
+  write_authz_file(sbox, {'/'       : '* = r',
+                          '/A/B/E'  : '* =', })
+
+  expected_output = svntest.main.greek_state.copy()
+  expected_output.wc_dir = local_dir
+  expected_output.tweak(status='A ', contents=None)
+  expected_output.remove('A/B/E', 'A/B/E/alpha', 'A/B/E/beta')
+  expected_wc = svntest.main.greek_state.copy()
+  expected_wc.remove('A/B/E', 'A/B/E/alpha', 'A/B/E/beta')
+
+  svntest.actions.run_and_verify_checkout(sbox.repo_url, local_dir,
+                                          expected_output,
+                                          expected_wc)
+
+  svntest.actions.run_and_verify_svn(None, None,
+                                     'svn: Cannot copy.*excluded by server',
+                                     'cp', sbox.ospath('A'), sbox.ospath('A2'))
+
+  # The copy failed and A2/B/E is incomplete.  That means A2 and A2/B
+  # are complete, but for the other parts of A2 the status is undefined.
+  expected_output = svntest.verify.ExpectedOutput(
+    ['A  +             -        1 jrandom      ' + sbox.ospath('A2') + '\n',
+     '   +             -        1 jrandom      ' + sbox.ospath('A2/B') + '\n',
+     '!               ?        ?   ?           ' + sbox.ospath('A2/B/E') + '\n',
+     ])
+  expected_output.match_all = False
+
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'st', '--verbose', sbox.ospath('A2'))
+
+def wc_wc_copy_revert(sbox):
+  "wc-to-wc-copy with absent nodes and then revert"
+
+  wc_wc_copy(sbox)
+
+  # Fails with a "No write-lock" error, as does "rm --force", on a
+  # path under A2.  Multiple repeats fail on different paths until the
+  # command completes.
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'revert', '--recursive', sbox.ospath('A2'))
+  
+
 ########################################################################
 # Run the tests
 
@@ -1001,6 +1050,8 @@ test_list = [ None,
               Skip(authz_access_required_at_repo_root2,
                    svntest.main.is_ra_type_file),
               Skip(multiple_matches, svntest.main.is_ra_type_file),
+              Skip(wc_wc_copy, svntest.main.is_ra_type_file),
+              XFail(Skip(wc_wc_copy_revert, svntest.main.is_ra_type_file)),
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/basic_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/basic_tests.py?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/basic_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/basic_tests.py Tue Aug 10 22:07:24 2010
@@ -257,20 +257,28 @@ def basic_mkdir_url_with_parents(sbox):
 
   sbox.build()
 
+  X_url = sbox.repo_url + '/X'
   X_Y_Z_url = sbox.repo_url + '/X/Y/Z'
   X_Y_Z2_url = sbox.repo_url + '/X/Y/Z2'
   X_T_C_url = sbox.repo_url + '/X/T/C'
+  U_url = sbox.repo_url + '/U'
   U_V_url = sbox.repo_url + '/U/V'
+  U_V_W_url = sbox.repo_url + '/U/V/W'
   svntest.actions.run_and_verify_svn("erroneous mkdir sans --parents",
                                      [],
                                      ".*Try 'svn mkdir --parents' instead.*",
                                      'mkdir', '-m', 'log_msg',
-                                     X_Y_Z_url, X_Y_Z2_url, X_T_C_url, U_V_url)
+                                     X_Y_Z_url, X_Y_Z2_url, X_T_C_url, U_V_W_url)
 
-  svntest.actions.run_and_verify_svn("mkdir --parents",
+  svntest.actions.run_and_verify_svn("mkdir",
                                      ["\n", "Committed revision 2.\n"], [],
+                                     'mkdir', '-m', 'log_msg',
+                                     X_url, U_url)
+
+  svntest.actions.run_and_verify_svn("mkdir --parents",
+                                     ["\n", "Committed revision 3.\n"], [],
                                      'mkdir', '-m', 'log_msg', '--parents',
-                                     X_Y_Z_url, X_Y_Z2_url, X_T_C_url, U_V_url)
+                                     X_Y_Z_url, X_Y_Z2_url, X_T_C_url, U_V_W_url)
 
   expected_output = wc.State(sbox.wc_dir, {
     'X'      : Item(status='A '),
@@ -281,6 +289,7 @@ def basic_mkdir_url_with_parents(sbox):
     'X/T/C'  : Item(status='A '),
     'U'      : Item(status='A '),
     'U/V'    : Item(status='A '),
+    'U/V/W'  : Item(status='A '),
     })
   expected_disk = svntest.main.greek_state.copy()
   expected_disk.add({
@@ -292,17 +301,19 @@ def basic_mkdir_url_with_parents(sbox):
     'X/T/C'  : Item(),
     'U'      : Item(),
     'U/V'    : Item(),
+    'U/V/W'  : Item(),
     })
-  expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 2)
+  expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 3)
   expected_status.add({
-    'X'      : Item(status='  ', wc_rev=2),
-    'X/Y'    : Item(status='  ', wc_rev=2),
-    'X/Y/Z'  : Item(status='  ', wc_rev=2),
-    'X/Y/Z2' : Item(status='  ', wc_rev=2),
-    'X/T'    : Item(status='  ', wc_rev=2),
-    'X/T/C'  : Item(status='  ', wc_rev=2),
-    'U'      : Item(status='  ', wc_rev=2),
-    'U/V'    : Item(status='  ', wc_rev=2),
+    'X'      : Item(status='  ', wc_rev=3),
+    'X/Y'    : Item(status='  ', wc_rev=3),
+    'X/Y/Z'  : Item(status='  ', wc_rev=3),
+    'X/Y/Z2' : Item(status='  ', wc_rev=3),
+    'X/T'    : Item(status='  ', wc_rev=3),
+    'X/T/C'  : Item(status='  ', wc_rev=3),
+    'U'      : Item(status='  ', wc_rev=3),
+    'U/V'    : Item(status='  ', wc_rev=3),
+    'U/V/W'  : Item(status='  ', wc_rev=3),
     })
   svntest.actions.run_and_verify_update(sbox.wc_dir,
                                         expected_output,

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/changelist_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/changelist_tests.py?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/changelist_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/changelist_tests.py Tue Aug 10 22:07:24 2010
@@ -101,8 +101,8 @@ def clname_from_lastchar_cb(full_path):
 
 # Regular expressions for 'svn changelist' output.
 _re_cl_skip = re.compile("Skipped '(.*)'")
-_re_cl_add  = re.compile("Path '(.*)' is now a member of changelist '(.*)'.")
-_re_cl_rem  = re.compile("Path '(.*)' is no longer a member of a changelist.")
+_re_cl_add  = re.compile("^A \[(.*)\] (.*)")
+_re_cl_rem  = re.compile("^D \[(.*)\] (.*)")
 
 def verify_changelist_output(output, expected_adds=None,
                              expected_removals=None,
@@ -133,21 +133,21 @@ def verify_changelist_output(output, exp
     match = _re_cl_rem.match(line)
     if match \
        and expected_removals \
-       and match.group(1) in expected_removals:
+       and match.group(2) in expected_removals:
         continue
     elif match:
       raise svntest.Failure("Unexpected changelist removal line: " + line)
     match = _re_cl_add.match(line)
     if match \
        and expected_adds \
-       and expected_adds.get(match.group(1)) == match.group(2):
+       and expected_adds.get(match.group(2)) == match.group(1):
         continue
     elif match:
       raise svntest.Failure("Unexpected changelist add line: " + line)
     match = _re_cl_skip.match(line)
     if match \
        and expected_skips \
-       and match.group(1) in expected_skips:
+       and match.group(2) in expected_skips:
         continue
     elif match:
       raise svntest.Failure("Unexpected changelist skip line: " + line)
@@ -277,7 +277,8 @@ def add_remove_changelists(sbox):
     os.path.join(wc_dir, 'A', 'D', 'H', 'psi') : 'bar',
     os.path.join(wc_dir, 'A', 'D', 'gamma') : 'bar',
     }
-  verify_changelist_output(output, expected_adds)
+  expected_removals = expected_adds
+  verify_changelist_output(output, expected_adds, expected_removals)
 
   # svn changelist baz WC_DIR/A/D/H --depth infinity
   exit_code, output, errput = svntest.main.run_svn(".*", "changelist", "baz",
@@ -289,7 +290,8 @@ def add_remove_changelists(sbox):
     os.path.join(wc_dir, 'A', 'D', 'H', 'omega') : 'baz',
     os.path.join(wc_dir, 'A', 'D', 'H', 'psi') : 'baz',
     }
-  verify_changelist_output(output, expected_adds)
+  expected_removals = expected_adds
+  verify_changelist_output(output, expected_adds, expected_removals)
 
   ### Now, let's selectively rename some changelists ###
 
@@ -306,7 +308,8 @@ def add_remove_changelists(sbox):
     os.path.join(wc_dir, 'A', 'mu') : 'foo-rename',
     os.path.join(wc_dir, 'iota') : 'foo-rename',
     }
-  verify_changelist_output(output, expected_adds)
+  expected_removals = expected_adds
+  verify_changelist_output(output, expected_adds, expected_removals)
 
   # svn changelist bar WC_DIR --depth infinity
   #     --changelist foo-rename --changelist baz
@@ -324,7 +327,8 @@ def add_remove_changelists(sbox):
     os.path.join(wc_dir, 'A', 'mu') : 'bar',
     os.path.join(wc_dir, 'iota') : 'bar',
     }
-  verify_changelist_output(output, expected_adds)
+  expected_removals = expected_adds
+  verify_changelist_output(output, expected_adds, expected_removals)
 
   ### Okay.  Time to remove some stuff from changelists now. ###
 
@@ -1140,8 +1144,8 @@ test_list = [ None,
               tree_conflicts_and_changelists_on_commit1,
               tree_conflicts_and_changelists_on_commit2,
               tree_conflicts_and_changelists_on_commit3,
-              XFail(move_keeps_changelist),
-              XFail(move_added_keeps_changelist),
+              move_keeps_changelist,
+              move_added_keeps_changelist,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/checkout_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/checkout_tests.py?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/checkout_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/checkout_tests.py Tue Aug 10 22:07:24 2010
@@ -30,7 +30,7 @@ import sys, re, os, time, subprocess
 
 # Our testing module
 import svntest
-from svntest import wc
+from svntest import wc, actions
 
 # (abbreviation)
 Skip = svntest.testcase.Skip
@@ -162,23 +162,49 @@ def checkout_with_obstructions(sbox):
 #----------------------------------------------------------------------
 
 def forced_checkout_of_file_with_dir_obstructions(sbox):
-  """forced co fails if a dir obstructs a file"""
+  """forced co flags conflict if a dir obstructs a file"""
+  # svntest.factory.make(sbox,
+  #                      """mkdir $WC_DIR.other/iota
+  #                         svn co --force url $WC_DIR.other """)
+  sbox.build()
+  url = sbox.repo_url
+  wc_dir_other = sbox.add_wc_path('other')
 
-  make_local_tree(sbox, False, False)
+  other_iota = os.path.join(wc_dir_other, 'iota')
 
-  # Make the "other" working copy
-  other_wc = sbox.add_wc_path('other')
-  os.mkdir(other_wc)
-  os.mkdir(os.path.join(other_wc, "iota"))
+  # mkdir $WC_DIR.other/iota
+  os.makedirs(other_iota)
 
-  # Checkout the standard greek repos into a directory that has a dir named
-  # "iota" obstructing the file "iota" in the repos.  This should fail.
-  exit_code, sout, serr = svntest.actions.run_and_verify_svn(
-    "Expected error during co", None, svntest.verify.AnyOutput,
-    "co", "--force", sbox.repo_url, other_wc)
+  # svn co --force url $WC_DIR.other
+  expected_output = svntest.wc.State(wc_dir_other, {
+    'A'                 : Item(status='A '),
+    'A/B'               : Item(status='A '),
+    'A/B/E'             : Item(status='A '),
+    'A/B/E/alpha'       : Item(status='A '),
+    'A/B/E/beta'        : Item(status='A '),
+    'A/B/F'             : Item(status='A '),
+    'A/B/lambda'        : Item(status='A '),
+    'A/D'               : Item(status='A '),
+    'A/D/H'             : Item(status='A '),
+    'A/D/H/chi'         : Item(status='A '),
+    'A/D/H/omega'       : Item(status='A '),
+    'A/D/H/psi'         : Item(status='A '),
+    'A/D/G'             : Item(status='A '),
+    'A/D/G/pi'          : Item(status='A '),
+    'A/D/G/rho'         : Item(status='A '),
+    'A/D/G/tau'         : Item(status='A '),
+    'A/D/gamma'         : Item(status='A '),
+    'A/C'               : Item(status='A '),
+    'A/mu'              : Item(status='A '),
+    'iota'              : Item(status='  ', treeconflict='C'),
+  })
+
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.tweak('iota', contents=None)
+
+  actions.run_and_verify_checkout(url, wc_dir_other, expected_output,
+    expected_disk, None, None, None, None, '--force')
 
-  test_stderr(".*Failed to add file.*a non-file object of the same name " \
-              "already exists", serr)
 
 #----------------------------------------------------------------------
 
@@ -817,7 +843,7 @@ def co_with_obstructing_local_adds(sbox)
                                           None, None, None, None,
                                           '--force')
 
-  expected_status.tweak('A/B/F/omicron', treeconflict='C')
+  expected_status.tweak('A/B/F/omicron', treeconflict='C', status='R ')
   expected_status.add({
     'A/B/F'         : Item(status='  ', wc_rev=4),
     })

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/copy_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/copy_tests.py?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/copy_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/copy_tests.py Tue Aug 10 22:07:24 2010
@@ -3428,10 +3428,11 @@ def copy_peg_rev_url(sbox):
                                      wc_dir)
 
   # Copy using a peg rev
+  # Add peg rev '@HEAD' to sigma_url when copying which tests for issue #3651.
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'cp',
                                      iota_url + '@HEAD', '-r', '1',
-                                     sigma_url, '-m', 'rev 3')
+                                     sigma_url + '@HEAD', '-m', 'rev 3')
 
   # Validate the copy destination's mergeinfo (we expect none).
   svntest.actions.run_and_verify_svn(None, [], [],
@@ -4462,6 +4463,37 @@ def copy_added_dir_with_copy(sbox):
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
 
+def copy_broken_symlink(sbox):
+  """copy broken symlink"""
+
+  ## See http://subversion.tigris.org/issues/show_bug.cgi?id=3303. ##
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  new_symlink = os.path.join(wc_dir, 'new_symlink');
+  copied_symlink = os.path.join(wc_dir, 'copied_symlink');
+  os.symlink('linktarget', new_symlink)
+
+  # Alias for svntest.actions.run_and_verify_svn
+  rav_svn = svntest.actions.run_and_verify_svn
+
+  rav_svn(None, None, [], 'add', new_symlink)
+  rav_svn(None, None, [], 'cp', new_symlink, copied_symlink)
+
+  # Check whether both new_symlink and copied_symlink are added to the
+  # working copy
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+
+  expected_status.add(
+    {
+      'new_symlink'       : Item(status='A ', wc_rev='0'),
+      'copied_symlink'    : Item(status='A ', wc_rev='0'),
+    })
+
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
+
 ########################################################################
 # Run the tests
 
@@ -4491,9 +4523,7 @@ test_list = [ None,
               repos_to_wc_1634,
               double_uri_escaping_1814,
               wc_to_wc_copy_between_different_repos,
-              ### should be XFail, but it core dumps with an assertion.
-              ### marking as Skip() to avoid core dump turds...
-              Skip(wc_to_wc_copy_deleted),
+              XFail(wc_to_wc_copy_deleted),
               url_to_non_existent_url_path,
               non_existent_url_to_url,
               old_dir_url_to_url,
@@ -4538,7 +4568,7 @@ test_list = [ None,
               copy_make_parents_wc_repo,
               copy_make_parents_repo_repo,
               URI_encoded_repos_to_wc,
-              allow_unversioned_parent_for_copy_src,
+              XFail(allow_unversioned_parent_for_copy_src),
               replaced_local_source_for_incoming_copy,
               unneeded_parents,
               double_parents_with_url,
@@ -4551,7 +4581,8 @@ test_list = [ None,
               XFail(move_below_move),
               reverse_merge_move,
               XFail(nonrecursive_commit_of_copy),
-              XFail(copy_added_dir_with_copy),
+              copy_added_dir_with_copy,
+              SkipUnless(copy_broken_symlink, svntest.main.is_posix_os),
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/depth_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/depth_tests.py?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/depth_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/depth_tests.py Tue Aug 10 22:07:24 2010
@@ -2175,6 +2175,7 @@ def excluded_path_misc_operation(sbox):
   A_path = os.path.join(wc_dir, 'A')
   B_path = os.path.join(A_path, 'B')
   L_path = os.path.join(A_path, 'L')
+  M_path = os.path.join(A_path, 'M')
   E_path = os.path.join(B_path, 'E')
   LE_path = os.path.join(L_path, 'E')
 
@@ -2211,19 +2212,27 @@ def excluded_path_misc_operation(sbox):
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'rm', '--force', L_path)
 
-  # copy A/B to A/L again, excluded entry should be copied too
+  # copy A/B to A/L and then cp A/L to A/M, excluded entry should be
+  # copied both times
   expected_output = ['A         '+L_path+'\n']
   svntest.actions.run_and_verify_svn(None, expected_output, [],
                                      'cp', B_path, L_path)
+  expected_output = ['A         '+M_path+'\n']
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'cp', L_path, M_path)
 
   # commit this copy, with an excluded item.
-  expected_output = svntest.wc.State(wc_dir, { 'A/L' : Item(verb='Adding'), })
+  expected_output = svntest.wc.State(wc_dir, { 'A/L' : Item(verb='Adding'),
+                                               'A/M' : Item(verb='Adding'), })
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
   expected_status.remove('A/B/E/alpha', 'A/B/E/beta', 'A/B/E')
   expected_status.add({
     'A/L'        : Item(status='  ', wc_rev=2),
     'A/L/lambda' : Item(status='  ', wc_rev=2),
     'A/L/F'      : Item(status='  ', wc_rev=2),
+    'A/M'        : Item(status='  ', wc_rev=2),
+    'A/M/lambda' : Item(status='  ', wc_rev=2),
+    'A/M/F'      : Item(status='  ', wc_rev=2),
     })
   svntest.actions.run_and_verify_commit(wc_dir,
                                         expected_output,

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/diff_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/diff_tests.py?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/diff_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/diff_tests.py Tue Aug 10 22:07:24 2010
@@ -52,6 +52,75 @@ def make_diff_header(path, old_tag, new_
     "+++ " + path_as_shown + "\t(" + new_tag + ")\n",
     ]
 
+def make_git_diff_header(path, old_tag, new_tag, add=False, src_label=None,
+                         dst_label=None, delete=False, cp=False, mv=False, 
+                         copyfrom=None):
+  """ Generate the expected 'git diff' header for file PATH, with its old
+  and new versions described in parentheses by OLD_TAG and NEW_TAG.
+  SRC_LABEL and DST_LABEL are paths or urls that are added to the diff
+  labels if we're diffing against the repository. ADD, DELETE, CP and MV
+  denotes the operations performed on the file. COPYFROM is the source of a
+  copy or move.  Return the header as an array of newline-terminated
+  strings."""
+
+  path_as_shown = path.replace('\\', '/')
+  if copyfrom:
+    copyfrom_as_shown = copyfrom.replace('\\', '/')
+  if src_label:
+    src_label = src_label.replace('\\', '/')
+    src_label = '\t(.../' + src_label + ')'
+  else:
+    src_label = ''
+  if dst_label:
+    dst_label = dst_label.replace('\\', '/')
+    dst_label = '\t(.../' + dst_label + ')'
+  else:
+    dst_label = ''
+
+  if add:
+    return [
+      "Index: " + path_as_shown + "\n",
+      "===================================================================\n",
+      "diff --git a/" + path_as_shown + " b/" + path_as_shown + "\n",
+      "new file mode 10644\n",
+      "--- /dev/null\t(" + old_tag + ")\n",
+      "+++ b/" + path_as_shown + dst_label + "\t(" + new_tag + ")\n",
+    ]
+  elif delete:
+    return [
+      "Index: " + path_as_shown + "\n",
+      "===================================================================\n",
+      "diff --git a/" + path_as_shown + " b/" + path_as_shown + "\n",
+      "deleted file mode 10644\n",
+      "--- a/" + path_as_shown + src_label + "\t(" + old_tag + ")\n",
+      "+++ /dev/null\t(" + new_tag + ")\n",
+    ]
+  elif cp:
+    return [
+      "Index: " + path_as_shown + "\n",
+      "===================================================================\n",
+      "diff --git a/" + copyfrom_as_shown + " b/" + path_as_shown + "\n",
+      "copy from " + copyfrom_as_shown + "\n",
+      "copy to " + path_as_shown + "\n",
+    ]
+  elif mv:
+    return [
+      "Index: " + path_as_shown + "\n",
+      "===================================================================\n",
+      "diff --git a/" + copyfrom_as_shown + " b/" + path_as_shown + "\n",
+      "rename from " + copyfrom_as_shown + "\n",
+      "rename to " + path_as_shown + "\n",
+    ]
+  else:
+    return [
+      "Index: " + path_as_shown + "\n",
+      "===================================================================\n",
+      "diff --git a/" + path_as_shown + " b/" + path_as_shown + "\n",
+      "--- a/" + path_as_shown + src_label + "\t(" + old_tag + ")\n",
+      "+++ b/" + path_as_shown + dst_label + "\t(" + new_tag + ")\n",
+    ]
+
+
 ######################################################################
 # Diff output checker
 #
@@ -3008,6 +3077,202 @@ def diff_external_diffcmd(sbox):
                                      'diff', '--diff-cmd', diff_script_path,
                                      iota_path)
 
+
+#----------------------------------------------------------------------
+# Diffing an unrelated repository URL against working copy with
+# local modifications (i.e. not committed). This is issue #3295 (diff
+# local changes against arbitrary URL@REV ignores local add).
+
+# Helper
+def make_file_edit_del_add(dir):
+  "make a file mod (M), a deletion (D) and an addition (A)."
+  alpha = os.path.join(dir, 'B', 'E', 'alpha')
+  beta = os.path.join(dir, 'B', 'E', 'beta')
+  theta = os.path.join(dir, 'B', 'E', 'theta')
+
+  # modify alpha, remove beta and add theta.
+  svntest.main.file_append(alpha, "Edited file alpha.\n")
+  svntest.main.run_svn(None, 'remove', beta)
+  svntest.main.file_append(theta, "Created file theta.\n")
+
+  svntest.main.run_svn(None, 'add', theta)
+
+
+def diff_url_against_local_mods(sbox):
+  "diff URL against working copy with local mods"
+
+  sbox.build()
+  os.chdir(sbox.wc_dir)
+
+  A = 'A'
+  A_url = sbox.repo_url + '/A'
+
+  # First, just make a copy.
+  A2 = 'A2'
+  A2_url = sbox.repo_url + '/A2'
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'cp', '-m', 'log msg',
+                                     A_url, A2_url)
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'up')
+
+  # In A, add, remove and change a file, and commit.
+  make_file_edit_del_add(A);
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'ci', '-m', 'committing A')
+
+  # In A2, do the same changes but leave uncommitted.
+  make_file_edit_del_add(A2);
+
+  # Diff URL of A against working copy of A2. Output should be empty.
+  expected_output = []
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'diff', '--old', A_url, '--new', A2)
+
+
+#----------------------------------------------------------------------
+# Diff rev against working copy of a removed and locally re-added file.
+# This is issue #1675 ("svn diff -rN added-file" has odd behavior).
+
+def diff_preexisting_rev_against_local_add(sbox):
+  "diff -r1 of removed file to its local addition"
+  sbox.build()
+  os.chdir(sbox.wc_dir)
+
+  beta = os.path.join('A', 'B', 'E', 'beta')
+
+  # remove
+  svntest.main.run_svn(None, 'remove', beta)
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'ci', '-m', 'removing beta')
+
+  # re-add, without committing
+  svntest.main.file_append(beta, "Re-created file beta.\n")
+  svntest.main.run_svn(None, 'add', beta)
+
+  # diff against -r1, the diff should show both removal and re-addition
+  exit_code, diff_output, err_output = svntest.main.run_svn(
+                        None, 'diff', '-r1', 'A')
+
+  verify_expected_output(diff_output, "-This is the file 'beta'.")
+  verify_expected_output(diff_output, "+Re-created file beta.")
+
+def diff_git_format_wc_wc(sbox):
+  "create a diff in git unidiff format for wc-wc"
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  iota_path = os.path.join(wc_dir, 'iota')
+  mu_path = os.path.join(wc_dir, 'A', 'mu')
+  new_path = os.path.join(wc_dir, 'new')
+  svntest.main.file_append(iota_path, "Changed 'iota'.\n")
+  svntest.main.file_append(new_path, "This is the file 'new'.\n")
+  svntest.main.run_svn(None, 'add', new_path)
+  svntest.main.run_svn(None, 'rm', mu_path)
+
+  ### We're not testing copied or moved paths
+
+  expected_output = make_git_diff_header(mu_path, "revision 1", 
+                                         "working copy", 
+                                         delete=True) + [
+    "@@ -1 +0,0 @@\n",
+    "-This is the file 'mu'.\n",
+  ] + make_git_diff_header(new_path, "revision 0", "working copy", 
+                           add=True) + [
+    "@@ -0,0 +1 @@\n",
+    "+This is the file 'new'.\n",
+  ] +  make_git_diff_header(iota_path, "revision 1", 
+                            "working copy") + [
+    "@@ -1 +1,2 @@\n",
+    " This is the file 'iota'.\n",
+    "+Changed 'iota'.\n",
+  ]
+
+  svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff', 
+                                     '--git-diff', wc_dir)
+
+def diff_git_format_url_wc(sbox):
+  "create a diff in git unidiff format for url-wc"
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  repo_url = sbox.repo_url
+  iota_path = os.path.join(wc_dir, 'iota')
+  mu_path = os.path.join(wc_dir, 'A', 'mu')
+  new_path = os.path.join(wc_dir, 'new')
+  svntest.main.file_append(iota_path, "Changed 'iota'.\n")
+  svntest.main.file_append(new_path, "This is the file 'new'.\n")
+  svntest.main.run_svn(None, 'add', new_path)
+  svntest.main.run_svn(None, 'rm', mu_path)
+
+  ### We're not testing copied or moved paths
+
+  svntest.main.run_svn(None, 'commit', '-m', 'Committing changes', wc_dir)
+  svntest.main.run_svn(None, 'up', wc_dir)
+
+  expected_output = make_git_diff_header(new_path, "revision 0", "revision 2", 
+                                         dst_label=wc_dir, add=True) + [
+    "@@ -0,0 +1 @@\n",
+    "+This is the file 'new'.\n",
+  ] + make_git_diff_header(mu_path, "revision 1", 
+                           "working copy", 
+                           src_label=repo_url,
+                           delete=True) + [
+    "@@ -1 +0,0 @@\n",
+    "-This is the file 'mu'.\n",
+  ] +  make_git_diff_header(iota_path, "revision 1", 
+                            "working copy", src_label=repo_url,
+                            dst_label=wc_dir) + [
+    "@@ -1 +1,2 @@\n",
+    " This is the file 'iota'.\n",
+    "+Changed 'iota'.\n",
+  ]
+
+  svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff', 
+                                     '--git-diff',
+                                     '--old', repo_url + '@1', '--new',
+                                     wc_dir)
+
+def diff_git_format_url_url(sbox):
+  "create a diff in git unidiff format for url-url"
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  repo_url = sbox.repo_url
+  iota_path = os.path.join(wc_dir, 'iota')
+  mu_path = os.path.join(wc_dir, 'A', 'mu')
+  new_path = os.path.join(wc_dir, 'new')
+  svntest.main.file_append(iota_path, "Changed 'iota'.\n")
+  svntest.main.file_append(new_path, "This is the file 'new'.\n")
+  svntest.main.run_svn(None, 'add', new_path)
+  svntest.main.run_svn(None, 'rm', mu_path)
+
+  ### We're not testing copied or moved paths. When we do, we will not be
+  ### able to identify them as copies/moves until we have editor-v2.
+
+  svntest.main.run_svn(None, 'commit', '-m', 'Committing changes', wc_dir)
+  svntest.main.run_svn(None, 'up', wc_dir)
+
+  expected_output = make_git_diff_header("A/mu", "revision 1", 
+                                         "revision 2", 
+                                         delete=True) + [
+    "@@ -1 +0,0 @@\n",
+    "-This is the file 'mu'.\n",
+    ] + make_git_diff_header("new", "revision 0", "revision 2", 
+                              add=True) + [
+    "@@ -0,0 +1 @@\n",
+    "+This is the file 'new'.\n",
+  ] +  make_git_diff_header("iota", "revision 1", 
+                            "revision 2") + [
+    "@@ -1 +1,2 @@\n",
+    " This is the file 'iota'.\n",
+    "+Changed 'iota'.\n",
+  ]
+
+  svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff', 
+                                     '--git-diff', 
+                                     '--old', repo_url + '@1', '--new',
+                                     repo_url + '@2')
+
 # Check ignoring mergeinfo in a diff
 def diff_ignore_mergeinfo(sbox):
   "svn diff --ignore-mergeinfo"
@@ -3103,88 +3368,6 @@ def diff_ignore_mergeinfo(sbox):
   svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff',
                                      '--ignore-mergeinfo')
 
-
-#----------------------------------------------------------------------
-# Diffing an unrelated repository URL against working copy with
-# local modifications (i.e. not committed). This is issue #3295 (diff
-# local changes against arbitrary URL@REV ignores local add).
-
-# Helper
-def make_file_edit_del_add(dir):
-  "make a file mod (M), a deletion (D) and an addition (A)."
-  alpha = os.path.join(dir, 'B', 'E', 'alpha')
-  beta = os.path.join(dir, 'B', 'E', 'beta')
-  theta = os.path.join(dir, 'B', 'E', 'theta')
-
-  # modify alpha, remove beta and add theta.
-  svntest.main.file_append(alpha, "Edited file alpha.\n")
-  svntest.main.run_svn(None, 'remove', beta)
-  svntest.main.file_append(theta, "Created file theta.\n")
-
-  svntest.main.run_svn(None, 'add', theta)
-
-
-def diff_url_against_local_mods(sbox):
-  "diff URL against working copy with local mods"
-
-  sbox.build()
-  os.chdir(sbox.wc_dir)
-
-  A = 'A'
-  A_url = sbox.repo_url + '/A'
-
-  # First, just make a copy.
-  A2 = 'A2'
-  A2_url = sbox.repo_url + '/A2'
-
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'cp', '-m', 'log msg',
-                                     A_url, A2_url)
-
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'up')
-
-  # In A, add, remove and change a file, and commit.
-  make_file_edit_del_add(A);
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'ci', '-m', 'committing A')
-
-  # In A2, do the same changes but leave uncommitted.
-  make_file_edit_del_add(A2);
-
-  # Diff URL of A against working copy of A2. Output should be empty.
-  expected_output = []
-  svntest.actions.run_and_verify_svn(None, expected_output, [],
-                                     'diff', '--old', A_url, '--new', A2)
-
-
-#----------------------------------------------------------------------
-# Diff rev against working copy of a removed and locally re-added file.
-# This is issue #1675 ("svn diff -rN added-file" has odd behavior).
-
-def diff_preexisting_rev_against_local_add(sbox):
-  "diff -r1 of removed file to its local addition"
-  sbox.build()
-  os.chdir(sbox.wc_dir)
-
-  beta = os.path.join('A', 'B', 'E', 'beta')
-
-  # remove
-  svntest.main.run_svn(None, 'remove', beta)
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'ci', '-m', 'removing beta')
-
-  # re-add, without committing
-  svntest.main.file_append(beta, "Re-created file beta.\n")
-  svntest.main.run_svn(None, 'add', beta)
-
-  # diff against -r1, the diff should show both removal and re-addition
-  exit_code, diff_output, err_output = svntest.main.run_svn(
-                        None, 'diff', '-r1', 'A')
-
-  verify_expected_output(diff_output, "-This is the file 'beta'.")
-  verify_expected_output(diff_output, "+Re-created file beta.")
-
 ########################################################################
 #Run the tests
 
@@ -3241,6 +3424,9 @@ test_list = [ None,
               diff_external_diffcmd,
               XFail(diff_url_against_local_mods),
               XFail(diff_preexisting_rev_against_local_add),
+              diff_git_format_wc_wc,
+              diff_git_format_url_wc,
+              diff_git_format_url_url,
               diff_ignore_mergeinfo,
               ]