Merge branch 'jk/fix-refresh-utime' into maint
authorJunio C Hamano <gitster@pobox.com>
Mon, 27 Jul 2015 19:21:40 +0000 (12:21 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 27 Jul 2015 19:21:40 +0000 (12:21 -0700)
Fix a small bug in our use of umask() return value.

* jk/fix-refresh-utime:
check_and_freshen_file: fix reversed success-check

1  2 
sha1_file.c
diff --combined sha1_file.c
index 0c70152c17fbf612bbdf0112bf12fe8f7a852761,5475d781d4961e24e0b3165c45c337cbaf2a3557..a68ae18dd8557e37dca82be3825cabe8f4cb53f4
@@@ -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;
        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;
  
                        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;
  
         * 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;
  
                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;
        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;