From: Junio C Hamano Date: Thu, 10 Nov 2016 21:17:30 +0000 (-0800) Subject: Merge branch 'jk/alt-odb-cleanup' X-Git-Tag: v2.11.0-rc1~8 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/0538b84027a8aba7e8b805e3ec8fceb3990023e5?ds=inline;hp=-c Merge branch 'jk/alt-odb-cleanup' Fix a corner-case regression in a topic that graduated during the v2.11 cycle. * jk/alt-odb-cleanup: alternates: re-allow relative paths from environment --- 0538b84027a8aba7e8b805e3ec8fceb3990023e5 diff --combined sha1_file.c index 5457314e6a,fbafdbed94..9c86d1924a --- a/sha1_file.c +++ b/sha1_file.c @@@ -296,7 -296,7 +296,7 @@@ static int link_alt_odb_entry(const cha } strbuf_addstr(&pathbuf, entry); - if (strbuf_normalize_path(&pathbuf) < 0) { + if (strbuf_normalize_path(&pathbuf) < 0 && relative_base) { error("unable to normalize alternate object path: %s", pathbuf.buf); strbuf_release(&pathbuf); @@@ -370,7 -370,7 +370,7 @@@ void read_info_alternates(const char * int fd; path = xstrfmt("%s/info/alternates", relative_base); - fd = git_open_noatime(path); + fd = git_open(path); free(path); if (fd < 0) return; @@@ -663,7 -663,7 +663,7 @@@ static int check_packed_git_idx(const c struct pack_idx_header *hdr; size_t idx_size; uint32_t version, nr, i, *index; - int fd = git_open_noatime(path); + int fd = git_open(path); struct stat st; if (fd < 0) @@@ -1069,7 -1069,7 +1069,7 @@@ static int open_packed_git_1(struct pac while (pack_max_fds <= pack_open_fds && close_one_pack()) ; /* nothing */ - p->pack_fd = git_open_noatime(p->pack_name); + p->pack_fd = git_open(p->pack_name); if (p->pack_fd < 0 || fstat(p->pack_fd, &st)) return -1; pack_open_fds++; @@@ -1410,32 -1410,6 +1410,32 @@@ static void prepare_packed_git_one(cha strbuf_release(&path); } +static int approximate_object_count_valid; + +/* + * Give a fast, rough count of the number of objects in the repository. This + * ignores loose objects completely. If you have a lot of them, then either + * you should repack because your performance will be awful, or they are + * all unreachable objects about to be pruned, in which case they're not really + * interesting as a measure of repo size in the first place. + */ +unsigned long approximate_object_count(void) +{ + static unsigned long count; + if (!approximate_object_count_valid) { + struct packed_git *p; + + prepare_packed_git(); + count = 0; + for (p = packed_git; p; p = p->next) { + if (open_pack_index(p)) + continue; + count += p->num_objects; + } + } + return count; +} + static void *get_next_packed_git(const void *p) { return ((const struct packed_git *)p)->next; @@@ -1507,7 -1481,6 +1507,7 @@@ void prepare_packed_git(void void reprepare_packed_git(void) { + approximate_object_count_valid = 0; prepare_packed_git_run_once = 0; prepare_packed_git(); } @@@ -1586,9 -1559,9 +1586,9 @@@ int check_sha1_signature(const unsigne return hashcmp(sha1, real_sha1) ? -1 : 0; } -int git_open_noatime(const char *name) +int git_open(const char *name) { - static int sha1_file_open_flag = O_NOATIME; + static int sha1_file_open_flag = O_NOATIME | O_CLOEXEC; for (;;) { int fd; @@@ -1598,17 -1571,12 +1598,17 @@@ if (fd >= 0) return fd; - /* Might the failure be due to O_NOATIME? */ - if (errno != ENOENT && sha1_file_open_flag) { - sha1_file_open_flag = 0; + /* Try again w/o O_CLOEXEC: the kernel might not support it */ + if ((sha1_file_open_flag & O_CLOEXEC) && errno == EINVAL) { + sha1_file_open_flag &= ~O_CLOEXEC; continue; } + /* Might the failure be due to O_NOATIME? */ + if (errno != ENOENT && (sha1_file_open_flag & O_NOATIME)) { + sha1_file_open_flag &= ~O_NOATIME; + continue; + } return -1; } } @@@ -1637,7 -1605,7 +1637,7 @@@ static int open_sha1_file(const unsigne struct alternate_object_database *alt; int most_interesting_errno; - fd = git_open_noatime(sha1_file_name(sha1)); + fd = git_open(sha1_file_name(sha1)); if (fd >= 0) return fd; most_interesting_errno = errno; @@@ -1645,7 -1613,7 +1645,7 @@@ prepare_alt_odb(); for (alt = alt_odb_list; alt; alt = alt->next) { const char *path = alt_sha1_path(alt, sha1); - fd = git_open_noatime(path); + fd = git_open(path); if (fd >= 0) return fd; if (most_interesting_errno == ENOENT) @@@ -1884,9 -1852,11 +1884,9 @@@ static int parse_sha1_header_extended(c int parse_sha1_header(const char *hdr, unsigned long *sizep) { - struct object_info oi; + struct object_info oi = OBJECT_INFO_INIT; oi.sizep = sizep; - oi.typename = NULL; - oi.typep = NULL; return parse_sha1_header_extended(hdr, &oi, LOOKUP_REPLACE_OBJECT); } @@@ -2124,8 -2094,8 +2124,8 @@@ unwind goto out; } -static int packed_object_info(struct packed_git *p, off_t obj_offset, - struct object_info *oi) +int packed_object_info(struct packed_git *p, off_t obj_offset, + struct object_info *oi) { struct pack_window *w_curs = NULL; unsigned long size; @@@ -2896,7 -2866,7 +2896,7 @@@ int sha1_object_info_extended(const uns int sha1_object_info(const unsigned char *sha1, unsigned long *sizep) { enum object_type type; - struct object_info oi = {NULL}; + struct object_info oi = OBJECT_INFO_INIT; oi.typep = &type; oi.sizep = sizep; @@@ -3367,11 -3337,6 +3367,11 @@@ int has_object_file(const struct object return has_sha1_file(oid->hash); } +int has_object_file_with_flags(const struct object_id *oid, int flags) +{ + return has_sha1_file_with_flags(oid->hash, flags); +} + static void check_tree(const void *buf, size_t size) { struct tree_desc desc;