subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhuij...@apache.org
Subject svn commit: r1444537 - in /subversion/trunk/subversion: include/private/svn_diff_tree.h libsvn_diff/diff_tree.c libsvn_wc/diff_editor.c
Date Sun, 10 Feb 2013 12:54:45 GMT
Author: rhuijben
Date: Sun Feb 10 12:54:44 2013
New Revision: 1444537

URL: http://svn.apache.org/r1444537
Log:
In the repos-wc diff, hook a svn diff processor filter that can transform
copies to changes, just like we currently do when not using 'show copies as
adds'

Eventually this handling should be moved to the output processing to show
that a file is added *and* its modifications.

* subversion/include/private/svn_diff_tree.h
  (svn_diff__tree_processor_copy_as_changed_create): New function.

* subversion/libsvn_diff/diff_tree.c
  (svn_diff__tree_processor_filter_create): Rename baton variable.
  (copy_as_changed_baton_t): New struct.
  (copy_as_changed_*): New functions.
  (svn_diff__tree_processor_copy_as_changed_create): New function.

* subversion/libsvn_wc/diff_editor.c
  (includes): Add assert.h.
  (make_edit_baton): Hook copy_as_changed transform.

  (file_diff,
   close_file): Use original_repos_relpath as trigger for added file
    is some kind of copy as that makes more sense to the rest of the
    code and avoids a db call.

Modified:
    subversion/trunk/subversion/include/private/svn_diff_tree.h
    subversion/trunk/subversion/libsvn_diff/diff_tree.c
    subversion/trunk/subversion/libsvn_wc/diff_editor.c

