Download raw body.
diff.git: Fix ed script output
Prior to this change ed script output was in the wrong order, i.e. in
the order diff_result provides and changes where missing added or
changed lines. ed edits need to be in reverse order to keep the edited
file in sync
---
lib/diff_output_edscript.c | 41 ++++++++++++++++++++++++++++----------
1 file changed, 30 insertions(+), 11 deletions(-)
diff --git a/lib/diff_output_edscript.c b/lib/diff_output_edscript.c
index 42d4d5b..3365d90 100644
--- a/lib/diff_output_edscript.c
+++ b/lib/diff_output_edscript.c
@@ -81,19 +81,34 @@ output_edscript_chunk(struct diff_output_info *outinfo,
}
} else {
/* change */
- if (left_len == 1 && right_len == 1) {
- rc = fprintf(dest, "%dc%d\n", left_start, right_start);
- } else if (left_len == 1) {
- rc = fprintf(dest, "%dc%d,%d\n", left_start,
- right_start, cc->right.end);
- } else if (right_len == 1) {
- rc = fprintf(dest, "%d,%dc%d\n", left_start,
- cc->left.end, right_start);
+ if (left_len == 1) {
+ rc = fprintf(dest, "%dc\n", left_start);
} else {
- rc = fprintf(dest, "%d,%dc%d,%d\n", left_start,
- cc->left.end, right_start, cc->right.end);
+ rc = fprintf(dest, "%d,%dc\n", left_start, cc->left.end);
+ }
+ }
+
+ /* Now write out the new lines in all the joined chunks. */
+ int c_idx;
+ for (c_idx = cc->chunk.start; c_idx < cc->chunk.end; c_idx++) {
+ const struct diff_chunk *c = &result->chunks.head[c_idx];
+ if (c->left_count && !c->right_count)
+ continue;
+ if (c->right_count && !c->left_count) {
+ rc = diff_output_lines(outinfo, dest,
+ c->solved ? "" : "?",
+ c->right_start, c->right_count);
+ fprintf(dest, ".\n");
+ }
+ if (rc)
+ return rc;
+ if (cc->chunk.end == result->chunks.len) {
+ rc = diff_output_trailing_newline_msg(outinfo, dest, c);
+ if (rc != DIFF_RC_OK)
+ return rc;
}
}
+
if (rc < 0)
return errno;
if (outinfo) {
@@ -151,7 +166,11 @@ diff_output_edscript(struct diff_output_info **output_info,
return DIFF_RC_OK;
}
- for (i = 0; i < result->chunks.len; i++) {
+ /*
+ * Changes in an ed script are in reverse order, the last change to the
+ * file has to be made first to keep state while making edits.
+ */
+ for (i = result->chunks.len-1; i >= 0 ; i--) {
struct diff_chunk *chunk = &result->chunks.head[i];
enum diff_chunk_type t = diff_chunk_type(chunk);
struct diff_chunk_context next;
diff.git: Fix ed script output