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.
368 lines
17 KiB
368 lines
17 KiB
6 years ago
|
# ./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,
|