You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by sb...@apache.org on 2010/08/16 14:36:14 UTC

svn commit: r985901 - in /subversion/trunk/subversion: libsvn_client/repos_diff_summarize.c tests/cmdline/diff_tests.py

Author: sbutler
Date: Mon Aug 16 12:36:13 2010
New Revision: 985901

URL: http://svn.apache.org/viewvc?rev=985901&view=rev
Log:
For diff --summarize, fix issue #2333 "svn diff URL1 URL2 != svn diff
URL2 URL1".  Similar to r983720, which fixed the normal diff command.

TODO: Respect the --depth option.

* subversion/libsvn_client/repos_diff_summarize.c:
  (edit_baton): Add boolean flag walk_deleted_repos_dirs.  Add a
   cancel_func and cancel_baton for the walk.
  (diff_deleted_dir): New function.
  (delete_entry): Use diff_deleted_dir() to walk a dir.
  (svn_client__get_diff_summarize_editor): Fill in the new baton fields.

* subversion/tests/cmdline/diff_tests.py:
  (basic_diff_summarize): Expect output for "deleted" trees.

Modified:
    subversion/trunk/subversion/libsvn_client/repos_diff_summarize.c
    subversion/trunk/subversion/tests/cmdline/diff_tests.py

Modified: subversion/trunk/subversion/libsvn_client/repos_diff_summarize.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/repos_diff_summarize.c?rev=985901&r1=985900&r2=985901&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/repos_diff_summarize.c (original)
+++ subversion/trunk/subversion/libsvn_client/repos_diff_summarize.c Mon Aug 16 12:36:13 2010
@@ -23,6 +23,7 @@
  */
 
 
+#include "svn_dirent_uri.h"
 #include "svn_props.h"
 #include "svn_pools.h"
 
@@ -45,6 +46,18 @@ struct edit_baton {
 
   /* The start revision for the comparison */
   svn_revnum_t revision;
+
+  /* TRUE if the operation needs to walk deleted dirs on the "old" side.
+     FALSE otherwise. */
+  svn_boolean_t walk_deleted_repos_dirs;
+
+  /* A callback used to see if the client wishes to cancel the running
+     operation. */
+  svn_cancel_func_t cancel_func;
+
+  /* A baton to pass to the cancellation callback. */
+  void *cancel_baton;
+
 };
 
 
@@ -129,6 +142,83 @@ open_root(void *edit_baton,
   return SVN_NO_ERROR;
 }
 
