X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=sha1_file.c;h=8f577985afd89ef04a87b4373b5f1d4561600122;hb=aac17941320f7f73e5d411b152bfd041572e8a66;hp=d91e072f3e5480de3605fb3f1e581a938301bdfb;hpb=3c249c950649a37f2871a8b193f01a0640a20aef;p=git.git diff --git a/sha1_file.c b/sha1_file.c index d91e072f3..8f577985a 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -63,14 +63,27 @@ int get_sha1_file(const char *path, unsigned char *result) int get_sha1(const char *str, unsigned char *sha1) { static char pathname[PATH_MAX]; + static const char *prefix[] = { + "", + "refs", + "refs/tags", + "refs/heads", + "refs/snap", + NULL + }; + const char *gitdir; + const char **p; if (!get_sha1_hex(str, sha1)) return 0; - if (!get_sha1_file(str, sha1)) - return 0; - snprintf(pathname, sizeof(pathname), ".git/%s", str); - if (!get_sha1_file(pathname, sha1)) - return 0; + + gitdir = ".git"; + for (p = prefix; *p; p++) { + snprintf(pathname, sizeof(pathname), "%s/%s/%s", gitdir, *p, str); + if (!get_sha1_file(pathname, sha1)) + return 0; + } + return -1; } @@ -271,8 +284,9 @@ int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned cha unsigned char sha1[20]; SHA_CTX c; char *filename; + static char tmpfile[PATH_MAX]; char hdr[50]; - int fd, hdrlen; + int fd, hdrlen, ret; /* Generate the header */ hdrlen = sprintf(hdr, "%s %lu", type, len)+1; @@ -287,18 +301,28 @@ int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned cha memcpy(returnsha1, sha1, 20); filename = sha1_file_name(sha1); - fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666); - if (fd < 0) { - if (errno != EEXIST) - return -1; - + fd = open(filename, O_RDONLY); + if (fd >= 0) { /* - * We might do collision checking here, but we'd need to - * uncompress the old file and check it. Later. + * FIXME!!! We might do collision checking here, but we'd + * need to uncompress the old file and check it. Later. */ + close(fd); return 0; } + if (errno != ENOENT) { + fprintf(stderr, "sha1 file %s: %s", filename, strerror(errno)); + return -1; + } + + snprintf(tmpfile, sizeof(tmpfile), "%s/obj_XXXXXX", get_object_directory()); + fd = mkstemp(tmpfile); + if (fd < 0) { + fprintf(stderr, "unable to create temporary sha1 filename %s: %s", tmpfile, strerror(errno)); + return -1; + } + /* Set it up */ memset(&stream, 0, sizeof(stream)); deflateInit(&stream, Z_BEST_COMPRESSION); @@ -325,54 +349,21 @@ int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned cha if (write(fd, compressed, size) != size) die("unable to write file"); + fchmod(fd, 0444); close(fd); - - return 0; -} - -static inline int collision_check(char *filename, void *buf, unsigned int size) -{ -#ifdef COLLISION_CHECK - void *map; - int fd = open(filename, O_RDONLY); - struct stat st; - int cmp; - - /* Unreadable object, or object went away? Strange. */ - if (fd < 0) - return -1; - - if (fstat(fd, &st) < 0 || size != st.st_size) - return -1; - - map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); - close(fd); - if (map == MAP_FAILED) - return -1; - cmp = memcmp(buf, map, size); - munmap(map, size); - if (cmp) - return -1; -#endif - return 0; -} - -int write_sha1_buffer(const unsigned char *sha1, void *buf, unsigned int size) -{ - char *filename = sha1_file_name(sha1); - int fd; - fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666); - if (fd < 0) { - if (errno != EEXIST) + ret = link(tmpfile, filename); + if (ret < 0) + ret = errno; + unlink(tmpfile); + if (ret) { + if (ret != EEXIST) { + fprintf(stderr, "unable to write sha1 filename %s: %s", filename, strerror(ret)); return -1; - if (collision_check(filename, buf, size)) - return error("SHA1 collision detected!" - " This is bad, bad, BAD!\a\n"); - return 0; + } + /* FIXME!!! Collision check here ? */ } - write(fd, buf, size); - close(fd); + return 0; } @@ -447,3 +438,22 @@ int has_sha1_file(const unsigned char *sha1) return 1; return 0; } + +int index_fd(unsigned char *sha1, int fd, struct stat *st) +{ + unsigned long size = st->st_size; + void *buf; + int ret; + + buf = ""; + if (size) + buf = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); + close(fd); + if ((int)(long)buf == -1) + return -1; + + ret = write_sha1_file(buf, size, "blob", sha1); + if (size) + munmap(buf, size); + return ret; +}