X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=checkout-cache.c;h=73a1a8d6680cb11aa9616948ff5aa72f2caa66bb;hb=74b46e32cb3907a4a062a0f11de5773054b7c71a;hp=b1c086a7ce3ba7eb4ddfaa33d89ea39a57ad422e;hpb=33db5f4d9027a10e477ccf054b2c1ab94f74c85a;p=git.git diff --git a/checkout-cache.c b/checkout-cache.c index b1c086a7..73a1a8d6 100644 --- a/checkout-cache.c +++ b/checkout-cache.c @@ -36,22 +36,51 @@ static int force = 0, quiet = 0; +static void create_directories(const char *path) +{ + int len = strlen(path); + char *buf = malloc(len + 1); + const char *slash = path; + + while ((slash = strchr(slash+1, '/')) != NULL) { + len = slash - path; + memcpy(buf, path, len); + buf[len] = 0; + mkdir(buf, 0755); + } +} + +static int create_file(const char *path, unsigned int mode) +{ + int fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0600); + if (fd < 0) { + if (errno == ENOENT) { + create_directories(path); + fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0600); + } + } + if (fd >= 0) + fchmod(fd, mode); + return fd; +} + static int write_entry(struct cache_entry *ce) { int fd; void *new; unsigned long size; long wrote; + char type[20]; - new = read_sha1_file(ce->sha1, "blob", &size); - if (!new) { - fprintf(stderr, "checkout-cache: unable to read sha1 file of %s (%s)", + 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)); return -1; } - fd = open(ce->name, O_WRONLY | O_CREAT | O_TRUNC, 0600); + fd = create_file(ce->name, ce->st_mode); if (fd < 0) { - fprintf(stderr, "checkout-cache: unable to create %s (%s)", + fprintf(stderr, "checkout-cache: unable to create %s (%s)\n", ce->name, strerror(errno)); free(new); return -1; @@ -61,7 +90,7 @@ static int write_entry(struct cache_entry *ce) free(new); if (wrote == size) return 0; - fprintf(stderr, "checkout-cache: unable to write %s", ce->name); + fprintf(stderr, "checkout-cache: unable to write %s\n", ce->name); return -1; } @@ -72,11 +101,9 @@ static int checkout_entry(struct cache_entry *ce) if (!stat(ce->name, &st)) { unsigned changed = cache_match_stat(ce, &st); - if (!changed) - return 0; - if (!quiet) - fprintf(stderr, "checkout-cache: %s already exists", ce->name); - return -1; + if (changed && !quiet) + fprintf(stderr, "checkout-cache: %s already exists\n", ce->name); + return 0; } } return write_entry(ce); @@ -87,7 +114,7 @@ static int checkout_file(const char *name) int pos = cache_name_pos(name, strlen(name)); if (pos < 0) { if (!quiet) - fprintf(stderr, "checkout-cache: %s is not in the cache", name); + fprintf(stderr, "checkout-cache: %s is not in the cache\n", name); return -1; } return checkout_entry(active_cache[pos]); @@ -110,7 +137,7 @@ int main(int argc, char **argv) int i, force_filename = 0; if (read_cache() < 0) { - fprintf(stderr, "Invalid cache"); + fprintf(stderr, "Invalid cache\n"); exit(1); }