Commit Diff


commit - 2f26640c77e9b4d1a303b6c3c7776ff75ad51111
commit + 7187fe972091ffb934d90ab11967d006868f8d7c
blob - eb5ea9058a20bee4cbe0ab59e51b057ac8067878
blob + 0fa63c3ef700e304d4e3c5950765ea9afd5d8a58
--- include/diff_output.h
+++ include/diff_output.h
@@ -61,6 +61,12 @@ int diff_chunk_get_right_end(const struct diff_chunk *
 void diff_chunk_context_get(struct diff_chunk_context *cc,
 				 const struct diff_result *r,
 				 int chunk_idx, int context_lines);
+void diff_chunk_context_load_change(struct diff_chunk_context *cc,
+				    int *nchunks_used,
+				    struct diff_result *result,
+				    int start_chunk_idx,
+				    int context_lines);
+
 struct diff_output_unidiff_state;
 struct diff_output_unidiff_state *diff_output_unidiff_state_alloc(void);
 void diff_output_unidiff_state_reset(struct diff_output_unidiff_state *state);
blob - 92805f9927a54bfd10e75d1fa3b36915ff80bd93
blob + a0dba87608e0c39d9e91584b1864e08f921d39d3
--- lib/diff_output_unidiff.c
+++ lib/diff_output_unidiff.c
@@ -110,6 +110,62 @@ diff_chunk_contexts_merge(struct diff_chunk_context *c
 	diff_ranges_merge(&cc->chunk, &other->chunk);
 	diff_ranges_merge(&cc->left, &other->left);
 	diff_ranges_merge(&cc->right, &other->right);
+}
+
+void
+diff_chunk_context_load_change(struct diff_chunk_context *cc,
+			       int *nchunks_used,
+			       struct diff_result *result,
+			       int start_chunk_idx,
+			       int context_lines)
+{
+	int i;
+	int seen_minus = 0, seen_plus = 0;
+
+	if (nchunks_used)
+		*nchunks_used = 0;
+
+	for (i = start_chunk_idx; i < result->chunks.len; i++) {
+		struct diff_chunk *chunk = &result->chunks.head[i];
+		enum diff_chunk_type t = diff_chunk_type(chunk);
+		struct diff_chunk_context next;
+
+		if (t != CHUNK_MINUS && t != CHUNK_PLUS) {
+			if (nchunks_used)
+				(*nchunks_used)++;
+			if (seen_minus && seen_plus)
+				break;
+			else
+				continue;
+		} else if (t == CHUNK_MINUS)
+			seen_minus = 1;
+		else if (t == CHUNK_PLUS)
+			seen_plus = 1;
+
+		if (diff_chunk_context_empty(cc)) {
+			/* Note down the start point, any number of subsequent
+			 * chunks may be joined up to this chunk by being
+			 * directly adjacent. */
+			diff_chunk_context_get(cc, result, i, context_lines);
+			if (nchunks_used)
+				(*nchunks_used)++;
+			continue;
+		}
+
+		/* There already is a previous chunk noted down for being
+		 * printed. Does it join up with this one? */
+		diff_chunk_context_get(&next, result, i, context_lines);
+
+		if (diff_chunk_contexts_touch(cc, &next)) {
+			/* This next context touches or overlaps the previous
+			 * one, join. */
+			diff_chunk_contexts_merge(cc, &next);
+			if (nchunks_used)
+				(*nchunks_used)++;
+			continue;
+		} else
+			break;
+	}
 }
 
 struct diff_output_unidiff_state {