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

svn commit: r989810 - in /subversion/trunk: notes/bar subversion/include/svn_wc.h subversion/libsvn_client/diff.c subversion/libsvn_wc/deprecated.c subversion/libsvn_wc/diff.c

Author: stsp
Date: Thu Aug 26 16:31:50 2010
New Revision: 989810

URL: http://svn.apache.org/viewvc?rev=989810&view=rev
Log:
Make copies show up correctly in the output of svn diff --git.

We used to show nothing for copies unless --show-copies-as-adds was specified.
But with git diffs, we need to show the 'copy from/copy to' headers.
The libsvn_wc diff code needs to know whether we're doing a git diff,
so that it can drive the callbacks in the libsvn_client diff code correctly.

* subversion/include/svn_wc.h
  (svn_wc_get_diff_editor6, svn_wc_diff6): New parameter use_git_diff_format.
  (svn_wc_get_diff_editor5, svn_wc_diff5): Update docstrings.

* subversion/libsvn_wc/diff.c
  (edit_baton, make_edit_baton): New member/parameter use_git_diff_format.
  (file_diff): When producing a git diff, call the file_added callback for
   copies which have not been modified. We diff them against the text base,
   so the content diff will be empty -- but the file_added callback will
   also cause git diff headers to be printed.
  (svn_wc_get_diff_editor6, svn_wc_diff6): New parameter use_git_diff_format,
   passed on to make_edit_baton().

* subversion/libsvn_wc/deprecated.c
  (svn_wc_get_diff_editor5, svn_wc_diff5): Make compatiblity wrappers set
   the new use_git_diff_format parameter to FALSE.

* subversion/libsvn_client/diff.c
  (diff_content_changed): Always print the Index: header when a git diff
   header is printed, even if the content diff is empty.
  (diff_parameters): New member use_git_diff_format.
  (diff_wc_wc, diff_repos_wc, do_diff, svn_client_diff5): Handle the new
   diff_parameters member.

Added:
    subversion/trunk/notes/bar
      - copied unchanged from r989640, subversion/trunk/notes/fs_dumprestore.txt
Modified:
    subversion/trunk/subversion/include/svn_wc.h
    subversion/trunk/subversion/libsvn_client/diff.c
    subversion/trunk/subversion/libsvn_wc/deprecated.c
    subversion/trunk/subversion/libsvn_wc/diff.c

