Commit d8e7ffc2 by Nick Hengeveld

Add content offset to git_diff_line

For additions and deletions, external consumers like subversion
can make use of the content offset to generate diffs in their
proprietary formats.
parent e1ce5249
...@@ -446,6 +446,7 @@ struct git_diff_line { ...@@ -446,6 +446,7 @@ struct git_diff_line {
int new_lineno; /** Line number in new file or -1 for deleted line */ int new_lineno; /** Line number in new file or -1 for deleted line */
int num_lines; /** Number of newline characters in content */ int num_lines; /** Number of newline characters in content */
size_t content_len; /** Number of bytes of data */ size_t content_len; /** Number of bytes of data */
git_off_t content_offset; /** Offset in the original file to the content */
const char *content; /** Pointer to diff text, not NUL-byte terminated */ const char *content; /** Pointer to diff text, not NUL-byte terminated */
}; };
......
...@@ -54,6 +54,7 @@ typedef struct { ...@@ -54,6 +54,7 @@ typedef struct {
git_patch *patch; git_patch *patch;
git_diff_hunk hunk; git_diff_hunk hunk;
int old_lineno, new_lineno; int old_lineno, new_lineno;
mmfile_t xd_old_data, xd_new_data;
} git_xdiff_info; } git_xdiff_info;
static int diff_update_lines( static int diff_update_lines(
...@@ -135,6 +136,13 @@ static int git_xdiff_cb(void *priv, mmbuffer_t *bufs, int len) ...@@ -135,6 +136,13 @@ static int git_xdiff_cb(void *priv, mmbuffer_t *bufs, int len)
(*bufs[0].ptr == '-') ? GIT_DIFF_LINE_DELETION : (*bufs[0].ptr == '-') ? GIT_DIFF_LINE_DELETION :
GIT_DIFF_LINE_CONTEXT; GIT_DIFF_LINE_CONTEXT;
if (line.origin == GIT_DIFF_LINE_ADDITION)
line.content_offset = bufs[1].ptr - info->xd_new_data.ptr;
else if (line.origin == GIT_DIFF_LINE_DELETION)
line.content_offset = bufs[1].ptr - info->xd_old_data.ptr;
else
line.content_offset = -1;
output->error = diff_update_lines( output->error = diff_update_lines(
info, &line, bufs[1].ptr, bufs[1].size); info, &line, bufs[1].ptr, bufs[1].size);
...@@ -155,6 +163,8 @@ static int git_xdiff_cb(void *priv, mmbuffer_t *bufs, int len) ...@@ -155,6 +163,8 @@ static int git_xdiff_cb(void *priv, mmbuffer_t *bufs, int len)
(*bufs[0].ptr == '-') ? GIT_DIFF_LINE_ADD_EOFNL : (*bufs[0].ptr == '-') ? GIT_DIFF_LINE_ADD_EOFNL :
GIT_DIFF_LINE_CONTEXT_EOFNL; GIT_DIFF_LINE_CONTEXT_EOFNL;
line.content_offset = -1;
output->error = diff_update_lines( output->error = diff_update_lines(
info, &line, bufs[2].ptr, bufs[2].size); info, &line, bufs[2].ptr, bufs[2].size);
...@@ -172,7 +182,6 @@ static int git_xdiff(git_diff_output *output, git_patch *patch) ...@@ -172,7 +182,6 @@ static int git_xdiff(git_diff_output *output, git_patch *patch)
git_xdiff_output *xo = (git_xdiff_output *)output; git_xdiff_output *xo = (git_xdiff_output *)output;
git_xdiff_info info; git_xdiff_info info;
git_diff_find_context_payload findctxt; git_diff_find_context_payload findctxt;
mmfile_t xd_old_data, xd_new_data;
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
info.patch = patch; info.patch = patch;
...@@ -193,10 +202,10 @@ static int git_xdiff(git_diff_output *output, git_patch *patch) ...@@ -193,10 +202,10 @@ static int git_xdiff(git_diff_output *output, git_patch *patch)
* updates are needed to xo->params.flags * updates are needed to xo->params.flags
*/ */
git_patch__old_data(&xd_old_data.ptr, &xd_old_data.size, patch); git_patch__old_data(&info.xd_old_data.ptr, &info.xd_old_data.size, patch);
git_patch__new_data(&xd_new_data.ptr, &xd_new_data.size, patch); git_patch__new_data(&info.xd_new_data.ptr, &info.xd_new_data.size, patch);
xdl_diff(&xd_old_data, &xd_new_data, xdl_diff(&info.xd_old_data, &info.xd_new_data,
&xo->params, &xo->config, &xo->callback); &xo->params, &xo->config, &xo->callback);
git_diff_find_context_clear(&findctxt); git_diff_find_context_clear(&findctxt);
......
...@@ -275,6 +275,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void) ...@@ -275,6 +275,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void)
cl_assert_equal_s("Ivory their outposts were--the guardrooms of them gilded,\n", actual.ptr); cl_assert_equal_s("Ivory their outposts were--the guardrooms of them gilded,\n", actual.ptr);
cl_assert_equal_i(6, line->old_lineno); cl_assert_equal_i(6, line->old_lineno);
cl_assert_equal_i(6, line->new_lineno); cl_assert_equal_i(6, line->new_lineno);
cl_assert_equal_i(-1, line->content_offset);
cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 3)); cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 3));
cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)line->origin); cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)line->origin);
...@@ -282,6 +283,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void) ...@@ -282,6 +283,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void)
cl_assert_equal_s("All the world went softly when it walked before my Cities--\n", actual.ptr); cl_assert_equal_s("All the world went softly when it walked before my Cities--\n", actual.ptr);
cl_assert_equal_i(9, line->old_lineno); cl_assert_equal_i(9, line->old_lineno);
cl_assert_equal_i(-1, line->new_lineno); cl_assert_equal_i(-1, line->new_lineno);
cl_assert_equal_i(252, line->content_offset);
cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 12)); cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 12));
cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)line->origin); cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)line->origin);
...@@ -289,6 +291,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void) ...@@ -289,6 +291,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void)
cl_assert_equal_s("This is some new text;\n", actual.ptr); cl_assert_equal_s("This is some new text;\n", actual.ptr);
cl_assert_equal_i(-1, line->old_lineno); cl_assert_equal_i(-1, line->old_lineno);
cl_assert_equal_i(9, line->new_lineno); cl_assert_equal_i(9, line->new_lineno);
cl_assert_equal_i(252, line->content_offset);
/* check hunk 1 */ /* check hunk 1 */
...@@ -309,6 +312,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void) ...@@ -309,6 +312,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void)
cl_assert_equal_s("My rulers and their treasure and their unborn populations,\n", actual.ptr); cl_assert_equal_s("My rulers and their treasure and their unborn populations,\n", actual.ptr);
cl_assert_equal_i(31, line->old_lineno); cl_assert_equal_i(31, line->old_lineno);
cl_assert_equal_i(25, line->new_lineno); cl_assert_equal_i(25, line->new_lineno);
cl_assert_equal_i(-1, line->content_offset);
cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 1, 3)); cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 1, 3));
cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)line->origin); cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)line->origin);
...@@ -316,6 +320,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void) ...@@ -316,6 +320,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void)
cl_assert_equal_s("The Daughters of the Palace whom they cherished in my Cities,\n", actual.ptr); cl_assert_equal_s("The Daughters of the Palace whom they cherished in my Cities,\n", actual.ptr);
cl_assert_equal_i(34, line->old_lineno); cl_assert_equal_i(34, line->old_lineno);
cl_assert_equal_i(-1, line->new_lineno); cl_assert_equal_i(-1, line->new_lineno);
cl_assert_equal_i(1468, line->content_offset);
cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 1, 12)); cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 1, 12));
cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)line->origin); cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)line->origin);
...@@ -323,6 +328,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void) ...@@ -323,6 +328,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void)
cl_assert_equal_s("Another replacement;\n", actual.ptr); cl_assert_equal_s("Another replacement;\n", actual.ptr);
cl_assert_equal_i(-1, line->old_lineno); cl_assert_equal_i(-1, line->old_lineno);
cl_assert_equal_i(28, line->new_lineno); cl_assert_equal_i(28, line->new_lineno);
cl_assert_equal_i(1066, line->content_offset);
git_patch_free(patch); git_patch_free(patch);
git_diff_free(diff); git_diff_free(diff);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment