This adds an option (compile time, defined in the Makefile) to have a cache of extracted blobs so that different working directories can hardlink against them instead of creating new files for every checkout. You should only use this if you're sure the programs you use break links on modification and you care about storing many large working directories with few changes at the same time. Signed-Off-By: Daniel Barkalow <barkalow@iabervon.org> Index: Makefile =================================================================== --- 157b46ce1d82b3579e2e1258927b0d9bdbc033ab/Makefile (mode:100644 sha1:940ef8578cf469354002cd8feaec25d907015267) +++ 08f7700831e056ad710af69f91e3a8a705b6b2b1/Makefile (mode:100644 sha1:a60fa46404c0487158d232bd021e4798bc8df8de) @@ -2,6 +2,9 @@ # 1461501637330902918203684832716283019655932542976 hashes do not give you # enough guarantees about no collisions between objects ever hapenning. # +# -DUSE_HARDLINK_CACHE if you want a cache of files to be hardlinked +# to for unmodified checked out files. +# # -DNSEC if you want git to care about sub-second file mtimes and ctimes. # Note that you need some new glibc (at least >2.2.4) for this, and it will # BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely randomly Index: checkout-cache.c =================================================================== --- 157b46ce1d82b3579e2e1258927b0d9bdbc033ab/checkout-cache.c (mode:100644 sha1:5d3028df0a45329e45fff2006719c9267adeb946) +++ 08f7700831e056ad710af69f91e3a8a705b6b2b1/checkout-cache.c (mode:100644 sha1:338588259e17dd235fdc7db759d770004a760e15) @@ -34,6 +34,10 @@ */ #include "cache.h" +#ifdef USE_HARDLINK_CACHE +#define HARDLINK_CACHE ".git/blobs" +#endif /* USE_HARDLINK_CACHE */ + static int force = 0, quiet = 0; static void create_directories(const char *path) @@ -67,6 +71,80 @@ return fd; } +#ifdef HARDLINK_CACHE + +/* + * NOTE! This returns a statically allocated buffer, so you have to be + * careful about using it. Do a "strdup()" if you need to save the + * filename. + */ +char *sha1_blob_cache_file_name(const unsigned char *sha1) +{ + int i; + static char *name, *base; + + if (!base) { + char *sha1_file_directory = HARDLINK_CACHE; + 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]; + } + return base; +} + +static int write_entry(struct cache_entry *ce) +{ + int fd; + void *new; + unsigned long size; + long wrote; + char type[20]; + char *cache_name; + struct stat st; + + cache_name = sha1_blob_cache_file_name(ce->sha1); + + if (stat(cache_name, &st)) { + new = read_sha1_file(ce->sha1, type, &size); + if (!new || strcmp(type, "blob")) { + return error("checkout-cache: unable to read sha1 file of %s (%s)", + ce->name, sha1_to_hex(ce->sha1)); + } + fd = create_file(cache_name, ntohl(ce->ce_mode)); + if (fd < 0) { + free(new); + return error("checkout-cache: unable to create %s (%s)", + ce->name, strerror(errno)); + } + wrote = write(fd, new, size); + close(fd); + free(new); + if (wrote != size) + return error("checkout-cache: unable to write %s", + ce->name); + } + if (link(cache_name, ce->name)) { + if (errno == ENOENT) { + create_directories(ce->name); + link(cache_name, ce->name); + } + } + return 0; +} + +#else + static int write_entry(struct cache_entry *ce) { int fd; @@ -94,6 +172,8 @@ return 0; } +#endif + static int checkout_entry(struct cache_entry *ce) { struct stat st; - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.htmlReceived on Mon Apr 18 01:35:27 2005
This archive was generated by hypermail 2.1.8 : 2005-04-18 01:35:27 EST