"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
fix tog diff view with "Binary files differ"
To:
gameoftrees@openbsd.org
Date:
Thu, 6 Jan 2022 00:17:30 +0100

Download raw body.

Thread
When a diff contains a line of the form:

Binary files A and B differ

then scrolling across that line with tog can mess up the display.

In cases I have observed, the first two lines of the tog diff view
change from something like this:

  [22/81] diff $commithash1 $commithash2
  Binary files a/b/c and d/e/f differ
  blob - $blob_hash1

To this after scrolling down one line:

  [23/81] diff $commithash1 $commithash2
  /e/f differ
  blob - $blob_hash1

Scrolling down further now has a funny effect where the first line
of the display keeps showing a portion of the former line.

The reason for this is in the diff code. This code is supposed to mark
the offset of every line written to the diff output, but we forget to
do this in case we print a "Binary files differ" style line.

The patch below fixes the problem. ok?

(As usual for files derived from diff.git, I would commit this change
to diff.git first and then sync it to got.git)

diff dbe266a4450f73d753bf746c8343ca4c7dc41d18 /home/stsp/src/got
blob - 5fc87f7b15b8e6a3c41ccc01901815d9d52b741a
file + lib/diff_output_unidiff.c
--- lib/diff_output_unidiff.c
+++ lib/diff_output_unidiff.c
@@ -425,7 +425,8 @@ diff_output_unidiff(struct diff_output_info **output_i
 	bool show_function_prototypes = (flags & DIFF_FLAG_SHOW_PROTOTYPES);
 	bool force_text = (flags & DIFF_FLAG_FORCE_TEXT_DATA);
 	bool have_binary = (atomizer_flags & DIFF_ATOMIZER_FOUND_BINARY_DATA);
-	int i;
+	off_t outoff = 0, *offp;
+	int rc, i;
 
 	if (!result)
 		return EINVAL;
@@ -447,9 +448,23 @@ diff_output_unidiff(struct diff_output_info **output_i
 			if (t != CHUNK_MINUS && t != CHUNK_PLUS)
 				continue;
 
-			fprintf(dest, "Binary files %s and %s differ\n",
+			if (outinfo && outinfo->line_offsets.len > 0) {
+				unsigned int idx =
+				    outinfo->line_offsets.len - 1;
+				outoff = outinfo->line_offsets.head[idx];
+			}
+
+			rc = fprintf(dest, "Binary files %s and %s differ\n",
 			    diff_output_get_label_left(info),
 			    diff_output_get_label_right(info));
+			if (outinfo) {
+				ARRAYLIST_ADD(offp, outinfo->line_offsets);
+				if (offp == NULL)
+					return ENOMEM;
+				outoff += rc;
+				*offp = outoff;
+
+			}
 			break;
 		}