Merge branch 'jk/alt-odb-cleanup'
authorJunio C Hamano <gitster@pobox.com>
Thu, 10 Nov 2016 21:17:30 +0000 (13:17 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 10 Nov 2016 21:17:30 +0000 (13:17 -0800)
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

1  2 
sha1_file.c
diff --combined sha1_file.c
index 5457314e6aaaf1a30d33f68c8e1005f8db584564,fbafdbed94cfe810000fbf72dd5eaf54b1302d9c..9c86d1924a23e4c81369f34ec8e1058c2dd15c1f
@@@ -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;
                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;
        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;