You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
367 lines
17 KiB
367 lines
17 KiB
# ./pullrev.sh r1564900 |
|
|
|
http://svn.apache.org/viewvc?view=revision&revision=r1564900 |
|
|
|
https://bugzilla.redhat.com/show_bug.cgi?id=1378178 |
|
|
|
--- subversion-1.7.14/subversion/tests/cmdline/diff_tests.py |
|
+++ subversion-1.7.14/subversion/tests/cmdline/diff_tests.py |
|
@@ -45,16 +45,39 @@ |
|
###################################################################### |
|
# Generate expected output |
|
|
|
-def make_diff_header(path, old_tag, new_tag): |
|
+def is_absolute_url(target): |
|
+ return (target.startswith('file://') |
|
+ or target.startswith('http://') |
|
+ or target.startswith('https://') |
|
+ or target.startswith('svn://') |
|
+ or target.startswith('svn+ssh://')) |
|
+ |
|
+def make_diff_header(path, old_tag, new_tag, src_label=None, dst_label=None): |
|
"""Generate the expected diff header for file PATH, with its old and new |
|
- versions described in parentheses by OLD_TAG and NEW_TAG. Return the header |
|
- as an array of newline-terminated strings.""" |
|
+ versions described in parentheses by OLD_TAG and NEW_TAG. SRC_LABEL and |
|
+ DST_LABEL are paths or urls that are added to the diff labels if we're |
|
+ diffing against the repository or diffing two arbitrary paths. |
|
+ Return the header as an array of newline-terminated strings.""" |
|
+ if src_label: |
|
+ src_label = src_label.replace('\\', '/') |
|
+ if not is_absolute_url(src_label): |
|
+ src_label = '.../' + src_label |
|
+ src_label = '\t(' + src_label + ')' |
|
+ else: |
|
+ src_label = '' |
|
+ if dst_label: |
|
+ dst_label = dst_label.replace('\\', '/') |
|
+ if not is_absolute_url(dst_label): |
|
+ dst_label = '.../' + dst_label |
|
+ dst_label = '\t(' + dst_label + ')' |
|
+ else: |
|
+ dst_label = '' |
|
path_as_shown = path.replace('\\', '/') |
|
return [ |
|
"Index: " + path_as_shown + "\n", |
|
"===================================================================\n", |
|
- "--- " + path_as_shown + "\t(" + old_tag + ")\n", |
|
- "+++ " + path_as_shown + "\t(" + new_tag + ")\n", |
|
+ "--- " + path_as_shown + src_label + "\t(" + old_tag + ")\n", |
|
+ "+++ " + path_as_shown + dst_label + "\t(" + new_tag + ")\n", |
|
] |
|
|
|
def make_no_diff_deleted_header(path, old_tag, new_tag): |
|
@@ -3867,6 +3890,122 @@ |
|
'diff', '-c2', |
|
sbox.repo_url + '/A/D/H') |
|
|
|
+@Issue(4460) |
|
+def diff_repo_wc_file_props(sbox): |
|
+ "diff repo to wc file target with props" |
|
+ sbox.build() |
|
+ iota = sbox.ospath('iota') |
|
+ |
|
+ # add a mime-type and a line to iota to test the binary check |
|
+ sbox.simple_propset('svn:mime-type', 'text/plain', 'iota') |
|
+ sbox.simple_append('iota','second line\n') |
|
+ |
|
+ # test that we get the line and the property add |
|
+ expected_output = make_diff_header(iota, 'revision 1', 'working copy') + \ |
|
+ [ '@@ -1 +1,2 @@\n', |
|
+ " This is the file 'iota'.\n", |
|
+ "+second line\n", ] + \ |
|
+ make_diff_prop_header(iota) + \ |
|
+ make_diff_prop_added('svn:mime-type', 'text/plain') |
|
+ svntest.actions.run_and_verify_svn(None, expected_output, [], |
|
+ 'diff', '-r1', iota) |
|
+ |
|
+ # reverse the diff, should get a property delete and line delete |
|
+ # skip actually testing the output since apparently 1.7 is busted |
|
+ # this isn't related to issue #4460, older versions of 1.7 had the issue |
|
+ # as well |
|
+ #expected_output = make_diff_header(iota, 'working copy', 'revision 1') + \ |
|
+ # [ '@@ -1,2 +1 @@\n', |
|
+ # " This is the file 'iota'.\n", |
|
+ # "-second line\n", ] + \ |
|
+ # make_diff_prop_header(iota) + \ |
|
+ # make_diff_prop_deleted('svn:mime-type', 'text/plain') |
|
+ expected_output = None |
|
+ svntest.actions.run_and_verify_svn(None, expected_output, [], |
|
+ 'diff', '--old', iota, |
|
+ '--new', iota + '@1') |
|
+ |
|
+ # copy iota to test with --show-copies as adds |
|
+ sbox.simple_copy('iota', 'iota_copy') |
|
+ iota_copy = sbox.ospath('iota_copy') |
|
+ |
|
+ # test that we get all lines as added and the property added |
|
+ # TODO: We only test that this test doesn't error out because of Issue #4464 |
|
+ # if and when that issue is fixed this test should check output |
|
+ svntest.actions.run_and_verify_svn(None, None, [], 'diff', |
|
+ '--show-copies-as-adds', '-r1', iota_copy) |
|
+ |
|
+ # reverse the diff, should get all lines as a delete and no property |
|
+ # TODO: We only test that this test doesn't error out because of Issue #4464 |
|
+ # if and when that issue is fixed this test should check output |
|
+ svntest.actions.run_and_verify_svn(None, None, [], 'diff', |
|
+ '--show-copies-as-adds', |
|
+ '--old', iota_copy, |
|
+ '--new', iota + '@1') |
|
+ |
|
+ # revert and commit with the eol-style of LF and then update so |
|
+ # that we can see a change on either windows or *nix. |
|
+ sbox.simple_revert('iota', 'iota_copy') |
|
+ sbox.simple_propset('svn:eol-style', 'LF', 'iota') |
|
+ sbox.simple_commit() #r2 |
|
+ sbox.simple_update() |
|
+ |
|
+ # now that we have a LF file on disk switch to CRLF |
|
+ sbox.simple_propset('svn:eol-style', 'CRLF', 'iota') |
|
+ |
|
+ # test that not only the property but also the file changes |
|
+ # i.e. that the line endings substitution works |
|
+ if svntest.main.is_os_windows(): |
|
+ # test suite normalizes crlf output into just lf on Windows. |
|
+ # so we have to assume it worked because there is an add and |
|
+ # remove line with the same content. Fortunately, it does't |
|
+ # do this on *nix so we can be pretty sure that it works right. |
|
+ # TODO: Provide a way to handle this better |
|
+ crlf = '\n' |
|
+ else: |
|
+ crlf = '\r\n' |
|
+ expected_output = make_diff_header(iota, 'revision 1', 'working copy') + \ |
|
+ [ '@@ -1 +1 @@\n', |
|
+ "-This is the file 'iota'.\n", |
|
+ "+This is the file 'iota'." + crlf ] + \ |
|
+ make_diff_prop_header(iota) + \ |
|
+ make_diff_prop_added('svn:eol-style', 'CRLF') |
|
+ |
|
+ svntest.actions.run_and_verify_svn(None, expected_output, [], |
|
+ 'diff', '-r1', iota) |
|
+ |
|
+ |
|
+@Issue(4460) |
|
+def diff_repo_repo_added_file_mime_type(sbox): |
|
+ "diff repo to repo added file with mime-type" |
|
+ sbox.build() |
|
+ wc_dir = sbox.wc_dir |
|
+ newfile = sbox.ospath('newfile') |
|
+ |
|
+ # add a file with a mime-type |
|
+ sbox.simple_append('newfile', "This is the file 'newfile'.\n") |
|
+ sbox.simple_add('newfile') |
|
+ sbox.simple_propset('svn:mime-type', 'text/plain', 'newfile') |
|
+ sbox.simple_commit() # r2 |
|
+ |
|
+ # try to diff across the addition |
|
+ expected_output = make_diff_header(newfile, 'revision 1', 'revision 2') + \ |
|
+ [ '@@ -0,0 +1 @@\n', |
|
+ "+This is the file 'newfile'.\n" ] + \ |
|
+ make_diff_prop_header(newfile) + \ |
|
+ make_diff_prop_added('svn:mime-type', 'text/plain') |
|
+ |
|
+ svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff', |
|
+ '-r1:2', newfile) |
|
+ |
|
+ # reverse the diff to diff across a deletion |
|
+ # Note no property delete is printed when whole file is deleted |
|
+ expected_output = make_diff_header(newfile, 'revision 2', 'revision 1') + \ |
|
+ [ '@@ -1, +0,0 @@\n', |
|
+ "-This is the file 'newfile'.\n" ] |
|
+ svntest.actions.run_and_verify_svn(None, None, [], 'diff', |
|
+ '-r2:1', newfile) |
|
+ |
|
######################################################################## |
|
#Run the tests |
|
|
|
@@ -3935,6 +4074,8 @@ |
|
no_spurious_conflict, |
|
diff_deleted_url, |
|
diff_git_format_wc_wc_dir_mv, |
|
+ diff_repo_wc_file_props, |
|
+ diff_repo_repo_added_file_mime_type, |
|
] |
|
|
|
if __name__ == '__main__': |
|
--- subversion-1.7.14/subversion/libsvn_client/diff.c |
|
+++ subversion-1.7.14/subversion/libsvn_client/diff.c |
|
@@ -1892,6 +1892,7 @@ |
|
const char *file_abspath; |
|
svn_stream_t *content; |
|
apr_hash_t *prop_hash; |
|
+ svn_string_t *mimetype; |
|
|
|
SVN_ERR(svn_stream_open_unique(&content, &file_abspath, NULL, |
|
svn_io_file_del_on_pool_cleanup, |
|
@@ -1900,13 +1901,13 @@ |
|
&prop_hash, scratch_pool)); |
|
SVN_ERR(svn_stream_close(content)); |
|
|
|
+ mimetype = apr_hash_get(prop_hash, SVN_PROP_MIME_TYPE, APR_HASH_KEY_STRING); |
|
+ |
|
if (show_deletion) |
|
{ |
|
SVN_ERR(callbacks->file_deleted(NULL, NULL, |
|
target, file_abspath, empty_file, |
|
- apr_hash_get(prop_hash, |
|
- SVN_PROP_MIME_TYPE, |
|
- APR_HASH_KEY_STRING), |
|
+ mimetype ? mimetype->data : NULL, |
|
NULL, |
|
make_regular_props_hash( |
|
prop_hash, scratch_pool, scratch_pool), |
|
@@ -1917,8 +1918,7 @@ |
|
SVN_ERR(callbacks->file_added(NULL, NULL, NULL, |
|
target, empty_file, file_abspath, |
|
rev1, rev2, NULL, |
|
- apr_hash_get(prop_hash, SVN_PROP_MIME_TYPE, |
|
- APR_HASH_KEY_STRING), |
|
+ mimetype ? mimetype->data : NULL, |
|
NULL, SVN_INVALID_REVNUM, |
|
make_regular_props_array(prop_hash, |
|
scratch_pool, |
|
@@ -2243,6 +2243,7 @@ |
|
apr_hash_t *file1_props = NULL; |
|
apr_hash_t *file2_props; |
|
svn_boolean_t is_copy = FALSE; |
|
+ svn_string_t *mimetype1, *mimetype2; |
|
|
|
/* Get content and props of file 1 (the remote file). */ |
|
SVN_ERR(svn_stream_open_unique(&file1_content, &file1_abspath, NULL, |
|
@@ -2292,6 +2293,7 @@ |
|
{ |
|
apr_hash_t *keywords = NULL; |
|
svn_string_t *keywords_prop; |
|
+ svn_string_t *eol_prop; |
|
svn_subst_eol_style_t eol_style; |
|
const char *eol_str; |
|
|
|
@@ -2299,10 +2301,10 @@ |
|
scratch_pool, scratch_pool)); |
|
|
|
/* We might have to create a normalised version of the working file. */ |
|
+ eol_prop = apr_hash_get(file2_props, SVN_PROP_EOL_STYLE, |
|
+ APR_HASH_KEY_STRING); |
|
svn_subst_eol_style_from_value(&eol_style, &eol_str, |
|
- apr_hash_get(file2_props, |
|
- SVN_PROP_EOL_STYLE, |
|
- APR_HASH_KEY_STRING)); |
|
+ eol_prop ? eol_prop->data : NULL); |
|
keywords_prop = apr_hash_get(file2_props, SVN_PROP_KEYWORDS, |
|
APR_HASH_KEY_STRING); |
|
if (keywords_prop) |
|
@@ -2309,7 +2311,7 @@ |
|
SVN_ERR(svn_subst_build_keywords2(&keywords, keywords_prop->data, |
|
NULL, NULL, 0, NULL, |
|
scratch_pool)); |
|
- if (svn_subst_translation_required(eol_style, SVN_SUBST_NATIVE_EOL_STR, |
|
+ if (svn_subst_translation_required(eol_style, eol_str, |
|
keywords, FALSE, TRUE)) |
|
{ |
|
svn_stream_t *working_content; |
|
@@ -2323,7 +2325,7 @@ |
|
svn_io_file_del_on_pool_cleanup, |
|
scratch_pool, scratch_pool)); |
|
normalized_content = svn_subst_stream_translated( |
|
- file2_content, SVN_SUBST_NATIVE_EOL_STR, |
|
+ file2_content, eol_str, |
|
TRUE, keywords, FALSE, scratch_pool); |
|
SVN_ERR(svn_stream_copy3(working_content, normalized_content, |
|
ctx->cancel_func, ctx->cancel_baton, |
|
@@ -2331,42 +2333,46 @@ |
|
} |
|
} |
|
|
|
+ mimetype1 = file1_props ? apr_hash_get(file1_props, SVN_PROP_MIME_TYPE, |
|
+ APR_HASH_KEY_STRING) |
|
+ : NULL; |
|
+ mimetype2 = apr_hash_get(file2_props, SVN_PROP_MIME_TYPE, |
|
+ APR_HASH_KEY_STRING); |
|
+ |
|
if (kind1 == svn_node_file && !(show_copies_as_adds && is_copy)) |
|
{ |
|
+ apr_array_header_t *propchanges; |
|
+ |
|
SVN_ERR(callbacks->file_opened(NULL, NULL, target, |
|
reverse ? SVN_INVALID_REVNUM : rev, |
|
callback_baton, scratch_pool)); |
|
|
|
if (reverse) |
|
- SVN_ERR(callbacks->file_changed(NULL, NULL, NULL, target, |
|
- file2_abspath, file1_abspath, |
|
- SVN_INVALID_REVNUM, rev, |
|
- apr_hash_get(file2_props, |
|
- SVN_PROP_MIME_TYPE, |
|
- APR_HASH_KEY_STRING), |
|
- apr_hash_get(file1_props, |
|
- SVN_PROP_MIME_TYPE, |
|
- APR_HASH_KEY_STRING), |
|
- make_regular_props_array( |
|
- file1_props, scratch_pool, |
|
- scratch_pool), |
|
- file2_props, |
|
- callback_baton, scratch_pool)); |
|
+ { |
|
+ SVN_ERR(svn_prop_diffs(&propchanges, file1_props, file2_props, |
|
+ scratch_pool)); |
|
+ |
|
+ SVN_ERR(callbacks->file_changed(NULL, NULL, NULL, target, |
|
+ file2_abspath, file1_abspath, |
|
+ SVN_INVALID_REVNUM, rev, |
|
+ mimetype2 ? mimetype2->data : NULL, |
|
+ mimetype1 ? mimetype1->data : NULL, |
|
+ propchanges, file2_props, |
|
+ callback_baton, scratch_pool)); |
|
+ } |
|
else |
|
- SVN_ERR(callbacks->file_changed(NULL, NULL, NULL, target, |
|
- file1_abspath, file2_abspath, |
|
- rev, SVN_INVALID_REVNUM, |
|
- apr_hash_get(file1_props, |
|
- SVN_PROP_MIME_TYPE, |
|
- APR_HASH_KEY_STRING), |
|
- apr_hash_get(file2_props, |
|
- SVN_PROP_MIME_TYPE, |
|
- APR_HASH_KEY_STRING), |
|
- make_regular_props_array( |
|
- file2_props, scratch_pool, |
|
- scratch_pool), |
|
- file1_props, |
|
- callback_baton, scratch_pool)); |
|
+ { |
|
+ SVN_ERR(svn_prop_diffs(&propchanges, file2_props, file1_props, |
|
+ scratch_pool)); |
|
+ |
|
+ SVN_ERR(callbacks->file_changed(NULL, NULL, NULL, target, |
|
+ file1_abspath, file2_abspath, |
|
+ rev, SVN_INVALID_REVNUM, |
|
+ mimetype1 ? mimetype1->data : NULL, |
|
+ mimetype2 ? mimetype2->data : NULL, |
|
+ propchanges, file1_props, |
|
+ callback_baton, scratch_pool)); |
|
+ } |
|
} |
|
else |
|
{ |
|
@@ -2374,9 +2380,7 @@ |
|
{ |
|
SVN_ERR(callbacks->file_deleted(NULL, NULL, |
|
target, file2_abspath, file1_abspath, |
|
- apr_hash_get(file2_props, |
|
- SVN_PROP_MIME_TYPE, |
|
- APR_HASH_KEY_STRING), |
|
+ mimetype2 ? mimetype2->data : NULL, |
|
NULL, |
|
make_regular_props_hash( |
|
file2_props, scratch_pool, |
|
@@ -2389,9 +2393,7 @@ |
|
file1_abspath, file2_abspath, |
|
rev, SVN_INVALID_REVNUM, |
|
NULL, |
|
- apr_hash_get(file2_props, |
|
- SVN_PROP_MIME_TYPE, |
|
- APR_HASH_KEY_STRING), |
|
+ mimetype2 ? mimetype2->data : NULL, |
|
NULL, SVN_INVALID_REVNUM, |
|
make_regular_props_array( |
|
file2_props, scratch_pool,
|
|
|