Hi!
I need to have a diff header even if there's only property changes for
the sake of parsing.
And I want only one diff header per file. Makes it easier to apply the
patch. For each found diff header we create one svn_patch_t object.
Simple and clean.
What to do? I could add a flag to the diff_cmd_baton and reset it
between each call but, as Greg pointed out, that's like using a global
variable.
I could collect all the paths with affected files and create the diff in
something like close_edit() but there's no such call for
svn_wc_diff_callbacks4_t.
One other approach:
[[[
Make 'svn diff' always write out a diff header if there are changes to a
path, no matter if it's property or text changes.
* subversion/libsvn_client/diff.c
(diff_cmd_baton): New field 'visited_paths' to hold all the paths for
which a diff header has already been written.
(display_prop_diff): Add parameter 'show_diff_header'.
(diff_props_changed): Call display_prop_diffs() with show_diff_header
set to TRUE if the path has not yet been processed.
(diff_content_changed): Add the path to 'visited_paths'.
(svn_client_diff5,
svn_client_diff_peg5): Initialize diff_cmd_baton->visited_paths.
]]]
Feels kinda ugly. Some obvious way to do it that I'm missing? The
alternatives I can come up with would involve revamping the callback
chain to make property changes and text changes end up in one function.
[[[
Index: subversion/libsvn_client/diff.c
===================================================================
--- subversion/libsvn_client/diff.c (revision 955844)
+++ subversion/libsvn_client/diff.c (arbetskopia)
@@ -200,6 +200,7 @@ display_prop_diffs(const apr_array_header_t *propc
const char *encoding,
apr_file_t *file,
const char *relative_to_dir,
+ svn_boolean_t show_diff_header,
apr_pool_t *pool)
{
int i;
@@ -294,7 +295,8 @@ display_prop_diffs(const apr_array_header_t *propc
* UNIX patch could apply the property diff to, so we use "##"
* instead of "@@" as the default hunk delimiter for property diffs.
* We also supress the diff header. */
- SVN_ERR(svn_diff_mem_string_output_unified2(os, diff, FALSE, "##",
+ SVN_ERR(svn_diff_mem_string_output_unified2(os, diff, show_diff_header,
+ "##",
svn_dirent_local_style(path, pool),
svn_dirent_local_style(path, pool),
encoding, orig, val, pool));
@@ -451,6 +453,8 @@ struct diff_cmd_baton {
/* The directory that diff target paths should be considered as
relative to for output generation (see issue #2723). */
const char *relative_to_dir;
+
+ apr_hash_t *visited_paths;
};
/* Generate a label for the diff output for file PATH at revision REVNUM.
@@ -485,15 +489,22 @@ diff_props_changed(const char *local_dir_abspath,
{
struct diff_cmd_baton *diff_cmd_baton = diff_baton;
apr_array_header_t *props;
+ svn_boolean_t show_diff_header;
apr_pool_t *subpool = svn_pool_create(diff_cmd_baton->pool);
SVN_ERR(svn_categorize_props(propchanges, NULL, NULL, &props, subpool));
+ if (apr_hash_get(diff_cmd_baton->visited_paths, path, APR_HASH_KEY_STRING))
+ show_diff_header = FALSE;
+ else
+ show_diff_header = TRUE;
+
if (props->nelts > 0)
SVN_ERR(display_prop_diffs(props, original_props, path,
diff_cmd_baton->header_encoding,
diff_cmd_baton->outfile,
diff_cmd_baton->relative_to_dir,
+ show_diff_header,
subpool));
if (state)
@@ -750,6 +761,8 @@ diff_content_changed(const char *path,
/* Destroy the subpool. */
svn_pool_destroy(subpool);
+ apr_hash_set(diff_cmd_baton->visited_paths, path, APR_HASH_KEY_STRING, path);
+
return SVN_NO_ERROR;
}
@@ -1908,6 +1921,7 @@ svn_client_diff5(const apr_array_header_t *options
diff_cmd_baton.force_empty = FALSE;
diff_cmd_baton.force_binary = ignore_content_type;
diff_cmd_baton.relative_to_dir = relative_to_dir;
+ diff_cmd_baton.visited_paths = apr_hash_make(pool);
return do_diff(&diff_params, &diff_callbacks, &diff_cmd_baton, ctx, pool);
}
@@ -1974,6 +1988,7 @@ svn_client_diff_peg5(const apr_array_header_t *opt
diff_cmd_baton.force_empty = FALSE;
diff_cmd_baton.force_binary = ignore_content_type;
diff_cmd_baton.relative_to_dir = relative_to_dir;
+ diff_cmd_baton.visited_paths = apr_hash_make(pool);
return do_diff(&diff_params, &diff_callbacks, &diff_cmd_baton, ctx, pool);
}
]]]
Daniel
Received on 2010-06-18 10:47:18 CEST