Only in git-0.04-b32-flat: base32val.pl diff -ur git-0.04/cache.h git-0.04-b32-flat/cache.h --- git-0.04/cache.h 2005-04-10 11:19:02.000000000 -0700 +++ git-0.04-b32-flat/cache.h 2005-04-13 23:54:43.000000000 -0700 @@ -99,9 +99,9 @@ extern int write_sha1_file(char *buf, unsigned len, unsigned char *return_sha1); extern int check_sha1_signature(unsigned char *sha1, void *buf, unsigned long size); -/* Convert to/from hex/sha1 representation */ -extern int get_sha1_hex(const char *hex, unsigned char *sha1); -extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */ +/* Convert to/from base64/sha1 representation */ +extern int get_sha1_b32(const char *hex, unsigned char *sha1); +extern char *sha1_to_b32(const unsigned char *sha1); /* static buffer result! */ /* General helper functions */ extern void usage(const char *err, ...); diff -ur git-0.04/cat-file.c git-0.04-b32-flat/cat-file.c --- git-0.04/cat-file.c 2005-04-09 11:16:47.000000000 -0700 +++ git-0.04-b32-flat/cat-file.c 2005-04-13 23:54:43.000000000 -0700 @@ -12,7 +12,7 @@ void *buf; unsigned long size; - if (argc != 3 || get_sha1_hex(argv[2], sha1)) + if (argc != 3 || get_sha1_b32(argv[2], sha1)) usage("cat-file: cat-file [-t | tagname] "); buf = read_sha1_file(sha1, type, &size); if (!buf) { diff -ur git-0.04/checkout-cache.c git-0.04-b32-flat/checkout-cache.c --- git-0.04/checkout-cache.c 2005-04-11 09:21:33.000000000 -0700 +++ git-0.04-b32-flat/checkout-cache.c 2005-04-13 23:54:43.000000000 -0700 @@ -75,7 +75,7 @@ new = read_sha1_file(ce->sha1, type, &size); if (!new || strcmp(type, "blob")) { fprintf(stderr, "checkout-cache: unable to read sha1 file of %s (%s)\n", - ce->name, sha1_to_hex(ce->sha1)); + ce->name, sha1_to_b32(ce->sha1)); return -1; } fd = create_file(ce->name, ce->st_mode); diff -ur git-0.04/commit-tree.c git-0.04-b32-flat/commit-tree.c --- git-0.04/commit-tree.c 2005-04-11 07:36:00.000000000 -0700 +++ git-0.04-b32-flat/commit-tree.c 2005-04-13 23:54:43.000000000 -0700 @@ -121,13 +121,13 @@ char *buffer; unsigned int size; - if (argc < 2 || get_sha1_hex(argv[1], tree_sha1) < 0) + if (argc < 2 || get_sha1_b32(argv[1], tree_sha1) < 0) usage("commit-tree [-p ]* < changelog"); for (i = 2; i < argc; i += 2) { char *a, *b; a = argv[i]; b = argv[i+1]; - if (!b || strcmp(a, "-p") || get_sha1_hex(b, parent_sha1[parents])) + if (!b || strcmp(a, "-p") || get_sha1_b32(b, parent_sha1[parents])) usage("commit-tree [-p ]* < changelog"); parents++; } @@ -153,7 +153,7 @@ remove_special(date); remove_special(realdate); init_buffer(&buffer, &size); - add_buffer(&buffer, &size, "tree %s\n", sha1_to_hex(tree_sha1)); + add_buffer(&buffer, &size, "tree %s\n", sha1_to_b32(tree_sha1)); /* * NOTE! This ordering means that the same exact tree merged with a @@ -161,7 +161,7 @@ * if everything else stays the same. */ for (i = 0; i < parents; i++) - add_buffer(&buffer, &size, "parent %s\n", sha1_to_hex(parent_sha1[i])); + add_buffer(&buffer, &size, "parent %s\n", sha1_to_b32(parent_sha1[i])); /* Person/date information */ add_buffer(&buffer, &size, "author %s <%s> %s\n", gecos, email, date); @@ -174,6 +174,6 @@ finish_buffer("commit ", &buffer, &size); write_sha1_file(buffer, size, commit_sha1); - printf("%s\n", sha1_to_hex(commit_sha1)); + printf("%s\n", sha1_to_b32(commit_sha1)); return 0; } diff -ur git-0.04/diff-tree.c git-0.04-b32-flat/diff-tree.c --- git-0.04/diff-tree.c 2005-04-11 07:36:23.000000000 -0700 +++ git-0.04-b32-flat/diff-tree.c 2005-04-13 23:54:43.000000000 -0700 @@ -64,7 +64,7 @@ tree = read_sha1_file(sha1, type, &size); if (!tree || strcmp(type, "tree")) - usage("corrupt tree sha %s", sha1_to_hex(sha1)); + usage("corrupt tree sha %s", sha1_to_b32(sha1)); show_tree(prefix, tree, size, newbase); @@ -73,7 +73,7 @@ return; } - printf("%s%o %s %s%s%c", prefix, mode, sha1_to_hex(sha1), base, path, 0); + printf("%s%o %s %s%s%c", prefix, mode, sha1_to_b32(sha1), base, path, 0); } static int compare_tree_entry(void *tree1, unsigned long size1, void *tree2, unsigned long size2, const char *base) @@ -82,7 +82,7 @@ const char *path1, *path2; const unsigned char *sha1, *sha2; int cmp, pathlen1, pathlen2; - char old_sha1_hex[50]; + char old_sha1_b32[28]; sha1 = extract(tree1, size1, &path1, &mode1); sha2 = extract(tree2, size2, &path2, &mode2); @@ -119,8 +119,8 @@ return retval; } - strcpy(old_sha1_hex, sha1_to_hex(sha1)); - printf("*%o->%o %s->%s %s%s%c", mode1, mode2, old_sha1_hex, sha1_to_hex(sha2), base, path1, 0); + strcpy(old_sha1_b32, sha1_to_b32(sha1)); + printf("*%o->%o %s->%s %s%s%c", mode1, mode2, old_sha1_b32, sha1_to_b32(sha2), base, path1, 0); return 0; } @@ -187,7 +187,7 @@ usage("diff-tree [-R] "); } - if (argc != 3 || get_sha1_hex(argv[1], old) || get_sha1_hex(argv[2], new)) + if (argc != 3 || get_sha1_b32(argv[1], old) || get_sha1_b32(argv[2], new)) usage("diff-tree "); return diff_tree_sha1(old, new, ""); } Only in git-0.04: .dircache diff -ur git-0.04/fsck-cache.c git-0.04-b32-flat/fsck-cache.c --- git-0.04/fsck-cache.c 2005-04-10 22:33:13.000000000 -0700 +++ git-0.04-b32-flat/fsck-cache.c 2005-04-14 00:00:08.000000000 -0700 @@ -20,6 +20,9 @@ static int nr_seen, alloc_seen, nr_needs, alloc_needs; +static const char base64sym[] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; + /* * These two functions build up a graph in memory about * what objects we've referenced, and found, and types.. @@ -68,8 +71,8 @@ if (lookup_seen(n->needs, n->tag)) continue; - strcpy(hex, sha1_to_hex(n->parent)); - printf("missing %s: %s referenced by %s\n", n->tag, sha1_to_hex(n->needs), hex); + strcpy(hex, sha1_to_b32(n->parent)); + printf("missing %s: %s referenced by %s\n", n->tag, sha1_to_b32(n->needs), hex); } /* Tell the user about things not referenced.. */ @@ -78,7 +81,7 @@ if (s->needed) continue; - printf("unreferenced %s: %s\n", s->tag, sha1_to_hex(s->sha1)); + printf("unreferenced %s: %s\n", s->tag, sha1_to_b32(s->sha1)); } } @@ -128,7 +131,7 @@ /* Warn about trees that don't do the recursive thing.. */ if (warn_old_tree && strchr(path, '/')) { - fprintf(stderr, "warning: fsck-cache: tree %s has full pathnames in it\n", sha1_to_hex(sha1)); + fprintf(stderr, "warning: fsck-cache: tree %s has full pathnames in it\n", sha1_to_b32(sha1)); warn_old_tree = 0; } @@ -147,20 +150,20 @@ if (memcmp(data, "tree ", 5)) return -1; - if (get_sha1_hex(data + 5, tree_sha1) < 0) + if (get_sha1_b32(data + 5, tree_sha1) < 0) return -1; mark_needs_sha1(sha1, "tree", tree_sha1); - data += 5 + 40 + 1; /* "tree " + + '\n' */ + data += 5 + 32 + 1; /* "tree " + + '\n' */ parents = 0; while (!memcmp(data, "parent ", 7)) { - if (get_sha1_hex(data + 7, parent_sha1) < 0) + if (get_sha1_b32(data + 7, parent_sha1) < 0) return -1; mark_needs_sha1(sha1, "commit", parent_sha1); - data += 7 + 40 + 1; /* "parent " + + '\n' */ + data += 7 + 32 + 1; /* "parent " + + '\n' */ parents++; } if (!parents) - printf("root: %s\n", sha1_to_hex(sha1)); + printf("root: %s\n", sha1_to_b32(sha1)); return 0; } @@ -182,7 +185,7 @@ static int fsck_name(char *hex) { unsigned char sha1[20]; - if (!get_sha1_hex(hex, sha1)) { + if (!get_sha1_b32(hex, sha1)) { unsigned long mapsize; void *map = map_sha1_file(sha1, &mapsize); if (map) { @@ -199,7 +202,7 @@ return -1; } -static int fsck_dir(int i, char *path) +static int fsck_dir(char *path) { DIR *dir = opendir(path); struct dirent *de; @@ -221,9 +224,8 @@ if (de->d_name[0] != '.') break; continue; - case 38: - sprintf(name, "%02x", i); - memcpy(name+2, de->d_name, len+1); + case 32: + memcpy(name, de->d_name, len+1); if (!fsck_name(name)) continue; } @@ -236,16 +238,12 @@ int main(int argc, char **argv) { int i; - char *sha1_dir; + char *sha1_dir, *db_dir; if (argc != 1) usage("fsck-cache"); sha1_dir = getenv(DB_ENVIRONMENT) ? : DEFAULT_DB_ENVIRONMENT; - for (i = 0; i < 256; i++) { - static char dir[4096]; - sprintf(dir, "%s/%02x", sha1_dir, i); - fsck_dir(i, dir); - } + fsck_dir(sha1_dir); check_connectivity(); return 0; } diff -ur git-0.04/init-db.c git-0.04-b32-flat/init-db.c --- git-0.04/init-db.c 2005-04-11 09:20:49.000000000 -0700 +++ git-0.04-b32-flat/init-db.c 2005-04-13 23:54:43.000000000 -0700 @@ -5,10 +5,13 @@ */ #include "cache.h" +static const char base64sym[] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; + int main(int argc, char **argv) { char *sha1_dir = getenv(DB_ENVIRONMENT), *path; - int len, i; + int len, i, j; if (mkdir(".dircache", 0755) < 0) { perror("unable to create .dircache"); @@ -41,16 +44,5 @@ exit(1); } } - path = malloc(len + 40); - memcpy(path, sha1_dir, len); - for (i = 0; i < 256; i++) { - sprintf(path+len, "/%02x", i); - if (mkdir(path, 0755) < 0) { - if (errno != EEXIST) { - perror(path); - exit(1); - } - } - } return 0; } diff -ur git-0.04/Makefile git-0.04-b32-flat/Makefile --- git-0.04/Makefile 2005-04-10 20:48:10.000000000 -0700 +++ git-0.04-b32-flat/Makefile 2005-04-13 23:51:50.000000000 -0700 @@ -1,4 +1,4 @@ -CFLAGS=-g -O3 -Wall +CFLAGS=-g -O -W -Wall CC=gcc PROG= update-cache show-diff init-db write-tree read-tree commit-tree \ diff -ur git-0.04/read-cache.c git-0.04-b32-flat/read-cache.c --- git-0.04/read-cache.c 2005-04-10 21:05:12.000000000 -0700 +++ git-0.04-b32-flat/read-cache.c 2005-04-14 00:17:17.000000000 -0700 @@ -3,6 +3,8 @@ * * Copyright (C) Linus Torvalds, 2005 */ + +#include #include "cache.h" const char *sha1_file_directory = NULL; @@ -19,43 +21,77 @@ exit(1); } -static unsigned hexval(char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - return ~0; -} +/* Base32 encoding, see RFC 3548. This is compatible with case-challenged + filesystems, and yet is short enough to fit in the dcache inline. */ + +static const char base32sym[] = "abcdefghijklmnopqrstuvwxyz234567"; -int get_sha1_hex(const char *hex, unsigned char *sha1) +static signed char base32val[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +}; + +int get_sha1_b32(const char *hex, unsigned char *sha1) { int i; - for (i = 0; i < 20; i++) { - unsigned int val = (hexval(hex[0]) << 4) | hexval(hex[1]); - if (val & ~0xff) + unsigned int d = 0; + int b = 0; + + for (i = 0; i < 32; i++) { + signed char v = base32val[(unsigned char)*hex++]; + if ( v < 0 ) return -1; - *sha1++ = val; - hex += 2; + d = (d << 5) + v; + b += 5; + + if ( b >= 8 ) { + b -= 8; + *sha1++ = d >> b; + } } return 0; } -char * sha1_to_hex(const unsigned char *sha1) +static void sha1_to_b32_p(const unsigned char * digest, char * output) { - static char buffer[50]; - static const char hex[] = "0123456789abcdef"; - char *buf = buffer; int i; - - for (i = 0; i < 20; i++) { - unsigned int val = *sha1++; - *buf++ = hex[val >> 4]; - *buf++ = hex[val & 0xf]; + const unsigned char *p; + char *q; + unsigned int d, b; + + p = digest; q = output; + d = 0; b = 0; + for ( i = 0 ; i < 20 ; i++ ) { + d = (d << 8) + *p++; + b += 8; + + while ( b >= 5 ) { + b -= 5; + *q++ = base32sym[(d >> b) & 0x1f]; + } } - return buffer; + *q = '\0'; +} + +char * sha1_to_b32(const unsigned char *digest) +{ + static unsigned char output[33]; /* 32 chars + final null */ + sha1_to_b32_p(digest, output); + return output; } /* @@ -65,7 +101,6 @@ */ char *sha1_file_name(const unsigned char *sha1) { - int i; static char *name, *base; if (!base) { @@ -73,18 +108,10 @@ int len = strlen(sha1_file_directory); base = malloc(len + 60); memcpy(base, sha1_file_directory, len); - memset(base+len, 0, 60); base[len] = '/'; - base[len+3] = '/'; name = base + len + 1; } - for (i = 0; i < 20; i++) { - static char hex[] = "0123456789abcdef"; - unsigned int val = sha1[i]; - char *pos = name + i*2 + (i > 0); - *pos++ = hex[val >> 4]; - *pos = hex[val & 0xf]; - } + sha1_to_b32_p(sha1, name); return base; } diff -ur git-0.04/read-tree.c git-0.04-b32-flat/read-tree.c --- git-0.04/read-tree.c 2005-04-10 10:28:53.000000000 -0700 +++ git-0.04-b32-flat/read-tree.c 2005-04-13 23:54:43.000000000 -0700 @@ -87,7 +87,7 @@ } continue; } - if (get_sha1_hex(arg, sha1) < 0) { + if (get_sha1_b32(arg, sha1) < 0) { fprintf(stderr, "read-tree [-m] \n"); goto out; } diff -ur git-0.04/show-diff.c git-0.04-b32-flat/show-diff.c --- git-0.04/show-diff.c 2005-04-09 11:16:47.000000000 -0700 +++ git-0.04-b32-flat/show-diff.c 2005-04-13 23:54:43.000000000 -0700 @@ -29,7 +29,7 @@ for (i = 0; i < entries; i++) { struct stat st; struct cache_entry *ce = active_cache[i]; - int n, changed; + int changed; unsigned long size; char type[20]; void *new; @@ -43,10 +43,8 @@ printf("%s: ok\n", ce->name); continue; } - printf("%.*s: ", ce->namelen, ce->name); - for (n = 0; n < 20; n++) - printf("%02x", ce->sha1[n]); - printf("\n"); + printf("%.*s: %s\n", + ce->namelen, ce->name, sha1_to_b32(ce->sha1)); new = read_sha1_file(ce->sha1, type, &size); show_differences(ce, &st, new, size); free(new); diff -ur git-0.04/write-tree.c git-0.04-b32-flat/write-tree.c --- git-0.04/write-tree.c 2005-04-10 09:13:10.000000000 -0700 +++ git-0.04-b32-flat/write-tree.c 2005-04-13 23:54:43.000000000 -0700 @@ -109,6 +109,6 @@ usage("no cache contents to write"); if (write_tree(active_cache, entries, "", 0, sha1) != entries) usage("write-tree: internal error"); - printf("%s\n", sha1_to_hex(sha1)); + printf("%s\n", sha1_to_b32(sha1)); return 0; }