ref: 5eb5831b056f59d389801e0f5358b2be85a4b82c
parent: c220d0acc67b3f5e0e8af2bbe41fa8e367e6aa60
author: Ori Bernstein <ori@eigenstate.org>
date: Thu Jul 25 22:44:21 EDT 2024
git/query: use git entry sorting when computing dir diff directories need to sort as though they end with a '/', when running through them for comparison, otherwise we flag files as added and removed spuriously, leading to them incorrectly getting deleted when merging commits.
--- a/sys/src/cmd/git/git.h
+++ b/sys/src/cmd/git/git.h
@@ -282,6 +282,7 @@
void unref(Object *);
void cache(Object *);
Object *emptydir(void);
+int entcmp(void*, void*);
/* object sets */
void osinit(Objset *);
--- a/sys/src/cmd/git/query.c
+++ b/sys/src/cmd/git/query.c
@@ -78,7 +78,7 @@
be = bp + b->tree->nent;
}
while(ap != ae && bp != be){
- c = strcmp(ap->name, bp->name);
+ c = entcmp(ap, bp);
if(c == 0){
if(ap->mode == bp->mode && hasheq(&ap->h, &bp->h))
goto next;
--- a/sys/src/cmd/git/save.c
+++ b/sys/src/cmd/git/save.c
@@ -54,33 +54,6 @@
return a-> order < b->order ? -1 : 1;
}
-int
-entcmp(void *pa, void *pb)
-{
- char abuf[256], bbuf[256], *ae, *be;
- Dirent *a, *b;
-
- a = pa;
- b = pb;
- /*
- * If the files have the same name, they're equal.
- * Otherwise, If they're trees, they sort as thoug
- * there was a trailing slash.
- *
- * Wat.
- */
- if(strcmp(a->name, b->name) == 0)
- return 0;
-
- ae = seprint(abuf, abuf + sizeof(abuf) - 1, a->name);
- be = seprint(bbuf, bbuf + sizeof(bbuf) - 1, b->name);
- if(a->mode & DMDIR)
- *ae = '/';
- if(b->mode & DMDIR)
- *be = '/';
- return strcmp(abuf, bbuf);
-}
-
static int
bwrite(void *p, void *buf, int nbuf)
{
--- a/sys/src/cmd/git/util.c
+++ b/sys/src/cmd/git/util.c
@@ -35,6 +35,34 @@
}
int
+entcmp(void *pa, void *pb)
+{
+ char abuf[256], bbuf[256], *ae, *be;
+ Dirent *a, *b;
+ int r;
+
+ a = pa;
+ b = pb;
+ /*
+ * If the files have the same name, they're equal.
+ * Otherwise, If they're trees, they sort as thoug
+ * there was a trailing slash.
+ *
+ * Wat.
+ */
+ r = strcmp(a->name, b->name);
+ if(r == 0 || (a->mode&DMDIR) == 0 && (b->mode&DMDIR) == 0)
+ return r;
+ ae = seprint(abuf, abuf + sizeof(abuf) - 1, a->name);
+ be = seprint(bbuf, bbuf + sizeof(bbuf) - 1, b->name);
+ if(a->mode & DMDIR)
+ *ae = '/';
+ if(b->mode & DMDIR)
+ *be = '/';
+ return strcmp(abuf, bbuf);
+}
+
+int
hasheq(Hash *a, Hash *b)
{
return memcmp(a->h, b->h, sizeof(a->h)) == 0;
--
⑨