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 2018/07/09 15:51:07 UTC

svn commit: r1835446 - in /subversion/trunk/subversion: include/private/svn_client_private.h libsvn_client/diff.c libsvn_client/shelf.c

Author: julianfoad
Date: Mon Jul  9 15:51:07 2018
New Revision: 1835446

URL: http://svn.apache.org/viewvc?rev=1835446&view=rev
Log:
Shelving: implement 'svn diff' on shelves.

'svn diff --cl=svn:shelf:SHELF' runs a diff on the shelf named SHELF.  This
is an alternative to the 'svn shelf-diff' command.  Most 'svn diff' options
are supported; --depth and --ignore-ancestry are not yet supported.

* subversion/include/private/svn_client_private.h,
  subversion/libsvn_client/shelf.c
  (svn_client__shelf_diff): Add depth and ignore-ancestry options (not yet
    supported). Constify the diff processor parameter.
  (file_changed, file_deleted, file_added, diff_baton_t): Adjust for that
    'const' change.

* subversion/libsvn_client/diff.c
  (diff_shelf, diff_shelves): New.
  (do_diff): Look for shelf diffs in the WC-WC diff case.

Modified:
    subversion/trunk/subversion/include/private/svn_client_private.h
    subversion/trunk/subversion/libsvn_client/diff.c
    subversion/trunk/subversion/libsvn_client/shelf.c

