ref: f8d9a6b94708bd093c26066786d00b70be28fd59
parent: 473f56751bd725580802c936ac27978bf071f37d
author: Ori Bernstein <ori@eigenstate.org>
date: Mon May 26 04:58:18 EDT 2025
git/walk: fix bug with prefixed directories
--- a/sys/src/cmd/git/walk.c
+++ b/sys/src/cmd/git/walk.c
@@ -77,31 +77,53 @@
return r == 0;
}
+/*
+ * Tricky; we want to know if a file or dir is indexed,
+ * but a dir is only indexed if we have a file with dir/
+ * listed in the index.
+ *
+ * as a result, we need to add a virtual '/' at the end
+ * of the path if we're doing it, so if we have:
+ * foo.bar/x
+ * foo/y
+ * and we want to find out if foo is a directory we should
+ * descend into, we need to compare as though foo/ ended
+ * with a '/', or we'll bsearch down do foo.bar, not foo.
+ *
+ * this code resembles entcmp() in util.c, but differs
+ * because we're comparing whole paths.
+ */
int
-pathcmp(char *s, char *path, int dir, int len)
+pathcmp(char *sa, char *sb, int sadir)
{
- int r;
+ unsigned a, b;
- r = strncmp(s, path, len);
- if(r != 0)
- return r;
- if(path[len] == 0 || dir && path[len] == '/')
- return 0;
- return -1;
+ while(1){
+ a = *sa++;
+ b = *sb++;
+ if(a != b){
+ if(a == 0 && sadir)
+ a = '/';
+ if(a == '/' && b == '/')
+ return 0;
+ return (a > b) ? 1 : -1;
+ }
+ if(a == 0)
+ return 0;
+ }
}
int
indexed(char *path, int dir)
{
- int lo, hi, mid, r, len;
+ int lo, hi, mid, r;
r = -1;
lo = 0;
hi = nidx-1;
- len = strlen(path);
while(lo <= hi){
mid = (hi + lo) / 2;
- r = pathcmp(path, idx[mid].path, dir, len);
+ r = pathcmp(path, idx[mid].path, dir);
if(r < 0)
hi = mid-1;
else if(r > 0)
--
⑨