commit c4080dcdb82c89b83170f36df9ada4d604f19407
parent 32a587d492299ddf147a7a70e130cbebe6f20659
Author: Chris Bracken <chris@bracken.jp>
Date: Thu, 19 Feb 2026 13:35:09 +0900
delta: fix diffstat graph max width
Diffstat:
3 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/BUILD.gn b/BUILD.gn
@@ -68,6 +68,7 @@ executable("gout_tests") {
sources = [
"src/format_tests.c",
+ "src/git/delta_tests.c",
"src/gout_tests.c",
"src/gout_tests_main.c",
"src/utils_tests.c",
diff --git a/src/git/delta.c b/src/git/delta.c
@@ -184,7 +184,10 @@ char* gitdelta_graph(const GitDelta* delta,
size_t max_width) {
size_t changed = delta->addcount + delta->delcount;
if (changed > max_width && length > 0) {
- length = ((float)max_width / changed * length) + 1;
+ length = (length * max_width) / changed;
+ if (length == 0) {
+ length = 1;
+ }
}
char* graph = ecalloc(length + 1, sizeof(char));
memset(graph, c, length);
diff --git a/src/git/delta_tests.c b/src/git/delta_tests.c
@@ -0,0 +1,36 @@
+#include <stdlib.h>
+#include <string.h>
+#include "git/delta.h"
+#include "utest.h"
+
+// Ensure graph is scaled to the maximum width when linecount exceeds max_width.
+UTEST(delta, GraphScalingDoesNotExceedMaxWidth) {
+ GitDelta delta = {
+ .addcount = 50,
+ .delcount = 50,
+ };
+ size_t max_width = 10;
+ char* added = gitdelta_added_graph(&delta, max_width);
+ char* deleted = gitdelta_deleted_graph(&delta, max_width);
+ size_t total_len = strlen(added) + strlen(deleted);
+ EXPECT_LE(total_len, max_width);
+
+ free(added);
+ free(deleted);
+}
+
+// For small changes where sum < max_width, we expect exact line counts.
+UTEST(delta, GraphScalingSmallChanges) {
+ GitDelta delta = {
+ .addcount = 1,
+ .delcount = 1,
+ };
+ size_t max_width = 80;
+ char* added = gitdelta_added_graph(&delta, max_width);
+ char* deleted = gitdelta_deleted_graph(&delta, max_width);
+ EXPECT_EQ((size_t)1, strlen(added));
+ EXPECT_EQ((size_t)1, strlen(deleted));
+
+ free(added);
+ free(deleted);
+}