summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2006-02-23 23:27:49 -0800
committerJunio C Hamano <junkio@cox.net>2006-02-23 23:51:01 -0800
commiteeef7135fed9b8784627c4c96e125241c06c65e1 (patch)
treee9f654640c1edbe0046b72b78bffbc994712149d
parentb76f6b627802d0a3c8bbf66fba0c090dbe56d509 (diff)
downloadgit-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.c33
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;
}