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.
This commit is contained in:
Ori Bernstein 2024-07-26 02:44:21 +00:00
parent c220d0acc6
commit 5eb5831b05
4 changed files with 30 additions and 28 deletions

View file

@ -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 *);

View file

@ -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;

View file

@ -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)
{

View file

@ -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)
{