+/* Recursively walk the tree rooted at DIR (at REVISION) in the
+ * repository, reporting all files as deleted.  Part of a workaround
+ * for issue 2333.
+ *
+ * DIR is a repository path relative to the URL in RA_SESSION.  REVISION
+ * may be NULL, in which case it defaults to HEAD.  EDIT_BATON is the
+ * overall crawler editor baton.  If CANCEL_FUNC is not NULL, then it
+ * should refer to a cancellation function (along with CANCEL_BATON).
+ */
+/* ### TODO: Handle depth. */
+static svn_error_t *
+diff_deleted_dir(const char *dir,
+                 svn_revnum_t revision,
+                 svn_ra_session_t *ra_session,
+                 void *edit_baton,
+                 svn_cancel_func_t cancel_func,
+                 void *cancel_baton,
+                 apr_pool_t *pool)
+{
+  struct edit_baton *eb = edit_baton;
+  apr_hash_t *dirents;
+  apr_pool_t *iterpool = svn_pool_create(pool);
+  apr_hash_index_t *hi;
+
+  if (cancel_func)
+    SVN_ERR(cancel_func(cancel_baton));
+
+  SVN_ERR(svn_ra_get_dir2(ra_session,
+                          &dirents,
+                          NULL, NULL,
+                          dir,
+                          revision,
+                          SVN_DIRENT_KIND,
+                          pool));
+  
+  for (hi = apr_hash_first(pool, dirents); hi;
+       hi = apr_hash_next(hi))
+    {
+      const char *path;
+      const char *name = svn__apr_hash_index_key(hi);
+      svn_dirent_t *dirent = svn__apr_hash_index_val(hi);
+      svn_node_kind_t kind;
+      svn_client_diff_summarize_t *sum;
+
+      svn_pool_clear(iterpool);
+
+      path = svn_relpath_join(dir, name, iterpool);
+
+      SVN_ERR(svn_ra_check_path(eb->ra_session,
+                                path,
+                                eb->revision,
+                                &kind,
+                                iterpool));
+
+      sum = apr_pcalloc(pool, sizeof(*sum));
+      sum->summarize_kind = svn_client_diff_summarize_kind_deleted;
+      sum->path = path;
+      sum->node_kind = kind;
+
+      SVN_ERR(eb->summarize_func(sum,
+                                 eb->summarize_func_baton,
+                                 iterpool));
+
+      if (dirent->kind == svn_node_dir)
+        SVN_ERR(diff_deleted_dir(path,
+                                 revision,
+                                 ra_session,
+                                 eb,
+                                 cancel_func,
+                                 cancel_baton,
+                                 iterpool));
+    }
+
+  svn_pool_destroy(iterpool);
+  return SVN_NO_ERROR;
+}
+
 /* An editor function.  */
 static svn_error_t *
 delete_entry(const char *path,
@@ -153,7 +243,18 @@ delete_entry(const char *path,
   sum->path = path;
   sum->node_kind = kind;
 
-  return eb->summarize_func(sum, eb->summarize_func_baton, pool);
+  SVN_ERR(eb->summarize_func(sum, eb->summarize_func_baton, pool));
+
+  if (kind == svn_node_dir)
+        SVN_ERR(diff_deleted_dir(path,
+                                 eb->revision,
+                                 eb->ra_session,
+                                 eb,
+                                 eb->cancel_func,
+                                 eb->cancel_baton,
+                                 pool));
+
+  return SVN_NO_ERROR;
 }
 
 /* An editor function.  */
@@ -328,6 +429,9 @@ svn_client__get_diff_summarize_editor(co
   eb->summarize_func_baton = summarize_baton;
   eb->ra_session = ra_session;
   eb->revision = revision;
+  eb->walk_deleted_repos_dirs = TRUE;
+  eb->cancel_func = cancel_func;
+  eb->cancel_baton = cancel_baton;
 
   tree_editor->open_root = open_root;
   tree_editor->delete_entry = delete_entry;

Modified: subversion/trunk/subversion/tests/cmdline/diff_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/diff_tests.py?rev=985901&r1=985900&r2=985901&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/diff_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/diff_tests.py Mon Aug 16 12:36:13 2010
@@ -2651,9 +2651,9 @@ def basic_diff_summarize(sbox):
     'A/C':            Item(status='D '),
     'A/D/gamma':      Item(status='D '),
     'A/D/H':          Item(status='D '),
-#    'A/D/H/chi':      Item(status='D '),
-#    'A/D/H/psi':      Item(status='D '),
-#    'A/D/H/omega':    Item(status='D '),
+    'A/D/H/chi':      Item(status='D '),
+    'A/D/H/psi':      Item(status='D '),
+    'A/D/H/omega':    Item(status='D '),
     })
 
   expected_reverse_diff = svntest.wc.State(wc_dir, {
@@ -2664,9 +2664,9 @@ def basic_diff_summarize(sbox):
     'newfile2':       Item(status='D '),
     'P':              Item(status='D '),
     'Q':              Item(status='D '),
-#    'Q/newfile':      Item(status='D '),
-#    'Q/R':            Item(status='D '),
-#    'Q/R/newfile':    Item(status='D '),
+    'Q/newfile':      Item(status='D '),
+    'Q/R':            Item(status='D '),
+    'Q/R/newfile':    Item(status='D '),
     'A/B/lambda':     Item(status='A '),
     'A/C':            Item(status='A '),
     'A/D/gamma':      Item(status='A '),