Modified: subversion/trunk/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_wc.h?rev=989810&r1=989809&r2=989810&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_wc.h (original)
+++ subversion/trunk/subversion/include/svn_wc.h Thu Aug 26 16:31:50 2010
@@ -5963,6 +5963,10 @@ svn_wc_canonicalize_svn_prop(const svn_s
  * appear as a diff against their copy source, or whether such paths will
  * appear as if they were newly added in their entirety.
  *
+ * If @a use_git_diff_format is TRUE, copied paths will be treated as added
+ * if they weren't modified after being copied. This allows the callbacks
+ * to generate appropriate --git diff headers for such files.
+ *
  * If @a use_text_base is TRUE, then compare the repository against
  * the working copy's text-base files, rather than the working files.
  *
@@ -5991,6 +5995,7 @@ svn_wc_get_diff_editor6(const svn_delta_
                         svn_depth_t depth,
                         svn_boolean_t ignore_ancestry,
                         svn_boolean_t show_copies_as_adds,
+                        svn_boolean_t use_git_diff_format,
                         svn_boolean_t use_text_base,
                         svn_boolean_t reverse_order,
                         const apr_array_header_t *changelists,
@@ -6002,7 +6007,7 @@ svn_wc_get_diff_editor6(const svn_delta_
 /**
  * Similar to svn_wc_get_diff_editor6(), but with an
  * #svn_wc_diff_callbacks3_t instead of #svn_wc_diff_callbacks4_t,
- * and @a show_copies_as_adds set to @c FALSE.
+ * @a show_copies_as_adds, and @a use_git_diff_format set to @c FALSE.
  *
  * @since New in 1.6.
  *
@@ -6144,6 +6149,10 @@ svn_wc_get_diff_editor(svn_wc_adm_access
  * appear as a diff against their copy source, or whether such paths will
  * appear as if they were newly added in their entirety.
  *
+ * If @a use_git_diff_format is TRUE, copied paths will be treated as added
+ * if they weren't modified after being copied. This allows the callbacks
+ * to generate appropriate --git diff headers for such files.
+ *
  * @a changelists is an array of <tt>const char *</tt> changelist
  * names, used as a restrictive filter on items whose differences are
  * reported; that is, don't generate diffs about any item unless
@@ -6164,6 +6173,7 @@ svn_wc_diff6(svn_wc_context_t *wc_ctx,
              svn_depth_t depth,
              svn_boolean_t ignore_ancestry,
              svn_boolean_t show_copies_as_adds,
+             svn_boolean_t use_git_diff_format,
              const apr_array_header_t *changelists,
              svn_cancel_func_t cancel_func,
              void *cancel_baton,
@@ -6171,8 +6181,9 @@ svn_wc_diff6(svn_wc_context_t *wc_ctx,
 
 /**
  * Similar to svn_wc_diff6(), but with a #svn_wc_diff_callbacks3_t argument
- * instead of #svn_wc_diff_callbacks4_t, and @a show_copies_as_adds set to
- * @c FALSE. It also doesn't allow specifying a cancel function.
+ * instead of #svn_wc_diff_callbacks4_t, @a show_copies_as_adds,
+ * and @a use_git_diff_format set to * @c FALSE.
+ * It also doesn't allow specifying a cancel function.
  *
  * @since New in 1.6.
  *

Modified: subversion/trunk/subversion/libsvn_client/diff.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/diff.c?rev=989810&r1=989809&r2=989810&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/diff.c (original)
+++ subversion/trunk/subversion/libsvn_client/diff.c Thu Aug 26 16:31:50 2010
@@ -773,7 +773,8 @@ diff_content_changed(const char *path,
                                    diff_cmd_baton->options.for_internal,
                                    subpool));
 
-      if (svn_diff_contains_diffs(diff) || diff_cmd_baton->force_empty)
+      if (svn_diff_contains_diffs(diff) || diff_cmd_baton->force_empty ||
+          diff_cmd_baton->use_git_diff_format)
         {
           /* Print out the diff header. */
           SVN_ERR(svn_stream_printf_from_utf8
@@ -846,11 +847,12 @@ diff_content_changed(const char *path,
           }
 
           /* Output the actual diff */
-          SVN_ERR(svn_diff_file_output_unified3
-                  (os, diff, tmpfile1, tmpfile2, label1, label2,
-                   diff_cmd_baton->header_encoding, rel_to_dir,
-                   diff_cmd_baton->options.for_internal->show_c_function,
-                   subpool));
+          if (svn_diff_contains_diffs(diff) || diff_cmd_baton->force_empty)
+            SVN_ERR(svn_diff_file_output_unified3
+                    (os, diff, tmpfile1, tmpfile2, label1, label2,
+                     diff_cmd_baton->header_encoding, rel_to_dir,
+                     diff_cmd_baton->options.for_internal->show_c_function,
+                     subpool));
 
           /* We have a printed a diff for this path, mark it as visited. */
           apr_hash_set(diff_cmd_baton->visited_paths, path,
@@ -1200,6 +1202,9 @@ struct diff_parameters
   /* Don't follow copyfrom when diffing copies. */
   svn_boolean_t show_copies_as_adds;
 
+  /* Are we producing a git-style diff? */
+  svn_boolean_t use_git_diff_format;
+
   /* Changelists of interest */
   const apr_array_header_t *changelists;
 };
@@ -1461,6 +1466,7 @@ diff_wc_wc(const char *path1,
            svn_depth_t depth,
            svn_boolean_t ignore_ancestry,
            svn_boolean_t show_copies_as_adds,
+           svn_boolean_t use_git_diff_format,
            const apr_array_header_t *changelists,
            const svn_wc_diff_callbacks4_t *callbacks,
            struct diff_cmd_baton *callback_baton,
@@ -1509,9 +1515,8 @@ diff_wc_wc(const char *path1,
                        path1,
                        callbacks, callback_baton,
                        depth,
-                       ignore_ancestry,
-                       show_copies_as_adds,
-                       changelists,
+                       ignore_ancestry, show_copies_as_adds,
+                       use_git_diff_format, changelists,
                        ctx->cancel_func, ctx->cancel_baton,
                        pool));
   return SVN_NO_ERROR;
@@ -1607,6 +1612,7 @@ diff_repos_wc(const char *path1,
               svn_depth_t depth,
               svn_boolean_t ignore_ancestry,
               svn_boolean_t show_copies_as_adds,
+              svn_boolean_t use_git_diff_format,
               const apr_array_header_t *changelists,
               const svn_wc_diff_callbacks4_t *callbacks,
               struct diff_cmd_baton *callback_baton,
@@ -1692,6 +1698,7 @@ diff_repos_wc(const char *path1,
                                   depth,
                                   ignore_ancestry,
                                   show_copies_as_adds,
+                                  use_git_diff_format,
                                   rev2_is_base,
                                   reverse,
                                   changelists,
@@ -1761,6 +1768,7 @@ do_diff(const struct diff_parameters *di
                                 FALSE, diff_param->depth,
                                 diff_param->ignore_ancestry,
                                 diff_param->show_copies_as_adds,
+                                diff_param->use_git_diff_format,
                                 diff_param->changelists,
                                 callbacks, callback_baton, ctx, pool));
         }
@@ -1775,6 +1783,7 @@ do_diff(const struct diff_parameters *di
                                 TRUE, diff_param->depth,
                                 diff_param->ignore_ancestry,
                                 diff_param->show_copies_as_adds,
+                                diff_param->use_git_diff_format,
                                 diff_param->changelists,
                                 callbacks, callback_baton, ctx, pool));
         }
@@ -1785,6 +1794,7 @@ do_diff(const struct diff_parameters *di
                              diff_param->depth,
                              diff_param->ignore_ancestry,
                              diff_param->show_copies_as_adds,
+                             diff_param->use_git_diff_format,
                              diff_param->changelists,
                              callbacks, callback_baton, ctx, pool));
         }
