This patch is a followup of the following thread. All tests pass with
this patch.
http://svn.haxx.se/dev/archive-2011-01/0210.shtml
Log
[[[
Make 'svn blame' continue processing targets after printing warning if one
or more of the targets is a non-existent URL or wc-entry. Also return a
non-zero error code and print an error message at the end in those
situations.
* subversion/svn/blame-cmd.c
(svn_cl__blame): If one of the targets is a non-existent URL or
wc-entry, don't bail out. Just warn and move on to the next
target. Also return a non-zero error code and print an error message
at the end in those situations.
* subversion/tests/cmdline/blame_tests.py
(blame_non_existent_wc_target, blame_non_existent_url_target):
New tests.
(test_list): Add reference to new tests.
Patch by: Noorul Islam K M <noorul{_AT_}collab.net>
]]]
Index: subversion/tests/cmdline/blame_tests.py
===================================================================
--- subversion/tests/cmdline/blame_tests.py (revision 1071585)
+++ subversion/tests/cmdline/blame_tests.py (working copy)
@@ -25,7 +25,7 @@
######################################################################
# General modules
-import os, sys
+import os, sys, re
# Our testing module
import svntest
@@ -710,7 +710,69 @@
svntest.actions.run_and_verify_svn(None, expected_output, [],
'blame', '-g', mu_path)
+def blame_non_existent_wc_target(sbox):
+ "blame non existent wc target"
+ sbox.build()
+
+ # First, make a new revision of iota.
+ iota = os.path.join(sbox.wc_dir, 'iota')
+ non_existent = os.path.join(sbox.wc_dir, 'non-existent')
+ svntest.main.file_append(iota, "New contents for iota\n")
+ svntest.main.run_svn(None, 'ci',
+ '-m', '', iota)
+
+ expected_output = [
+ " 1 jrandom This is the file 'iota'.\n",
+ " 2 jrandom New contents for iota\n",
+ ]
+
+ expected_err = "svn: warning: W155010: The node '" + \
+ re.escape(os.path.abspath(non_existent)) + "' was not found.\n" + \
+ ".*\nsvn: E200009: Could not perform blame on all targets " + \
+ "because some targets don't exist\n"
+ expected_err_re = re.compile(expected_err)
+
+ exit_code, output, error = svntest.main.run_svn(1, 'blame',
+ non_existent, iota)
+
+ # Verify error
+ if not expected_err_re.match("".join(error)):
+ raise svntest.Failure('blame failed: expected error "%s", but received '
+ '"%s"' % (expected_err, "".join(error)))
+
+def blame_non_existent_url_target(sbox):
+ "blame non existent url target"
+
+ sbox.build()
+
+ # First, make a new revision of iota.
+ iota = os.path.join(sbox.wc_dir, 'iota')
+ iota_url = sbox.repo_url + '/iota'
+ non_existent = sbox.repo_url + '/non-existent'
+ svntest.main.file_append(iota, "New contents for iota\n")
+ svntest.main.run_svn(None, 'ci',
+ '-m', '', iota)
+
+ expected_output = [
+ " 1 jrandom This is the file 'iota'.\n",
+ " 2 jrandom New contents for iota\n",
+ ]
+
+ expected_err = "svn: warning: W160017: '/non-existent' " + \
+ "is not a file in revision 2\n" + \
+ ".*\nsvn: E200009: Could not perform blame on all targets " + \
+ "because some targets don't exist\n"
+ expected_err_re = re.compile(expected_err)
+
+ exit_code, output, error = svntest.main.run_svn(1, 'blame',
+ non_existent, iota_url)
+
+ # Verify error
+ if not expected_err_re.match("".join(error)):
+ raise svntest.Failure('blame failed: expected error "%s", but received '
+ '"%s"' % (expected_err, "".join(error)))
+
########################################################################
# Run the tests
@@ -731,6 +793,8 @@
blame_peg_rev_file_not_in_head,
blame_file_not_in_head,
blame_output_after_merge,
+ blame_non_existent_wc_target,
+ blame_non_existent_url_target,
]
if __name__ == '__main__':
Index: subversion/svn/blame-cmd.c
===================================================================
--- subversion/svn/blame-cmd.c (revision 1071585)
+++ subversion/svn/blame-cmd.c (working copy)
@@ -245,6 +245,7 @@
int i;
svn_boolean_t end_revision_unspecified = FALSE;
svn_diff_file_options_t *diff_options = svn_diff_file_options_create(pool);
+ svn_boolean_t seen_nonexistent_target = FALSE;
SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
opt_state->targets,
@@ -377,6 +378,14 @@
_("Skipping binary file: '%s'\n"),
target));
}
+ else if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND ||
+ err->apr_err == SVN_ERR_FS_NOT_FILE)
+ {
+ svn_handle_warning2(stderr, err, "svn: ");
+ svn_error_clear(err);
+ err = NULL;
+ seen_nonexistent_target = TRUE;
+ }
else
{
return svn_error_return(err);
@@ -396,5 +405,11 @@
if (opt_state->xml && ! opt_state->incremental)
SVN_ERR(svn_cl__xml_print_footer("blame", pool));
- return SVN_NO_ERROR;
+ if (seen_nonexistent_target)
+ return svn_error_create(
+ SVN_ERR_ILLEGAL_TARGET, NULL,
+ _("Could not perform blame on all targets because some "
+ "targets don't exist"));
+ else
+ return SVN_NO_ERROR;
}
Received on 2011-02-17 14:00:52 CET