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/27 17:23:00 UTC
svn commit: r990172 - in /subversion/trunk/subversion: libsvn_client/diff.c
tests/cmdline/diff_tests.py
Author: stsp
Date: Fri Aug 27 15:22:59 2010
New Revision: 990172
URL: http://svn.apache.org/viewvc?rev=990172&view=rev
Log:
Make property diffs show git-style diff headers in git diff mode.
* subversion/tests/cmdline/diff_tests.py
(diff_git_with_props, test_list): New test.
* subversion/libsvn_client/diff.c
(print_git_diff_header): Needs forward declaration so it can be used in ...
(display_prop_diffs): ... this function, without having to move it around.
Add new arguments USE_GIT_DIFF_FORMAT, RA_SESSION, and WC_CTX, for use
in git diff mode. In which, show git diff headers, with paths relative
to the repository root.
(diff_props_changed): Update caller.
Modified:
subversion/trunk/subversion/libsvn_client/diff.c
subversion/trunk/subversion/tests/cmdline/diff_tests.py
Modified: subversion/trunk/subversion/libsvn_client/diff.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/diff.c?rev=990172&r1=990171&r2=990172&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/diff.c (original)
+++ subversion/trunk/subversion/libsvn_client/diff.c Fri Aug 27 15:22:59 2010
@@ -433,12 +433,32 @@ diff_label(const char *path,
return label;
}
-
-
+/* ### forward declaration */
+static svn_error_t *
+print_git_diff_header(svn_stream_t *os,
+ const char **label1, const char **label2,
+ svn_diff_operation_kind_t operation,
+ const char *path,
+ const char *path1,
+ const char *path2,
+ svn_revnum_t rev1,
+ svn_revnum_t rev2,
+ const char *copyfrom_path,
+ const char *header_encoding,
+ svn_ra_session_t *ra_session,
+ svn_wc_context_t *wc_ctx,
+ apr_pool_t *scratch_pool);
/* A helper func that writes out verbal descriptions of property diffs
to FILE. Of course, the apr_file_t will probably be the 'outfile'
- passed to svn_client_diff5, which is probably stdout. */
+ passed to svn_client_diff5, which is probably stdout.
+
+ ### FIXME needs proper docstring
+
+ If USE_GIT_DIFF_FORMAT is TRUE, pring git diff headers, which always
+ show paths relative to the repository root. RA_SESSION and WC_CTX are
+ needed to normalize paths relative the repository root, and are ignored
+ if USE_GIT_DIFF_FORMAT is FALSE. */
static svn_error_t *
display_prop_diffs(const apr_array_header_t *propchanges,
apr_hash_t *original_props,
@@ -451,47 +471,83 @@ display_prop_diffs(const apr_array_heade
apr_file_t *file,
const char *relative_to_dir,
svn_boolean_t show_diff_header,
+ svn_boolean_t use_git_diff_format,
+ svn_ra_session_t *ra_session,
+ svn_wc_context_t *wc_ctx,
apr_pool_t *pool)
{
int i;
+ const char *path1 = apr_pstrdup(pool, orig_path1);
+ const char *path2 = apr_pstrdup(pool, orig_path2);
/* If we're creating a diff on the wc root, path would be empty. */
if (path[0] == '\0')
path = apr_psprintf(pool, ".");
- if (show_diff_header)
- {
- const char *path1 = orig_path1;
- const char *path2 = orig_path2;
- const char *label1;
- const char *label2;
-
- SVN_ERR(adjust_paths_for_diff_labels(&path, &path1, &path2,
- relative_to_dir, pool));
-
- label1 = diff_label(path1, rev1, pool);
- label2 = diff_label(path2, rev2, pool);
-
- /* ### Should we show the paths in platform specific format,
- * ### diff_content_changed() does not! */
-
- SVN_ERR(file_printf_from_utf8 (file, encoding,
- "Index: %s" APR_EOL_STR
- "%s" APR_EOL_STR,
- path,
- equal_string));
-
- SVN_ERR(file_printf_from_utf8(file, encoding,
- "--- %s" APR_EOL_STR
- "+++ %s" APR_EOL_STR,
- label1,
- label2));
- }
+ if (show_diff_header)
+ SVN_ERR(adjust_paths_for_diff_labels(&path, &path1, &path2,
+ relative_to_dir, pool));
+
+ if (use_git_diff_format)
+ {
+ SVN_ERR(adjust_relative_to_repos_root(&path1, path, orig_path1,
+ ra_session, wc_ctx,
+ svn_path_is_url(path1) &&
+ svn_path_is_url(path2),
+ pool));
+ SVN_ERR(adjust_relative_to_repos_root(&path2, path, orig_path2,
+ ra_session, wc_ctx,
+ svn_path_is_url(path1) &&
+ svn_path_is_url(path2),
+ pool));
+ }
+
+ if (show_diff_header)
+ {
+ const char *label1;
+ const char *label2;
+ const char *adjusted_path1 = apr_pstrdup(pool, path1);
+ const char *adjusted_path2 = apr_pstrdup(pool, path2);
+
+ SVN_ERR(adjust_paths_for_diff_labels(&path, &adjusted_path1,
+ &adjusted_path2,
+ relative_to_dir, pool));
+
+ label1 = diff_label(adjusted_path1, rev1, pool);
+ label2 = diff_label(adjusted_path2, rev2, pool);
+
+ /* ### Should we show the paths in platform specific format,
+ * ### diff_content_changed() does not! */
+
+ SVN_ERR(file_printf_from_utf8(file, encoding,
+ "Index: %s" APR_EOL_STR
+ "%s" APR_EOL_STR,
+ path, equal_string));
+
+ if (use_git_diff_format)
+ {
+ svn_stream_t *os;
+
+ os = svn_stream_from_aprfile2(file, TRUE, pool);
+ SVN_ERR(print_git_diff_header(os, &label1, &label2,
+ svn_diff_op_modified, path,
+ orig_path1, orig_path2,
+ rev1, rev2, NULL,
+ encoding, ra_session, wc_ctx, pool));
+ SVN_ERR(svn_stream_close(os));
+ }
+
+ SVN_ERR(file_printf_from_utf8(file, encoding,
+ "--- %s" APR_EOL_STR
+ "+++ %s" APR_EOL_STR,
+ label1,
+ label2));
+ }
SVN_ERR(file_printf_from_utf8(file, encoding,
_("%sProperty changes on: %s%s"),
APR_EOL_STR,
- path,
+ use_git_diff_format ? path1 : path,
APR_EOL_STR));
SVN_ERR(file_printf_from_utf8(file, encoding, "%s" APR_EOL_STR,
@@ -861,6 +917,9 @@ diff_props_changed(const char *local_dir
diff_cmd_baton->outfile,
diff_cmd_baton->relative_to_dir,
show_diff_header,
+ diff_cmd_baton->use_git_diff_format,
+ diff_cmd_baton->ra_session,
+ diff_cmd_baton->wc_ctx,
subpool));
/* We've printed the diff header so now we can mark the path as
Modified: subversion/trunk/subversion/tests/cmdline/diff_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/diff_tests.py?rev=990172&r1=990171&r2=990172&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/diff_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/diff_tests.py Fri Aug 27 15:22:59 2010
@@ -3645,7 +3645,53 @@ def diff_git_empty_files(sbox):
svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff',
'--git', wc_dir)
+def diff_git_with_props(sbox):
+ "create a diff in git format showing prop changes"
+ sbox.build()
+ wc_dir = sbox.wc_dir
+ iota_path = os.path.join(wc_dir, 'iota')
+ new_path = os.path.join(wc_dir, 'new')
+ svntest.main.file_write(iota_path, "")
+
+ # Now commit the local mod, creating rev 2.
+ expected_output = svntest.wc.State(wc_dir, {
+ 'iota' : Item(verb='Sending'),
+ })
+
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.add({
+ 'iota' : Item(status=' ', wc_rev=2),
+ })
+
+ svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+ expected_status, None, wc_dir)
+
+ svntest.main.file_write(new_path, "")
+ svntest.main.run_svn(None, 'add', new_path)
+ svntest.main.run_svn(None, 'propset', 'svn:eol-style', 'native', new_path)
+ svntest.main.run_svn(None, 'propset', 'svn:keywords', 'Id', iota_path)
+
+ expected_output = make_git_diff_header(new_path, "new", "revision 0",
+ "working copy",
+ add=True, text_changes=False) + [
+ "\n",
+ "Property changes on: new\n",
+ "___________________________________________________________________\n",
+ "Added: svn:eol-style\n",
+ "## -0,0 +1 ##\n",
+ "+native\n",
+ ] + make_git_diff_header(iota_path, "iota", "revision 1", "working copy",
+ text_changes=False) + [
+ "\n",
+ "Property changes on: iota\n",
+ "___________________________________________________________________\n",
+ "Added: svn:keywords\n",
+ "## -0,0 +1 ##\n",
+ "+Id\n",
+ ]
+ svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff',
+ '--git', wc_dir)
########################################################################
#Run the tests
@@ -3708,6 +3754,7 @@ test_list = [ None,
diff_prop_missing_context,
diff_prop_multiple_hunks,
diff_git_empty_files,
+ diff_git_with_props,
]
if __name__ == '__main__':