On Mon, Jul 30, 2007 at 06:24:52PM +0200, Stefan Sperling wrote:
> As already mentioned in a private mail to Erik I'm currently on holiday.
> So I won't be able to look into the -x parameter until the end
> of next week.
And here it is, finally.
What exactly is the difference between --ignore-space-change
and --ignore-all-space? At the moment the test I've added treats
them exactly the same. Is there a subtle difference the test should
take into account?
[[[
* subversion/svnlook/main.c:
Teach 'svnlook diff' about the --extensions parameter
as already present in the 'svn diff' subcommand.
* subversion/tests/cmdline/svnlook_tests.py:
Add two new tests, namely diff_ignore_whitespace and
diff_ignore_eolstyle, to test the new --extensions
parameter of 'svnlook diff'.
]]]
Index: subversion/svnlook/main.c
===================================================================
--- subversion/svnlook/main.c (revision 26100)
+++ subversion/svnlook/main.c (working copy)
@@ -133,6 +133,37 @@
{"version", svnlook__version, 0,
N_("show program version information")},
+#ifndef AS400
+ {"extensions", 'x', 1,
+ N_("Default: '-u'. When Subversion is invoking an\n"
+ " "
+ " external diff program, ARG is simply passed along\n"
+ " "
+ " to the program. But when Subversion is using its\n"
+ " "
+ " default internal diff implementation, or when\n"
+ " "
+ " Subversion is displaying blame annotations, ARG\n"
+ " "
+ " could be any of the following:\n"
+ " "
+ " -u (--unified):\n"
+ " "
+ " Output 3 lines of unified context.\n"
+ " "
+ " -b (--ignore-space-change):\n"
+ " "
+ " Ignore changes in the amount of white space.\n"
+ " "
+ " -w (--ignore-all-space):\n"
+ " "
+ " Ignore all white space.\n"
+ " "
+ " --ignore-eol-style:\n"
+ " "
+ " Ignore changes in EOL style")},
+#endif
+
{0, 0, 0, 0}
};
@@ -166,7 +197,7 @@
N_("usage: svnlook diff REPOS_PATH\n\n"
"Print GNU-style diffs of changed files and properties.\n"),
{'r', 't', svnlook__no_diff_deleted, svnlook__no_diff_added,
- svnlook__diff_copy_from} },
+ svnlook__diff_copy_from, 'x'} },
{"dirs-changed", subcommand_dirschanged, {0},
N_("usage: svnlook dirs-changed REPOS_PATH\n\n"
@@ -253,6 +284,7 @@
svn_boolean_t full_paths; /* --full-paths */
svn_boolean_t copy_info; /* --copy-info */
svn_boolean_t non_recursive; /* --non-recursive */
+ const char *extensions; /* diff extension args */ /* UTF-8! */
};
@@ -271,6 +303,7 @@
svn_revnum_t rev_id;
svn_fs_txn_t *txn;
const char *txn_name /* UTF-8! */;
+ const apr_array_header_t *diff_options;
} svnlook_ctxt_t;
@@ -798,19 +831,23 @@
svn_boolean_t do_diff = FALSE;
svn_boolean_t orig_empty = FALSE;
svn_boolean_t is_copy = FALSE;
- svn_boolean_t printed_header = FALSE;
svn_boolean_t binary = FALSE;
apr_pool_t *subpool;
+ svn_stringbuf_t *header;
SVN_ERR(check_cancel(NULL));
if (! node)
return SVN_NO_ERROR;
+ header = svn_stringbuf_create("", pool);
+
/* Print copyfrom history for the top node of a copied tree. */
if ((SVN_IS_VALID_REVNUM(node->copyfrom_rev))
&& (node->copyfrom_path != NULL))
{
+ svn_string_t *str;
+
/* This is ... a copy. */
is_copy = TRUE;
@@ -823,11 +860,10 @@
else
base_path = apr_pstrdup(pool, node->copyfrom_path);
- SVN_ERR(svn_cmdline_printf(pool, _("Copied: %s (from rev %ld, %s)\n"),
- path, node->copyfrom_rev, base_path));
+ str = svn_string_createf(pool, _("Copied: %s (from rev %ld, %s)\n"),
+ path, node->copyfrom_rev, base_path);
+ svn_stringbuf_appendcstr(header, str->data);
- printed_header = TRUE;
-
SVN_ERR(svn_fs_revision_root(&base_root,
svn_fs_root_fs(base_root),
node->copyfrom_rev, pool));
@@ -886,37 +922,48 @@
tmpdir, pool));
}
- /* The header for the copy case has already been written, and we don't
+ /* The header for the copy case has already been created, and we don't
want a header here for files with only property modifications. */
- if (! printed_header
+ if (header->len == 0
&& (node->action != 'R' || node->text_mod))
{
- SVN_ERR(svn_cmdline_printf(pool, "%s: %s\n",
+ svn_string_t *str;
+
+ str = svn_string_createf(pool, "%s: %s\n",
((node->action == 'A') ? _("Added") :
((node->action == 'D') ? _("Deleted") :
((node->action == 'R') ? _("Modified")
: _("Index")))),
- path));
- printed_header = TRUE;
+ path);
+ svn_stringbuf_appendcstr(header, str->data);
}
}
if (do_diff)
{
- SVN_ERR(svn_cmdline_printf(pool, "%s\n", equal_string));
- SVN_ERR(svn_cmdline_fflush(stdout));
+ svn_stringbuf_appendcstr(header, equal_string);
+ svn_stringbuf_appendcstr(header, "\n");
if (binary)
- SVN_ERR(svn_cmdline_printf(pool, _("(Binary files differ)\n")));
+ svn_stringbuf_appendcstr(header, _("(Binary files differ)\n\n"));
else
{
svn_diff_t *diff;
- SVN_ERR(svn_diff_file_diff(&diff, orig_path, new_path, pool));
+ svn_diff_file_options_t *opts = svn_diff_file_options_create(pool);
+
+ if (c->diff_options)
+ SVN_ERR(svn_diff_file_options_parse(opts, c->diff_options, pool));
+
+ SVN_ERR(svn_diff_file_diff_2(&diff, orig_path, new_path, opts, pool));
+
if (svn_diff_contains_diffs(diff))
{
svn_stream_t *ostream;
const char *orig_label, *new_label;
+ /* Print diff header. */
+ SVN_ERR(svn_cmdline_printf(pool, header->data));
+
SVN_ERR(svn_stream_for_stdout(&ostream, pool));
if (orig_empty)
@@ -930,14 +977,11 @@
orig_label, new_label,
svn_cmdline_output_encoding(pool), pool));
SVN_ERR(svn_stream_close(ostream));
+ SVN_ERR(svn_cmdline_printf(pool, "\n"));
}
}
-
- SVN_ERR(svn_cmdline_printf(pool, "\n"));
SVN_ERR(svn_cmdline_fflush(stdout));
}
- else if (printed_header)
- SVN_ERR(svn_cmdline_printf(pool, "\n"));
/* Make sure we delete any temporary files. */
if (orig_path)
@@ -1597,6 +1641,13 @@
baton->is_revision = opt_state->txn ? FALSE : TRUE;
baton->rev_id = opt_state->rev;
baton->txn_name = apr_pstrdup(pool, opt_state->txn);
+
+ {
+ /* Fall back to "" to get diff_options initialized either way. */
+ const char *optstr = opt_state->extensions ? opt_state->extensions : "";
+ baton->diff_options = svn_cstring_split(optstr, " \t\n\r", TRUE, pool);
+ }
+
if (baton->txn_name)
SVN_ERR(svn_fs_open_txn(&(baton->txn), baton->fs,
baton->txn_name, pool));
@@ -2060,6 +2111,10 @@
opt_state.copy_info = TRUE;
break;
+ case 'x':
+ opt_state.extensions = opt_arg;
+ break;
+
default:
subcommand_help(NULL, NULL, pool);
svn_pool_destroy(pool);
Index: subversion/tests/cmdline/svnlook_tests.py
===================================================================
--- subversion/tests/cmdline/svnlook_tests.py (revision 26100)
+++ subversion/tests/cmdline/svnlook_tests.py (working copy)
@@ -415,7 +415,110 @@
if len(history[2:]) != 1:
raise svntest.Failure("Output not limited to expected number of items")
+#----------------------------------------------------------------------
+def diff_ignore_whitespace(sbox):
+ "test 'svnlook diff -x -b' and 'svnlook diff -x -w'"
+ sbox.build()
+ repo_dir = sbox.repo_dir
+ wc_dir = sbox.wc_dir
+
+ # Make whitespace-only changes to mu
+ mu_path = os.path.join(wc_dir, 'A', 'mu')
+ svntest.main.file_write(mu_path, "This is the file 'mu'.\n")
+
+ # Created expected output tree for 'svn ci'
+ expected_output = svntest.wc.State(wc_dir, {
+ 'A/mu' : Item(verb='Sending'),
+ })
+
+ # Create expected status tree; all local revisions should be at 1,
+ # but mu should be at revision 2.
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('A/mu', wc_rev=2)
+
+ svntest.actions.run_and_verify_commit(wc_dir,
+ expected_output,
+ expected_status,
+ None,
+ None, None,
+ None, None,
+ wc_dir)
+
+ # Check the output of 'svnlook diff -x --ignore-space-change' on mu.
+ # It should not print anything.
+ output = run_svnlook('diff', '-r2', '-x', '--ignore-space-change',
+ repo_dir, '/A/mu')
+ if output != []:
+ raise svntest.Failure
+
+ # Check the output of 'svnlook diff -x --ignore-all-space' on mu.
+ # It should not print anything.
+ output = run_svnlook('diff', '-r2', '-x', '--ignore-all-space',
+ repo_dir, '/A/mu')
+ if output != []:
+ raise svntest.Failure
+
+#----------------------------------------------------------------------
+def diff_ignore_eolstyle(sbox):
+ "test 'svnlook diff -x --ignore-eol-style'"
+
+ sbox.build()
+ repo_dir = sbox.repo_dir
+ wc_dir = sbox.wc_dir
+
+ if os.name == 'nt':
+ crlf = '\n'
+ else:
+ crlf = '\r\n'
+
+ mu_path = os.path.join(wc_dir, 'A', 'mu')
+
+ rev = 1
+ # do the --ignore-eol-style test for each eol-style
+ for eol, eolchar in zip(['CRLF', 'CR', 'native', 'LF'],
+ [crlf, '\015', '\n', '\012']):
+ # rewrite file mu and set the eol-style property.
+ svntest.main.file_write(mu_path, "This is the file 'mu'." + eolchar, 'wb')
+ svntest.main.run_svn(None, 'propset', 'svn:eol-style', eol, mu_path)
+
+ # Created expected output tree for 'svn ci'
+ expected_output = svntest.wc.State(wc_dir, {
+ 'A/mu' : Item(verb='Sending'),
+ })
+
+ # Create expected status tree; all local revisions should be at
+ # revision 1, but mu should be at revision rev + 1.
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('A/mu', wc_rev=rev + 1)
+
+ svntest.actions.run_and_verify_commit(wc_dir,
+ expected_output,
+ expected_status,
+ None,
+ None, None,
+ None, None,
+ wc_dir)
+
+ # Grab the diff
+ expected_output, err = svntest.actions.run_and_verify_svn(None, None, [],
+ 'diff',
+ '-r', 'PREV',
+ '-x',
+ '--ignore-eol-style',
+ mu_path)
+
+ output = run_svnlook('diff', '-r%i' % (rev + 1), '-x', '--ignore-eol-style',
+ repo_dir, '/A/mu')
+ rev += 1
+
+ # replace wcdir/A/mu with A/mu in expected_output
+ for i in xrange(len(expected_output)):
+ expected_output[i] = expected_output[i].replace(mu_path, 'A/mu')
+
+ svntest.actions.compare_and_display_lines('', '', expected_output, output)
+
+
########################################################################
# Run the tests
@@ -429,6 +532,8 @@
changed_copy_info,
tree_non_recursive,
limit_history,
+ diff_ignore_whitespace,
+ diff_ignore_eolstyle,
]
if __name__ == '__main__':
--
Stefan Sperling <stsp@elego.de> Software Developer
elego Software Solutions GmbH HRB 77719
Gustav-Meyer-Allee 25, Gebaeude 12 Tel: +49 30 23 45 86 96
13355 Berlin Fax: +49 30 23 45 86 95
http://www.elego.de Geschaeftsfuehrer: Olaf Wagner
- application/pgp-signature attachment: stored
Received on Wed Aug 15 19:07:51 2007