Modified: subversion/trunk/subversion/include/private/svn_client_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_client_private.h?rev=1835446&r1=1835445&r2=1835446&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_client_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_client_private.h Mon Jul  9 15:51:07 2018
@@ -376,6 +376,8 @@ svn_client__get_diff_writer_svn(
 /** Output the subtree of @a shelf_version rooted at @a shelf_relpath
  * as a diff to @a diff_processor.
  *
+ * ### depth and ignore_ancestry are currently ignored.
+ *
  * @since New in 1.X.
  * @warning EXPERIMENTAL.
  */
@@ -383,7 +385,9 @@ SVN_EXPERIMENTAL
 svn_error_t *
 svn_client__shelf_diff(svn_client_shelf_version_t *shelf_version,
                        const char *shelf_relpath,
-                       svn_diff_tree_processor_t *diff_processor,
+                       svn_depth_t depth,
+                       svn_boolean_t ignore_ancestry,
+                       const svn_diff_tree_processor_t *diff_processor,
                        apr_pool_t *scratch_pool);
 
 /*** Editor for diff summary ***/

Modified: subversion/trunk/subversion/libsvn_client/diff.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/diff.c?rev=1835446&r1=1835445&r2=1835446&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/diff.c (original)
+++ subversion/trunk/subversion/libsvn_client/diff.c Mon Jul  9 15:51:07 2018
@@ -23,6 +23,9 @@
 
 /* ==================================================================== */
 
+/* We define this here to remove any further warnings about the usage of
+   experimental functions in this file. */
+#define SVN_EXPERIMENTAL
 
 
 /*** Includes. ***/
@@ -2321,6 +2324,80 @@ diff_repos_wc(struct diff_driver_info_t
   return SVN_NO_ERROR;
 }
 
+/* Run diff on shelf SHELF_NAME, if it exists.
+ */
+static svn_error_t *
+diff_shelf(const char *shelf_name,
+           const char *target_abspath,
+           svn_depth_t depth,
+           svn_boolean_t ignore_ancestry,
+           const svn_diff_tree_processor_t *diff_processor,
+           svn_client_ctx_t *ctx,
+           apr_pool_t *scratch_pool)
+{
+  svn_error_t *err;
+  svn_client_shelf_t *shelf;
+  svn_client_shelf_version_t *shelf_version;
+  const char *wc_relpath;
+
+  err = svn_client_shelf_open_existing(&shelf,
+                                       shelf_name, target_abspath,
+                                       ctx, scratch_pool);
+  if (err && err->apr_err == SVN_ERR_ILLEGAL_TARGET)
+    {
+      svn_error_clear(err);
+      return SVN_NO_ERROR;
+    }
+  else
+    SVN_ERR(err);
+
+  SVN_ERR(svn_client_shelf_version_open(&shelf_version,
+                                        shelf, shelf->max_version,
+                                        scratch_pool, scratch_pool));
+  wc_relpath = svn_dirent_skip_ancestor(shelf->wc_root_abspath, target_abspath);
+  SVN_ERR(svn_client__shelf_diff(shelf_version, wc_relpath,
+                                 depth, ignore_ancestry,
+                                 diff_processor, scratch_pool));
+  SVN_ERR(svn_client_shelf_close(shelf, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+/* Run diff on all shelves named in CHANGELISTS by a changelist name
+ * of the form "svn:shelf:SHELF_NAME", if they exist.
+ */
+static svn_error_t *
+diff_shelves(const apr_array_header_t *changelists,
+             const char *target_abspath,
+             svn_depth_t depth,
+             svn_boolean_t ignore_ancestry,
+             const svn_diff_tree_processor_t *diff_processor,
+             svn_client_ctx_t *ctx,
+             apr_pool_t *scratch_pool)
+{
+  static const char PREFIX[] = "svn:shelf:";
+  static const int PREFIX_LEN = 10;
+  int i;
+
+  if (! changelists)
+    return SVN_NO_ERROR;
+  for (i = 0; i < changelists->nelts; i++)
+    {
+      const char *cl = APR_ARRAY_IDX(changelists, i, const char *);
+
+      if (strncmp(cl, PREFIX, PREFIX_LEN) == 0)
+        {
+          const char *shelf_name = cl + PREFIX_LEN;
+
+          SVN_ERR(diff_shelf(shelf_name, target_abspath,
+                             depth, ignore_ancestry,
+                             diff_processor, ctx, scratch_pool));
+        }
+    }
+
+  return SVN_NO_ERROR;
+}
+
 
 /* This is basically just the guts of svn_client_diff[_summarize][_peg]6(). */
 static svn_error_t *
@@ -2436,6 +2513,15 @@ do_diff(diff_driver_info_t *ddi,
                   ddi->orig_path_2 = path_or_url2;
                 }
 
+              {
+                const char *abspath1;
+
+                SVN_ERR(svn_dirent_get_absolute(&abspath1, path_or_url1,
+                                                scratch_pool));
+                SVN_ERR(diff_shelves(changelists, abspath1,
+                                     depth, ignore_ancestry,
+                                     diff_processor, ctx, scratch_pool));
+              }
               SVN_ERR(diff_wc_wc(path_or_url1, revision1,
                                  path_or_url2, revision2,
                                  depth, ignore_ancestry, changelists,

Modified: subversion/trunk/subversion/libsvn_client/shelf.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/shelf.c?rev=1835446&r1=1835445&r2=1835446&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/shelf.c (original)
+++ subversion/trunk/subversion/libsvn_client/shelf.c Mon Jul  9 15:51:07 2018
@@ -1623,7 +1623,7 @@ static svn_error_t *
 file_changed(svn_client_shelf_version_t *shelf_version,
              const char *relpath,
              svn_wc_status3_t *s,
-             svn_diff_tree_processor_t *diff_processor,
+             const svn_diff_tree_processor_t *diff_processor,
              svn_diff_source_t *left_source,
              svn_diff_source_t *right_source,
              const char *left_stored_abspath,
@@ -1666,7 +1666,7 @@ static svn_error_t *
 file_deleted(svn_client_shelf_version_t *shelf_version,
              const char *relpath,
              svn_wc_status3_t *s,
-             svn_diff_tree_processor_t *diff_processor,
+             const svn_diff_tree_processor_t *diff_processor,
              svn_diff_source_t *left_source,
              const char *left_stored_abspath,
              void *dir_baton,
@@ -1702,7 +1702,7 @@ static svn_error_t *
 file_added(svn_client_shelf_version_t *shelf_version,
            const char *relpath,
            svn_wc_status3_t *s,
-           svn_diff_tree_processor_t *diff_processor,
+           const svn_diff_tree_processor_t *diff_processor,
            svn_diff_source_t *right_source,
            const char *right_stored_abspath,
            void *dir_baton,
@@ -1739,7 +1739,7 @@ struct diff_baton_t
   svn_client_shelf_version_t *shelf_version;
   const char *top_relpath;  /* top of diff, relative to shelf */
   const char *walk_root_abspath;
-  svn_diff_tree_processor_t *diff_processor;
+  const svn_diff_tree_processor_t *diff_processor;
 };
 
 /* Drive BATON->diff_processor.
@@ -1915,7 +1915,9 @@ svn_client_shelf_delete_newer_versions(s
 svn_error_t *
 svn_client__shelf_diff(svn_client_shelf_version_t *shelf_version,
                        const char *shelf_relpath,
-                       svn_diff_tree_processor_t *diff_processor,
+                       svn_depth_t depth,
+                       svn_boolean_t ignore_ancestry,
+                       const svn_diff_tree_processor_t *diff_processor,
                        apr_pool_t *scratch_pool)
 {
   struct diff_baton_t baton;