@@ -2003,6 +2013,7 @@ svn_client_diff5(const apr_array_header_
   diff_params.ignore_ancestry = ignore_ancestry;
   diff_params.no_diff_deleted = no_diff_deleted;
   diff_params.show_copies_as_adds = show_copies_as_adds;
+  diff_params.use_git_diff_format = use_git_diff_format;
   diff_params.changelists = changelists;
 
   /* setup callback and baton */

Modified: subversion/trunk/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/deprecated.c?rev=989810&r1=989809&r2=989810&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_wc/deprecated.c Thu Aug 26 16:31:50 2010
@@ -1789,6 +1789,7 @@ svn_wc_get_diff_editor5(svn_wc_adm_acces
                                    depth,
                                    ignore_ancestry,
                                    FALSE,
+                                   FALSE,
                                    use_text_base,
                                    reverse_order,
                                    changelists,
@@ -1940,6 +1941,7 @@ svn_wc_diff5(svn_wc_adm_access_t *anchor
                        depth,
                        ignore_ancestry,
                        FALSE,
+                       FALSE,
                        changelists,
                        NULL, NULL,
                        pool));

Modified: subversion/trunk/subversion/libsvn_wc/diff.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/diff.c?rev=989810&r1=989809&r2=989810&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/diff.c (original)
+++ subversion/trunk/subversion/libsvn_wc/diff.c Thu Aug 26 16:31:50 2010
@@ -227,6 +227,9 @@ struct edit_baton {
   /* Should this diff not compare copied files with their source? */
   svn_boolean_t show_copies_as_adds;
 
+  /* Are we producing a git-style diff? */
+  svn_boolean_t use_git_diff_format;
+
   /* Possibly diff repos against text-bases instead of working files. */
   svn_boolean_t use_text_base;
 
@@ -350,6 +353,7 @@ make_edit_baton(struct edit_baton **edit
                 svn_depth_t depth,
                 svn_boolean_t ignore_ancestry,
                 svn_boolean_t show_copies_as_adds,
+                svn_boolean_t use_git_diff_format,
                 svn_boolean_t use_text_base,
                 svn_boolean_t reverse_order,
                 const apr_array_header_t *changelists,
@@ -373,6 +377,7 @@ make_edit_baton(struct edit_baton **edit
   eb->depth = depth;
   eb->ignore_ancestry = ignore_ancestry;
   eb->show_copies_as_adds = show_copies_as_adds;
+  eb->use_git_diff_format = use_git_diff_format;
   eb->use_text_base = use_text_base;
   eb->reverse_order = reverse_order;
   eb->changelist_hash = changelist_hash;
@@ -562,6 +567,7 @@ file_diff(struct dir_baton *db,
   svn_boolean_t have_base;
   svn_wc__db_status_t base_status;
   const char *local_abspath;
+  svn_boolean_t modified;
 
   SVN_ERR_ASSERT(! eb->use_text_base);
 
@@ -656,15 +662,23 @@ file_diff(struct dir_baton *db,
         }
     }
 
+  SVN_ERR(svn_wc__internal_text_modified_p(&modified, eb->db,
+                                           local_abspath, FALSE, TRUE,
+                                           pool));
+
  /* Now deal with showing additions, or the add-half of replacements.
   * If the item is schedule-add *with history*, then we usually want
   * to see the usual working vs. text-base comparison, which will show changes
   * made since the file was copied.  But in case we're showing copies as adds,
-  * we need to compare the copied file to the empty file. */
+  * we need to compare the copied file to the empty file. If we're doing a git
+  * diff, and the file was copied but not modified, we need to report the file
+  * as added and diff it against the text base (empty diff), so that a "copied"
+  * git diff header can 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))
+       status == svn_wc__db_status_moved_here) &&
+         (eb->show_copies_as_adds || (eb->use_git_diff_format && ! modified))))
     {
       const char *translated = NULL;
       const char *working_mimetype;
@@ -689,7 +703,9 @@ file_diff(struct dir_baton *db,
               pool, pool));
 
       SVN_ERR(eb->callbacks->file_added(NULL, NULL, NULL, NULL, path,
-                                        empty_file,
+                                        (! eb->show_copies_as_adds &&
+                                         eb->use_git_diff_format &&
+                                         ! modified) ? textbase : empty_file,
                                         translated,
                                         0, revision,
                                         NULL,
@@ -701,7 +717,6 @@ file_diff(struct dir_baton *db,
     }
   else
     {
-      svn_boolean_t modified;
       const char *translated = NULL;
       apr_hash_t *baseprops;
       const char *base_mimetype;
@@ -711,9 +726,6 @@ file_diff(struct dir_baton *db,
 
       /* Here we deal with showing pure modifications. */
 
-      SVN_ERR(svn_wc__internal_text_modified_p(&modified, eb->db,
-                                               local_abspath, FALSE, TRUE,
-                                               pool));
       if (modified)
         {
           /* Note that this might be the _second_ time we translate
@@ -1817,6 +1829,7 @@ svn_wc_get_diff_editor6(const svn_delta_
                         svn_depth_t depth,
                         svn_boolean_t ignore_ancestry,
                         svn_boolean_t show_copies_as_adds,
+                        svn_boolean_t use_git_diff_format,
                         svn_boolean_t use_text_base,
                         svn_boolean_t reverse_order,
                         const apr_array_header_t *changelists,
@@ -1836,6 +1849,7 @@ svn_wc_get_diff_editor6(const svn_delta_
                           anchor_path, target,
                           callbacks, callback_baton,
                           depth, ignore_ancestry, show_copies_as_adds,
+                          use_git_diff_format,
                           use_text_base, reverse_order, changelists,
                           cancel_func, cancel_baton,
                           result_pool));
@@ -1891,6 +1905,7 @@ svn_wc_diff6(svn_wc_context_t *wc_ctx,
              svn_depth_t depth,
              svn_boolean_t ignore_ancestry,
              svn_boolean_t show_copies_as_adds,
+             svn_boolean_t use_git_diff_format,
              const apr_array_header_t *changelists,
              svn_cancel_func_t cancel_func,
              void *cancel_baton,
@@ -1921,6 +1936,7 @@ svn_wc_diff6(svn_wc_context_t *wc_ctx,
                           target,
                           callbacks, callback_baton,
                           depth, ignore_ancestry, show_copies_as_adds,
+                          use_git_diff_format,
                           FALSE, FALSE, changelists,
                           cancel_func, cancel_baton,
                           pool));