Daniel Berlin <dberlin@dberlin.org> writes:
> Theoretically, one should be able to use the libsvn_diff API, which
> tells you "lines from start to end in original were modified to become
> lines start to end in new file", and produce the explicit adds and
> deletes from that, but i haven't been able to get it to work right.
>
> In fact, diff -n is more or less doing this in order to produce the info
> it gives us. So we should be able to do it too :).
I'm not quite sure what you need, or what you can't get to work.
The patch below is a quick hack that overides the current diff output
vtable, so it's not suitable for the repository. Diff clients, like
the test program 'subversion/tests/libsvn_diff/diff-test', will output
approximate 'diff -n' output (the patch reuses the unified code so
each line representing an added line has a leading space).
Subversion and GNU sometimes choose different sequences to convert one
file into another so their outputs don't always match but they should
effect the same transformation.
Index: subversion/libsvn_diff/diff_file.c
===================================================================
--- subversion/libsvn_diff/diff_file.c (revision 13689)
+++ subversion/libsvn_diff/diff_file.c (working copy)
@@ -805,6 +805,45 @@
}
static
+svn_error_t *
+file_output_rcs_diff_modified(void *baton,
+ apr_off_t original_start,
+ apr_off_t original_length,
+ apr_off_t modified_start,
+ apr_off_t modified_length,
+ apr_off_t latest_start,
+ apr_off_t latest_length)
+{
+ svn_diff__file_output_baton_t *output_baton = baton;
+
+ if (original_length > 0)
+ printf("d%ld %ld\n", original_start + 1, original_length);
+
+ if (modified_length > 0)
+ {
+ printf("a%ld %ld\n", original_start + original_length, modified_length);
+
+ while (output_baton->current_line[1] < modified_start)
+ SVN_ERR(svn_diff__file_output_unified_line
+ (output_baton, svn_diff__file_output_unified_skip, 1));
+ while (output_baton->current_line[1] < modified_start + modified_length)
+ SVN_ERR(svn_diff__file_output_unified_line
+ (output_baton, svn_diff__file_output_unified_context, 1));
+
+ {
+ apr_size_t hunk_len = output_baton->hunk->len;
+ SVN_ERR(svn_stream_write(output_baton->output_stream,
+ output_baton->hunk->data,
+ &hunk_len));
+ output_baton->hunk_length[1] = 0;
+ svn_stringbuf_setempty(output_baton->hunk);
+ }
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static
const char *
svn_diff__file_output_unified_default_hdr(apr_pool_t *pool,
const char *path)
@@ -826,7 +865,7 @@
static const svn_diff_output_fns_t svn_diff__file_output_unified_vtable =
{
NULL, /* output_common */
- svn_diff__file_output_unified_diff_modified,
+ file_output_rcs_diff_modified,
NULL, /* output_diff_latest */
NULL, /* output_diff_common */
NULL /* output_conflict */
--
Philip Martin
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sat Mar 26 23:47:31 2005