diff options
author | Junio C Hamano <junkio@cox.net> | 2006-02-23 23:27:49 -0800 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2006-02-23 23:51:01 -0800 |
commit | eeef7135fed9b8784627c4c96e125241c06c65e1 (patch) | |
tree | e9f654640c1edbe0046b72b78bffbc994712149d | |
parent | b76f6b627802d0a3c8bbf66fba0c090dbe56d509 (diff) | |
download | git-eeef7135fed9b8784627c4c96e125241c06c65e1.tar.gz |
pack-objects: hash basename and direname a bit differently.
...so that "Makefile"s from different revs are sorted together,
separate from "t/Makefile"s, but close enough.
Signed-off-by: Junio C Hamano <junkio@cox.net>
-rw-r--r-- | pack-objects.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/pack-objects.c b/pack-objects.c index 2320bcf310..095bcb8286 100644 --- a/pack-objects.c +++ b/pack-objects.c @@ -445,18 +445,29 @@ struct name_path { int len; }; +#define DIRBITS 12 + static unsigned name_hash(struct name_path *path, const char *name) { struct name_path *p = path; const char *n = name + strlen(name); - unsigned hash = 0; + unsigned hash = 0, name_hash = 0, name_done = 0; if (n != name && n[-1] == '\n') n--; while (name <= --n) { unsigned char c = *n; + if (c == '/' && !name_done) { + name_hash = hash; + name_done = 1; + hash = 0; + } hash = hash * 11 + c; } + if (!name_done) { + name_hash = hash; + hash = 0; + } for (p = path; p; p = p->up) { hash = hash * 11 + '/'; n = p->elem + p->len; @@ -465,6 +476,26 @@ static unsigned name_hash(struct name_path *path, const char *name) hash = hash * 11 + c; } } + /* + * Make sure "Makefile" and "t/Makefile" are hashed separately + * but close enough. + */ + hash = (name_hash<<DIRBITS) | (hash & ((1U<<DIRBITS )-1)); + + if (0) { /* debug */ + n = name + strlen(name); + if (n != name && n[-1] == '\n') + n--; + while (name <= --n) + fputc(*n, stderr); + for (p = path; p; p = p->up) { + fputc('/', stderr); + n = p->elem + p->len; + while (p->elem <= --n) + fputc(*n, stderr); + } + fprintf(stderr, "\t%08x\n", hash); + } return hash; } |