From 5eb5831b056f59d389801e0f5358b2be85a4b82c Mon Sep 17 00:00:00 2001 From: Ori Bernstein Date: Fri, 26 Jul 2024 02:44:21 +0000 Subject: [PATCH] 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. --- sys/src/cmd/git/git.h | 1 + sys/src/cmd/git/query.c | 2 +- sys/src/cmd/git/save.c | 27 --------------------------- sys/src/cmd/git/util.c | 28 ++++++++++++++++++++++++++++ 4 files changed, 30 insertions(+), 28 deletions(-) diff --git a/sys/src/cmd/git/git.h b/sys/src/cmd/git/git.h index dafec1b82..19dba5c64 100644 --- a/sys/src/cmd/git/git.h +++ b/sys/src/cmd/git/git.h @@ -282,6 +282,7 @@ Object *ref(Object *); void unref(Object *); void cache(Object *); Object *emptydir(void); +int entcmp(void*, void*); /* object sets */ void osinit(Objset *); diff --git a/sys/src/cmd/git/query.c b/sys/src/cmd/git/query.c index d0288313d..203e94271 100644 --- a/sys/src/cmd/git/query.c +++ b/sys/src/cmd/git/query.c @@ -78,7 +78,7 @@ difftrees(Object *a, Object *b) 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; diff --git a/sys/src/cmd/git/save.c b/sys/src/cmd/git/save.c index b41a528a6..0a6ec356d 100644 --- a/sys/src/cmd/git/save.c +++ b/sys/src/cmd/git/save.c @@ -54,33 +54,6 @@ idxcmp(void *pa, void *pb) 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) { diff --git a/sys/src/cmd/git/util.c b/sys/src/cmd/git/util.c index d53b0b7de..a5486aa2d 100644 --- a/sys/src/cmd/git/util.c +++ b/sys/src/cmd/git/util.c @@ -34,6 +34,34 @@ emptydir(void) return e; } +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) {