From: Junio C Hamano Date: Mon, 27 Jul 2015 19:21:40 +0000 (-0700) Subject: Merge branch 'jk/fix-refresh-utime' into maint X-Git-Tag: v2.4.7~12 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/7c696007ca422b9712549f27e17c2d778cb887c4?ds=inline;hp=-c Merge branch 'jk/fix-refresh-utime' into maint Fix a small bug in our use of umask() return value. * jk/fix-refresh-utime: check_and_freshen_file: fix reversed success-check --- 7c696007ca422b9712549f27e17c2d778cb887c4 diff --combined sha1_file.c index 0c70152c17,5475d781d4..a68ae18dd8 --- a/sha1_file.c +++ b/sha1_file.c @@@ -8,7 -8,6 +8,7 @@@ */ #include "cache.h" #include "string-list.h" +#include "lockfile.h" #include "delta.h" #include "pack.h" #include "blob.h" @@@ -443,6 -442,7 +443,7 @@@ void prepare_alt_odb(void read_info_alternates(get_object_directory(), 0); } + /* Returns 1 if we have successfully freshened the file, 0 otherwise. */ static int freshen_file(const char *fn) { struct utimbuf t; @@@ -450,11 -450,18 +451,18 @@@ return !utime(fn, &t); } + /* + * All of the check_and_freshen functions return 1 if the file exists and was + * freshened (if freshening was requested), 0 otherwise. If they return + * 0, you should not assume that it is safe to skip a write of the object (it + * either does not exist on disk, or has a stale mtime and may be subject to + * pruning). + */ static int check_and_freshen_file(const char *fn, int freshen) { if (access(fn, F_OK)) return 0; - if (freshen && freshen_file(fn)) + if (freshen && !freshen_file(fn)) return 0; return 1; } @@@ -707,8 -714,8 +715,8 @@@ static void mmap_limit_check(size_t len (uintmax_t)length, (uintmax_t)limit); } -void *xmmap(void *start, size_t length, - int prot, int flags, int fd, off_t offset) +void *xmmap_gently(void *start, size_t length, + int prot, int flags, int fd, off_t offset) { void *ret; @@@ -719,19 -726,12 +727,19 @@@ return NULL; release_pack_memory(length); ret = mmap(start, length, prot, flags, fd, offset); - if (ret == MAP_FAILED) - die_errno("Out of memory? mmap failed"); } return ret; } +void *xmmap(void *start, size_t length, + int prot, int flags, int fd, off_t offset) +{ + void *ret = xmmap_gently(start, length, prot, flags, fd, offset); + if (ret == MAP_FAILED) + die_errno("mmap failed"); + return ret; +} + void close_pack_windows(struct packed_git *p) { while (p->windows) { @@@ -1205,7 -1205,7 +1213,7 @@@ static void report_pack_garbage(struct if (!report_garbage) return; - sort_string_list(list); + string_list_sort(list); for (i = 0; i < list->nr; i++) { const char *path = list->items[i].string; @@@ -2480,8 -2480,10 +2488,8 @@@ static int fill_pack_entry(const unsign * answer, as it may have been deleted since the index was * loaded! */ - if (!is_pack_valid(p)) { - warning("packfile %s cannot be accessed", p->pack_name); + if (!is_pack_valid(p)) return 0; - } e->offset = offset; e->p = p; hashcpy(e->sha1, sha1); @@@ -2948,6 -2950,7 +2956,6 @@@ static int write_loose_object(const uns } /* Set it up */ - memset(&stream, 0, sizeof(stream)); git_deflate_init(&stream, zlib_compression_level); stream.next_out = compressed; stream.avail_out = sizeof(compressed); @@@ -3004,18 -3007,12 +3012,18 @@@ static int freshen_loose_object(const u static int freshen_packed_object(const unsigned char *sha1) { struct pack_entry e; - return find_pack_entry(sha1, &e) && freshen_file(e.p->pack_name); + if (!find_pack_entry(sha1, &e)) + return 0; + if (e.p->freshened) + return 1; + if (!freshen_file(e.p->pack_name)) + return 0; + e.p->freshened = 1; + return 1; } -int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *returnsha1) +int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1) { - unsigned char sha1[20]; char hdr[32]; int hdrlen; @@@ -3023,32 -3020,13 +3031,32 @@@ * it out into .git/objects/??/?{38} file. */ write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen); - if (returnsha1) - hashcpy(returnsha1, sha1); - if (freshen_loose_object(sha1) || freshen_packed_object(sha1)) + if (freshen_packed_object(sha1) || freshen_loose_object(sha1)) return 0; return write_loose_object(sha1, hdr, hdrlen, buf, len, 0); } +int hash_sha1_file_literally(const void *buf, unsigned long len, const char *type, + unsigned char *sha1, unsigned flags) +{ + char *header; + int hdrlen, status = 0; + + /* type string, SP, %lu of the length plus NUL must fit this */ + header = xmalloc(strlen(type) + 32); + write_sha1_file_prepare(buf, len, type, sha1, header, &hdrlen); + + if (!(flags & HASH_WRITE_OBJECT)) + goto cleanup; + if (freshen_packed_object(sha1) || freshen_loose_object(sha1)) + goto cleanup; + status = write_loose_object(sha1, header, hdrlen, buf, len, 0); + +cleanup: + free(header); + return status; +} + int force_object_loose(const unsigned char *sha1, time_t mtime) { void *buf; @@@ -3084,7 -3062,7 +3092,7 @@@ int has_sha1_pack(const unsigned char * return find_pack_entry(sha1, &e); } -int has_sha1_file(const unsigned char *sha1) +int has_sha1_file_with_flags(const unsigned char *sha1, int flags) { struct pack_entry e; @@@ -3092,8 -3070,6 +3100,8 @@@ return 1; if (has_loose_object(sha1)) return 1; + if (flags & HAS_SHA1_QUICK) + return 0; reprepare_packed_git(); return find_pack_entry(sha1, &e); } @@@ -3211,7 -3187,7 +3219,7 @@@ static int index_core(unsigned char *sh int ret; if (!size) { - ret = index_mem(sha1, NULL, size, type, path, flags); + ret = index_mem(sha1, "", size, type, path, flags); } else if (size <= SMALL_FILE_SIZE) { char *buf = xmalloc(size); if (size == read_in_full(fd, buf, size)) @@@ -3390,42 -3366,31 +3398,42 @@@ static int for_each_file_in_obj_subdir( return r; } -int for_each_loose_file_in_objdir(const char *path, +int for_each_loose_file_in_objdir_buf(struct strbuf *path, each_loose_object_fn obj_cb, each_loose_cruft_fn cruft_cb, each_loose_subdir_fn subdir_cb, void *data) { - struct strbuf buf = STRBUF_INIT; - size_t baselen; + size_t baselen = path->len; int r = 0; int i; - strbuf_addstr(&buf, path); - strbuf_addch(&buf, '/'); - baselen = buf.len; - for (i = 0; i < 256; i++) { - strbuf_addf(&buf, "%02x", i); - r = for_each_file_in_obj_subdir(i, &buf, obj_cb, cruft_cb, + strbuf_addf(path, "/%02x", i); + r = for_each_file_in_obj_subdir(i, path, obj_cb, cruft_cb, subdir_cb, data); - strbuf_setlen(&buf, baselen); + strbuf_setlen(path, baselen); if (r) break; } + return r; +} + +int for_each_loose_file_in_objdir(const char *path, + each_loose_object_fn obj_cb, + each_loose_cruft_fn cruft_cb, + each_loose_subdir_fn subdir_cb, + void *data) +{ + struct strbuf buf = STRBUF_INIT; + int r; + + strbuf_addstr(&buf, path); + r = for_each_loose_file_in_objdir_buf(&buf, obj_cb, cruft_cb, + subdir_cb, data); strbuf_release(&buf); + return r; } @@@ -3438,19 -3403,12 +3446,19 @@@ static int loose_from_alt_odb(struct al void *vdata) { struct loose_alt_odb_data *data = vdata; - return for_each_loose_file_in_objdir(alt->base, - data->cb, NULL, NULL, - data->data); + struct strbuf buf = STRBUF_INIT; + int r; + + /* copy base not including trailing '/' */ + strbuf_add(&buf, alt->base, alt->name - alt->base - 1); + r = for_each_loose_file_in_objdir_buf(&buf, + data->cb, NULL, NULL, + data->data); + strbuf_release(&buf); + return r; } -int for_each_loose_object(each_loose_object_fn cb, void *data) +int for_each_loose_object(each_loose_object_fn cb, void *data, unsigned flags) { struct loose_alt_odb_data alt; int r; @@@ -3460,9 -3418,6 +3468,9 @@@ if (r) return r; + if (flags & FOR_EACH_OBJECT_LOCAL_ONLY) + return 0; + alt.cb = cb; alt.data = data; return foreach_alt_odb(loose_from_alt_odb, &alt); @@@ -3487,15 -3442,13 +3495,15 @@@ static int for_each_object_in_pack(stru return r; } -int for_each_packed_object(each_packed_object_fn cb, void *data) +int for_each_packed_object(each_packed_object_fn cb, void *data, unsigned flags) { struct packed_git *p; int r = 0; prepare_packed_git(); for (p = packed_git; p; p = p->next) { + if ((flags & FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local) + continue; r = for_each_object_in_pack(p, cb, data); if (r) break;