Modified: subversion/trunk/subversion/include/private/svn_diff_tree.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_diff_tree.h?rev=1444537&r1=1444536&r2=1444537&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_diff_tree.h (original)
+++ subversion/trunk/subversion/include/private/svn_diff_tree.h Sun Feb 10 12:54:44 2013
@@ -235,7 +235,7 @@ svn_diff__tree_processor_reverse_create(
 
 /**
  * Create a new svn_diff_tree_processor_t instance with all functions setup
- * to first call into processor for all paths equal to and below prefix_relpath.
+ * to call into processor for all paths equal to and below prefix_relpath.
  *
  * @since New in 1.8.
  */ /* Used by libsvn clients repository diff */
@@ -244,6 +244,18 @@ svn_diff__tree_processor_filter_create(c
                                        const char *prefix_relpath,
                                        apr_pool_t *result_pool);
 
+/**
+ * Create a new svn_diff_tree_processor_t instace with all function setup
+ * to call into processor with all adds with copyfrom information transformed
+ * to simple node changes.
+ *
+ * @since New in 1.8.
+ */ /* Used by libsvn_wc diff editor */
+const svn_diff_tree_processor_t *
+svn_diff__tree_processor_copy_as_changed_create(
+                                const svn_diff_tree_processor_t *processor,
+                                apr_pool_t *result_pool);
+
 
 /**
  * Create a new svn_diff_tree_processor_t instance with all functions setup

Modified: subversion/trunk/subversion/libsvn_diff/diff_tree.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_diff/diff_tree.c?rev=1444537&r1=1444536&r2=1444537&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_diff/diff_tree.c (original)
+++ subversion/trunk/subversion/libsvn_diff/diff_tree.c Sun Feb 10 12:54:44 2013
@@ -889,15 +889,15 @@ svn_diff__tree_processor_filter_create(c
                                         const char *prefix_relpath,
                                         apr_pool_t *result_pool)
 {
-  struct filter_tree_baton_t *rb;
+  struct filter_tree_baton_t *fb;
   svn_diff_tree_processor_t *filter;
 
-  rb = apr_pcalloc(result_pool, sizeof(*rb));
-  rb->processor = processor;
+  fb = apr_pcalloc(result_pool, sizeof(*fb));
+  fb->processor = processor;
   if (prefix_relpath)
-    rb->prefix_relpath = apr_pstrdup(result_pool, prefix_relpath);
+    fb->prefix_relpath = apr_pstrdup(result_pool, prefix_relpath);
 
-  filter = svn_diff__tree_processor_create(rb, result_pool);
+  filter = svn_diff__tree_processor_create(fb, result_pool);
 
   filter->dir_opened   = filter_dir_opened;
   filter->dir_added    = filter_dir_added;
@@ -916,6 +916,352 @@ svn_diff__tree_processor_filter_create(c
   return filter;
 }
 
+struct copy_as_changed_baton_t
+{
+  const svn_diff_tree_processor_t *processor;
+};
+
+static svn_error_t *
+copy_as_changed_dir_opened(void **new_dir_baton,
+                           svn_boolean_t *skip,
+                           svn_boolean_t *skip_children,
+                           const char *relpath,
+                           const svn_diff_source_t *left_source,
+                           const svn_diff_source_t *right_source,
+                           const svn_diff_source_t *copyfrom_source,
+                           void *parent_dir_baton,
+                           const svn_diff_tree_processor_t *processor,
+                           apr_pool_t *result_pool,
+                           apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  if (!left_source && copyfrom_source)
+    {
+      assert(right_source != NULL);
+
+      left_source = copyfrom_source;
+      copyfrom_source = NULL;
+    }
+
+  SVN_ERR(cb->processor->dir_opened(new_dir_baton, skip, skip_children,
+                                    relpath,
+                                    left_source, right_source,
+                                    copyfrom_source,
+                                    parent_dir_baton,
+                                    cb->processor,
+                                    result_pool, scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_as_changed_dir_added(const char *relpath,
+                          const svn_diff_source_t *copyfrom_source,
+                          const svn_diff_source_t *right_source,
+                          /*const*/ apr_hash_t *copyfrom_props,
+                          /*const*/ apr_hash_t *right_props,
+                          void *dir_baton,
+                          const svn_diff_tree_processor_t *processor,
+                          apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  if (copyfrom_source)
+    {
+      apr_array_header_t *propchanges;
+      SVN_ERR(svn_prop_diffs(&propchanges, right_props, copyfrom_props,
+                             scratch_pool));
+      SVN_ERR(cb->processor->dir_changed(relpath,
+                                         copyfrom_source,
+                                         right_source,
+                                         copyfrom_props,
+                                         right_props,
+                                         propchanges,
+                                         dir_baton,
+                                         cb->processor,
+                                         scratch_pool));
+    }
+  else
+    {
+      SVN_ERR(cb->processor->dir_added(relpath,
+                                       copyfrom_source,
+                                       right_source,
+                                       copyfrom_props,
+                                       right_props,
+                                       dir_baton,
+                                       cb->processor,
+                                       scratch_pool));
+    }
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_as_changed_dir_deleted(const char *relpath,
+                            const svn_diff_source_t *left_source,
+                            /*const*/ apr_hash_t *left_props,
+                            void *dir_baton,
+                            const svn_diff_tree_processor_t *processor,
+                            apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  SVN_ERR(cb->processor->dir_deleted(relpath,
+                                     left_source,
+                                     left_props,
+                                     dir_baton,
+                                     cb->processor,
+                                     scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_as_changed_dir_changed(const char *relpath,
+                            const svn_diff_source_t *left_source,
+                            const svn_diff_source_t *right_source,
+                            /*const*/ apr_hash_t *left_props,
+                            /*const*/ apr_hash_t *right_props,
+                            const apr_array_header_t *prop_changes,
+                            void *dir_baton,
+                            const struct svn_diff_tree_processor_t *processor,
+                            apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  SVN_ERR(cb->processor->dir_changed(relpath,
+                                     left_source,
+                                     right_source,
+                                     left_props,
+                                     right_props,
+                                     prop_changes,
+                                     dir_baton,
+                                     cb->processor,
+                                     scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_as_changed_dir_closed(const char *relpath,
+                           const svn_diff_source_t *left_source,
+                           const svn_diff_source_t *right_source,
+                           void *dir_baton,
+                           const svn_diff_tree_processor_t *processor,
+                           apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  SVN_ERR(cb->processor->dir_closed(relpath,
+                                    left_source,
+                                    right_source,
+                                    dir_baton,
+                                    cb->processor,
+                                    scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_as_changed_file_opened(void **new_file_baton,
+                            svn_boolean_t *skip,
+                            const char *relpath,
+                            const svn_diff_source_t *left_source,
+                            const svn_diff_source_t *right_source,
+                            const svn_diff_source_t *copyfrom_source,
+                            void *dir_baton,
+                            const svn_diff_tree_processor_t *processor,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  if (!left_source && copyfrom_source)
+    {
+      assert(right_source != NULL);
+
+      left_source = copyfrom_source;
+      copyfrom_source = NULL;
+    }
+
+  SVN_ERR(cb->processor->file_opened(new_file_baton,
+                                     skip,
+                                     relpath,
+                                     left_source,
+                                     right_source,
+                                     copyfrom_source,
+                                     dir_baton,
+                                     cb->processor,
+                                     result_pool,
+                                     scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_as_changed_file_added(const char *relpath,
+                           const svn_diff_source_t *copyfrom_source,
+                           const svn_diff_source_t *right_source,
+                           const char *copyfrom_file,
+                           const char *right_file,
+                           /*const*/ apr_hash_t *copyfrom_props,
+                           /*const*/ apr_hash_t *right_props,
+                           void *file_baton,
+                           const svn_diff_tree_processor_t *processor,
+                           apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  if (copyfrom_source)
+    {
+      apr_array_header_t *propchanges;
+      SVN_ERR(svn_prop_diffs(&propchanges, right_props, copyfrom_props,
+                             scratch_pool));
+
+      SVN_ERR(cb->processor->file_changed(relpath,
+                                          copyfrom_source,
+                                          right_source,
+                                          copyfrom_file,
+                                          right_file,
+                                          copyfrom_props,
+                                          right_props,
+                                          copyfrom_file && right_file,
+                                          propchanges,
+                                          file_baton,
+                                          cb->processor,
+                                          scratch_pool));
+    }
+  else
+    {
+      SVN_ERR(cb->processor->file_added(relpath,
+                                        copyfrom_source,
+                                        right_source,
+                                        copyfrom_file,
+                                        right_file,
+                                        copyfrom_props,
+                                        right_props,
+                                        file_baton,
+                                        cb->processor,
+                                        scratch_pool));
+    }
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_as_changed_file_deleted(const char *relpath,
+                             const svn_diff_source_t *left_source,
+                             const char *left_file,
+                             /*const*/ apr_hash_t *left_props,
+                             void *file_baton,
+                             const svn_diff_tree_processor_t *processor,
+                             apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  SVN_ERR(cb->processor->file_deleted(relpath,
+                                      left_source,
+                                      left_file,
+                                      left_props,
+                                      file_baton,
+                                      cb->processor,
+                                      scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_as_changed_file_changed(const char *relpath,
+                             const svn_diff_source_t *left_source,
+                             const svn_diff_source_t *right_source,
+                             const char *left_file,
+                             const char *right_file,
+                             /*const*/ apr_hash_t *left_props,
+                             /*const*/ apr_hash_t *right_props,
+                             svn_boolean_t file_modified,
+                             const apr_array_header_t *prop_changes,
+                             void *file_baton,
+                             const svn_diff_tree_processor_t *processor,
+                             apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  SVN_ERR(cb->processor->file_changed(relpath,
+                                      left_source,
+                                      right_source,
+                                      left_file,
+                                      right_file,
+                                      left_props,
+                                      right_props,
+                                      file_modified,
+                                      prop_changes,
+                                      file_baton,
+                                      cb->processor,
+                                      scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_as_changed_file_closed(const char *relpath,
+                            const svn_diff_source_t *left_source,
+                            const svn_diff_source_t *right_source,
+                            void *file_baton,
+                            const svn_diff_tree_processor_t *processor,
+                            apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  SVN_ERR(cb->processor->file_closed(relpath,
+                                     left_source,
+                                     right_source,
+                                     file_baton,
+                                     cb->processor,
+                                     scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_as_changed_node_absent(const char *relpath,
+                            void *dir_baton,
+                            const svn_diff_tree_processor_t *processor,
+                            apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  SVN_ERR(cb->processor->node_absent(relpath,
+                                    dir_baton,
+                                    cb->processor,
+                                    scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+
+const svn_diff_tree_processor_t *
+svn_diff__tree_processor_copy_as_changed_create(
+                        const svn_diff_tree_processor_t * processor,
+                        apr_pool_t *result_pool)
+{
+  struct copy_as_changed_baton_t *cb;
+  svn_diff_tree_processor_t *filter;
+
+  cb = apr_pcalloc(result_pool, sizeof(*cb));
+  cb->processor = processor;
+
+  filter = svn_diff__tree_processor_create(cb, result_pool);
+  filter->dir_opened   = copy_as_changed_dir_opened;
+  filter->dir_added    = copy_as_changed_dir_added;
+  filter->dir_deleted  = copy_as_changed_dir_deleted;
+  filter->dir_changed  = copy_as_changed_dir_changed;
+  filter->dir_closed   = copy_as_changed_dir_closed;
+
+  filter->file_opened   = copy_as_changed_file_opened;
+  filter->file_added    = copy_as_changed_file_added;
+  filter->file_deleted  = copy_as_changed_file_deleted;
+  filter->file_changed  = copy_as_changed_file_changed;
+  filter->file_closed   = copy_as_changed_file_closed;
+
+  filter->node_absent   = copy_as_changed_node_absent;
+
+  return filter;
+}
+
 
 /* Processor baton for the tee tree processor */
 struct tee_baton_t

Modified: subversion/trunk/subversion/libsvn_wc/diff_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/diff_editor.c?rev=1444537&r1=1444536&r2=1444537&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/diff_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/diff_editor.c Sun Feb 10 12:54:44 2013
@@ -55,6 +55,8 @@
 #include <apr_hash.h>
 #include <apr_md5.h>
 
+#include <assert.h>
+
 #include "svn_error.h"
 #include "svn_pools.h"
 #include "svn_dirent_uri.h"
@@ -404,6 +406,10 @@ make_edit_baton(struct edit_baton **edit
   if (reverse_order)
     processor = svn_diff__tree_processor_reverse_create(processor, NULL, pool);
 
+  if (! show_copies_as_adds)
+    processor = svn_diff__tree_processor_copy_as_changed_create(processor,
+                                                                pool);
+
   eb = apr_pcalloc(pool, sizeof(*eb));
   eb->db = db;
   eb->anchor_abspath = apr_pstrdup(pool, anchor_abspath);
@@ -572,6 +578,7 @@ file_diff(struct edit_baton *eb,
   const char *empty_file;
   svn_boolean_t replaced;
   svn_wc__db_status_t status;
+  svn_revnum_t original_revision;
   const char *original_repos_relpath;
   svn_revnum_t revision;
   svn_revnum_t revert_base_revnum;
@@ -589,8 +596,9 @@ file_diff(struct edit_baton *eb,
 
   SVN_ERR(svn_wc__db_read_info(&status, NULL, &revision, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL,
-                               &original_repos_relpath, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               &original_repos_relpath, NULL, NULL,
+                               &original_revision, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL,
                                NULL, &have_base, NULL, NULL,
                                db, local_abspath, scratch_pool, scratch_pool));
   if (have_base)
@@ -604,14 +612,6 @@ file_diff(struct edit_baton *eb,
               && have_base
               && base_status != svn_wc__db_status_not_present);
 
-  /* Now refine ADDED to one of: ADDED, COPIED, MOVED_HERE. Note that only
-     the latter two have corresponding pristine info to diff against.  */
-  if (status == svn_wc__db_status_added)
-    SVN_ERR(svn_wc__db_scan_addition(&status, NULL, NULL, NULL, NULL,
-                                     NULL, NULL, NULL,
-                                     NULL, NULL, NULL, db, local_abspath,
-                                     scratch_pool, scratch_pool));
-
   /* A wc-wc diff of replaced files actually shows a diff against the
    * revert-base, showing all previous lines as removed and adding all new
    * lines. This does not happen for copied/moved-here files, not even with
@@ -619,8 +619,7 @@ file_diff(struct edit_baton *eb,
    * an add, diffing against the empty file).
    * So show the revert-base revision for plain replaces. */
   if (replaced
-      && ! (status == svn_wc__db_status_copied
-            || status == svn_wc__db_status_moved_here))
+      && ! original_repos_relpath)
     {
       use_base = TRUE;
       revision = revert_base_revnum;
@@ -690,11 +689,11 @@ file_diff(struct edit_baton *eb,
   * diff, and the file was copied, we need to report the file as added and
   * diff it against the text base, so that a "copied" git diff header, and
   * possibly a diff against the copy source, will be generated for it. */
-  if ((! replaced && status == svn_wc__db_status_added) ||
-     (replaced && ! eb->ignore_ancestry) ||
-     ((status == svn_wc__db_status_copied ||
-       status == svn_wc__db_status_moved_here) &&
-         (eb->show_copies_as_adds || eb->use_git_diff_format)))
+  if ((! replaced && status == svn_wc__db_status_added
+                  && !original_repos_relpath)
+      || (replaced && ! eb->ignore_ancestry)
+      || (original_repos_relpath
+          && (eb->show_copies_as_adds || eb->use_git_diff_format)))
     {
       void *file_baton = NULL;
       svn_boolean_t skip = FALSE;
@@ -1752,6 +1751,8 @@ close_file(void *file_baton,
   apr_pool_t *scratch_pool = fb->pool;
   svn_wc__db_status_t status;
   const char *empty_file;
+  const char *original_repos_relpath;
+  svn_revnum_t original_revision;
   svn_error_t *err;
 
   /* The BASE information */
@@ -1800,9 +1801,10 @@ close_file(void *file_baton,
     }
 
   err = svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, &pristine_checksum, NULL, NULL,
-                             NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, &had_props, &props_mod,
+                             NULL, NULL, NULL, &pristine_checksum, NULL,
+                             &original_repos_relpath,
+                             NULL, NULL, &original_revision, NULL, NULL, NULL,
+                             NULL, NULL, NULL, &had_props, &props_mod,
                              NULL, NULL, NULL,
                              db, fb->local_abspath,
                              scratch_pool, scratch_pool);
@@ -1814,6 +1816,8 @@ close_file(void *file_baton,
       pristine_checksum = NULL;
       had_props = FALSE;
       props_mod = FALSE;
+      original_repos_relpath = NULL;
+      original_revision = SVN_INVALID_REVNUM;
     }
   else
     SVN_ERR(err);
@@ -1894,16 +1898,9 @@ close_file(void *file_baton,
       return SVN_NO_ERROR;
     }
 
-  if (status == svn_wc__db_status_added)
-    SVN_ERR(svn_wc__db_scan_addition(&status, NULL, NULL, NULL, NULL, NULL,
-                                     NULL, NULL, NULL, NULL, NULL, eb->db,
-                                     fb->local_abspath,
-                                     scratch_pool, scratch_pool));
-
   /* If the file was locally added with history, and we want to show copies
    * as added, diff the file with the empty file. */
-  if ((status == svn_wc__db_status_copied ||
-       status == svn_wc__db_status_moved_here) && eb->show_copies_as_adds)
+  if (original_repos_relpath && eb->show_copies_as_adds)
     {
       svn_boolean_t skip = FALSE;
 



Mime
View raw message