From dfceb3d27be25dce3f9b727922771a86d08e3d4e Mon Sep 17 00:00:00 2001 From: Bryce Kwon Date: Sat, 7 Nov 2026 13:35:00 -1000 Subject: Keep a followed diff to the path it names A followed diff kept every path that started with the requested one, so following small.c took small.cpp in as well. A path now has to be the requested one or lie below it, as the pathspec of an unfollowed diff matches. --- source/ui-diff.c | 15 +++++++++++++-- tests/t0107-diff.sh | 27 +++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/source/ui-diff.c b/source/ui-diff.c index c696ab1..2974744 100644 --- a/source/ui-diff.c +++ b/source/ui-diff.c @@ -178,12 +178,23 @@ static void count_diff_lines(char *line, int len) render_line_fn(line, len); } +/* + * A path is kept when it is the prefix itself or lies below it, as the + * pathspec of a diff that does not follow would match it. + */ +static int path_in_prefix(const char *path, const char *prefix) +{ + const char *rest; + + return skip_prefix(path, prefix, &rest) && (!*rest || *rest == '/'); +} + static int show_filepair(struct diff_filepair *pair) { if (!current_prefix) return 1; - return starts_with(pair->one->path, current_prefix) || - starts_with(pair->two->path, current_prefix); + return path_in_prefix(pair->one->path, current_prefix) || + path_in_prefix(pair->two->path, current_prefix); } static void print_line(char *line, int len) diff --git a/tests/t0107-diff.sh b/tests/t0107-diff.sh index 2560c42..6caf539 100755 --- a/tests/t0107-diff.sh +++ b/tests/t0107-diff.sh @@ -368,6 +368,33 @@ test_expect_success 'a followed file is diffed as the rename alone' ' ! grep "a/file-1 b/file-1" tmp ' +# A followed path is matched as a pathspec would match it, the file itself or +# whatever lies below it, rather than every path starting with the same +# characters. +test_expect_success 'a followed path takes in no file it only prefixes' ' + mkrepo repos/prefixed 1 && + ( + cd repos/prefixed && + mkdir small.d && + echo c >small.c && + echo cpp >small.cpp && + echo d >small.d/f && + git add . && + git commit -m "add the files" && + echo C >small.c && + echo CPP >small.cpp && + echo D >small.d/f && + git commit -am "change the files" + ) && + cgitrc_repo prefixedrc prefixed enable-follow-links=1 && + cgit_ok prefixedrc "url=prefixed/diff/small.c&follow=1" >tmp && + grep "diff --git a/small.c b/small.c" tmp && + ! grep "small.cpp" tmp && + cgit_ok prefixedrc "url=prefixed/diff/small.d&follow=1" >tmp && + grep "diff --git a/small.d/f b/small.d/f" tmp && + ! grep "small.c" tmp +' + test_expect_success 'following with no path limits nothing' ' cgit_ok followrc "url=moved/commit/&follow=1" >tmp && grep "diff --git a/file-1 b/file-1" tmp && -- cgit 2.12.1