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));