Code

Merge branch 'jk/commit-v-strip'
authorJunio C Hamano <gitster@pobox.com>
Sun, 16 Nov 2008 08:48:59 +0000 (00:48 -0800)
committerJunio C Hamano <gitster@pobox.com>
Sun, 16 Nov 2008 08:48:59 +0000 (00:48 -0800)
* jk/commit-v-strip:
  status: show "-v" diff even for initial commit
  wt-status: refactor initial commit printing
  define empty tree sha1 as a macro

1  2 
cache.h
sha1_file.c
wt-status.c

diff --combined cache.h
index 3b5f0c4c003a611b45e2ca9455681dc8a8347516,07795d9a816a9f17db2c19a6be8597d9ee1cd6f6..7efba7756d3658996f2cda4f79f1c5d2072ed51c
+++ b/cache.h
@@@ -262,7 -262,6 +262,7 @@@ static inline void remove_name_hash(str
  
  #define read_cache() read_index(&the_index)
  #define read_cache_from(path) read_index_from(&the_index, (path))
 +#define is_cache_unborn() is_index_unborn(&the_index)
  #define read_cache_unmerged() read_index_unmerged(&the_index)
  #define write_cache(newfd, cache, entries) write_index(&the_index, (newfd))
  #define discard_cache() discard_index(&the_index)
@@@ -369,7 -368,6 +369,7 @@@ extern int init_db(const char *template
  /* Initialize and use the cache information */
  extern int read_index(struct index_state *);
  extern int read_index_from(struct index_state *, const char *path);
 +extern int is_index_unborn(struct index_state *);
  extern int read_index_unmerged(struct index_state *);
  extern int write_index(const struct index_state *, int newfd);
  extern int discard_index(struct index_state *);
@@@ -530,6 -528,12 +530,12 @@@ static inline void hashclr(unsigned cha
  }
  extern int is_empty_blob_sha1(const unsigned char *sha1);
  
+ #define EMPTY_TREE_SHA1_HEX \
+       "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
+ #define EMPTY_TREE_SHA1_BIN \
+        "\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60" \
+        "\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04"
  int git_mkstemp(char *path, size_t n, const char *template);
  
  /*
@@@ -574,16 -578,12 +580,16 @@@ extern int force_object_loose(const uns
  /* just like read_sha1_file(), but non fatal in presence of bad objects */
  extern void *read_object(const unsigned char *sha1, enum object_type *type, unsigned long *size);
  
 +/* global flag to enable extra checks when accessing packed objects */
 +extern int do_check_packed_object_crc;
 +
  extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned long size, const char *type);
  
  extern int move_temp_to_file(const char *tmpfile, const char *filename);
  
  extern int has_sha1_pack(const unsigned char *sha1, const char **ignore);
  extern int has_sha1_file(const unsigned char *sha1);
 +extern int has_loose_object_nonlocal(const unsigned char *sha1);
  
  extern int has_pack_file(const unsigned char *sha1);
  extern int has_pack_index(const unsigned char *sha1);
@@@ -692,8 -692,7 +698,8 @@@ extern struct packed_git 
        int index_version;
        time_t mtime;
        int pack_fd;
 -      int pack_local;
 +      unsigned pack_local:1,
 +               pack_keep:1;
        unsigned char sha1[20];
        /* something like ".git/objects/pack/xxxxx.pack" */
        char pack_name[FLEX_ARRAY]; /* more */
@@@ -765,7 -764,7 +771,7 @@@ extern const unsigned char *nth_packed_
  extern off_t nth_packed_object_offset(const struct packed_git *, uint32_t);
  extern off_t find_pack_entry_one(const unsigned char *, struct packed_git *);
  extern void *unpack_entry(struct packed_git *, off_t, enum object_type *, unsigned long *);
 -extern unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep);
 +extern unsigned long unpack_object_header_buffer(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep);
  extern unsigned long get_size_from_delta(struct packed_git *, struct pack_window **, off_t);
  extern const char *packed_object_info_detail(struct packed_git *, off_t, unsigned long *, unsigned long *, unsigned int *, unsigned char *);
  extern int matches_pack_name(struct packed_git *p, const char *name);
diff --combined sha1_file.c
index 0fa65baa59de4db058ca6a41bba29ac78eab2643,1489d04d032d2890a6d54dc4e9d2ad926b8636cc..75a748a644f8f11c7bcb372fe74fbfb00faf1796
@@@ -423,30 -423,23 +423,30 @@@ void prepare_alt_odb(void
        read_info_alternates(get_object_directory(), 0);
  }
  
 -static int has_loose_object(const unsigned char *sha1)
 +static int has_loose_object_local(const unsigned char *sha1)
  {
        char *name = sha1_file_name(sha1);
 -      struct alternate_object_database *alt;
 +      return !access(name, F_OK);
 +}
  
 -      if (!access(name, F_OK))
 -              return 1;
 +int has_loose_object_nonlocal(const unsigned char *sha1)
 +{
 +      struct alternate_object_database *alt;
        prepare_alt_odb();
        for (alt = alt_odb_list; alt; alt = alt->next) {
 -              name = alt->name;
 -              fill_sha1_path(name, sha1);
 +              fill_sha1_path(alt->name, sha1);
                if (!access(alt->base, F_OK))
                        return 1;
        }
        return 0;
  }
  
 +static int has_loose_object(const unsigned char *sha1)
 +{
 +      return has_loose_object_local(sha1) ||
 +             has_loose_object_nonlocal(sha1);
 +}
 +
  static unsigned int pack_used_ctr;
  static unsigned int pack_mmap_calls;
  static unsigned int peak_pack_open_windows;
@@@ -848,11 -841,6 +848,11 @@@ struct packed_git *add_packed_git(cons
                return NULL;
        }
        memcpy(p->pack_name, path, path_len);
 +
 +      strcpy(p->pack_name + path_len, ".keep");
 +      if (!access(p->pack_name, F_OK))
 +              p->pack_keep = 1;
 +
        strcpy(p->pack_name + path_len, ".pack");
        if (stat(p->pack_name, &st) || !S_ISREG(st.st_mode)) {
                free(p);
@@@ -1122,8 -1110,7 +1122,8 @@@ static int legacy_loose_object(unsigne
                return 0;
  }
  
 -unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep)
 +unsigned long unpack_object_header_buffer(const unsigned char *buf,
 +              unsigned long len, enum object_type *type, unsigned long *sizep)
  {
        unsigned shift;
        unsigned char c;
        size = c & 15;
        shift = 4;
        while (c & 0x80) {
 -              if (len <= used)
 -                      return 0;
 -              if (sizeof(long) * 8 <= shift)
 +              if (len <= used || sizeof(long) * 8 <= shift) {
 +                      error("bad object header");
                        return 0;
 +              }
                c = buf[used++];
                size += (c & 0x7f) << shift;
                shift += 7;
@@@ -1177,7 -1164,7 +1177,7 @@@ static int unpack_sha1_header(z_stream 
         * really worth it and we don't write it any longer.  But we
         * can still read it.
         */
 -      used = unpack_object_header_gently(map, mapsize, &type, &size);
 +      used = unpack_object_header_buffer(map, mapsize, &type, &size);
        if (!used || !valid_loose_object_type[type])
                return -1;
        map += used;
@@@ -1326,10 -1313,8 +1326,10 @@@ unsigned long get_size_from_delta(struc
        } while ((st == Z_OK || st == Z_BUF_ERROR) &&
                 stream.total_out < sizeof(delta_head));
        inflateEnd(&stream);
 -      if ((st != Z_STREAM_END) && stream.total_out != sizeof(delta_head))
 -              die("delta data unpack-initial failed");
 +      if ((st != Z_STREAM_END) && stream.total_out != sizeof(delta_head)) {
 +              error("delta data unpack-initial failed");
 +              return 0;
 +      }
  
        /* Examine the initial part of the delta to figure out
         * the result size.
@@@ -1370,7 -1355,7 +1370,7 @@@ static off_t get_delta_base(struct pack
                        base_offset = (base_offset << 7) + (c & 127);
                }
                base_offset = delta_obj_offset - base_offset;
 -              if (base_offset >= delta_obj_offset)
 +              if (base_offset <= 0 || base_offset >= delta_obj_offset)
                        return 0;  /* out of bound */
                *curpos += used;
        } else if (type == OBJ_REF_DELTA) {
@@@ -1396,32 -1381,15 +1396,32 @@@ static int packed_delta_info(struct pac
        off_t base_offset;
  
        base_offset = get_delta_base(p, w_curs, &curpos, type, obj_offset);
 +      if (!base_offset)
 +              return OBJ_BAD;
        type = packed_object_info(p, base_offset, NULL);
 +      if (type <= OBJ_NONE) {
 +              struct revindex_entry *revidx;
 +              const unsigned char *base_sha1;
 +              revidx = find_pack_revindex(p, base_offset);
 +              if (!revidx)
 +                      return OBJ_BAD;
 +              base_sha1 = nth_packed_object_sha1(p, revidx->nr);
 +              mark_bad_packed_object(p, base_sha1);
 +              type = sha1_object_info(base_sha1, NULL);
 +              if (type <= OBJ_NONE)
 +                      return OBJ_BAD;
 +      }
  
        /* We choose to only get the type of the base object and
         * ignore potentially corrupt pack file that expects the delta
         * based on a base with a wrong size.  This saves tons of
         * inflate() calls.
         */
 -      if (sizep)
 +      if (sizep) {
                *sizep = get_size_from_delta(p, w_curs, curpos);
 +              if (*sizep == 0)
 +                      type = OBJ_BAD;
 +      }
  
        return type;
  }
@@@ -1443,11 -1411,10 +1443,11 @@@ static int unpack_object_header(struct 
         * insane, so we know won't exceed what we have been given.
         */
        base = use_pack(p, w_curs, *curpos, &left);
 -      used = unpack_object_header_gently(base, left, &type, sizep);
 -      if (!used)
 -              die("object offset outside of pack file");
 -      *curpos += used;
 +      used = unpack_object_header_buffer(base, left, &type, sizep);
 +      if (!used) {
 +              type = OBJ_BAD;
 +      } else
 +              *curpos += used;
  
        return type;
  }
@@@ -1531,9 -1498,8 +1531,9 @@@ static int packed_object_info(struct pa
                        *sizep = size;
                break;
        default:
 -              die("pack %s contains unknown object type %d",
 -                  p->pack_name, type);
 +              error("unknown object type %i at offset %"PRIuMAX" in %s",
 +                    type, (uintmax_t)obj_offset, p->pack_name);
 +              type = OBJ_BAD;
        }
        unuse_pack(&w_curs);
        return type;
@@@ -1697,12 -1663,9 +1697,12 @@@ static void *unpack_delta_entry(struct 
                 * This is costly but should happen only in the presence
                 * of a corrupted pack, and is better than failing outright.
                 */
 -              struct revindex_entry *revidx = find_pack_revindex(p, base_offset);
 -              const unsigned char *base_sha1 =
 -                                      nth_packed_object_sha1(p, revidx->nr);
 +              struct revindex_entry *revidx;
 +              const unsigned char *base_sha1;
 +              revidx = find_pack_revindex(p, base_offset);
 +              if (!revidx)
 +                      return NULL;
 +              base_sha1 = nth_packed_object_sha1(p, revidx->nr);
                error("failed to read delta base object %s"
                      " at offset %"PRIuMAX" from %s",
                      sha1_to_hex(base_sha1), (uintmax_t)base_offset,
        return result;
  }
  
 +int do_check_packed_object_crc;
 +
  void *unpack_entry(struct packed_git *p, off_t obj_offset,
                   enum object_type *type, unsigned long *sizep)
  {
        off_t curpos = obj_offset;
        void *data;
  
 +      if (do_check_packed_object_crc && p->index_version > 1) {
 +              struct revindex_entry *revidx = find_pack_revindex(p, obj_offset);
 +              unsigned long len = revidx[1].offset - obj_offset;
 +              if (check_pack_crc(p, &w_curs, obj_offset, len, revidx->nr)) {
 +                      const unsigned char *sha1 =
 +                              nth_packed_object_sha1(p, revidx->nr);
 +                      error("bad packed object CRC for %s",
 +                            sha1_to_hex(sha1));
 +                      mark_bad_packed_object(p, sha1);
 +                      return NULL;
 +              }
 +      }
 +
        *type = unpack_object_header(p, &w_curs, &curpos, sizep);
        switch (*type) {
        case OBJ_OFS_DELTA:
@@@ -2006,14 -1954,7 +2006,14 @@@ int sha1_object_info(const unsigned cha
                if (!find_pack_entry(sha1, &e, NULL))
                        return status;
        }
 -      return packed_object_info(e.p, e.offset, sizep);
 +
 +      status = packed_object_info(e.p, e.offset, sizep);
 +      if (status < 0) {
 +              mark_bad_packed_object(e.p, sha1);
 +              status = sha1_object_info(sha1, sizep);
 +      }
 +
 +      return status;
  }
  
  static void *read_packed_sha1(const unsigned char *sha1,
@@@ -2055,9 -1996,7 +2055,7 @@@ static struct cached_object 
  static int cached_object_nr, cached_object_alloc;
  
  static struct cached_object empty_tree = {
-       /* empty tree sha1: 4b825dc642cb6eb9a060e54bf8d69288fbee4904 */
-       "\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60"
-       "\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04",
+       EMPTY_TREE_SHA1_BIN,
        OBJ_TREE,
        "",
        0
diff --combined wt-status.c
index 6a7645ed86fd5879e959460011a8add015d392d9,ec91fba601bab8a6e9545952cf08a0a544c8107d..3edae43ce9d99b27ed69166d90db71bc3c219404
@@@ -185,31 -185,12 +185,12 @@@ static void wt_status_print_changed_cb(
                wt_status_print_trailer(s);
  }
  
- static void wt_status_print_initial(struct wt_status *s)
- {
-       int i;
-       struct strbuf buf = STRBUF_INIT;
-       if (active_nr) {
-               s->commitable = 1;
-               wt_status_print_cached_header(s);
-       }
-       for (i = 0; i < active_nr; i++) {
-               color_fprintf(s->fp, color(WT_STATUS_HEADER), "#\t");
-               color_fprintf_ln(s->fp, color(WT_STATUS_UPDATED), "new file: %s",
-                               quote_path(active_cache[i]->name, -1,
-                                          &buf, s->prefix));
-       }
-       if (active_nr)
-               wt_status_print_trailer(s);
-       strbuf_release(&buf);
- }
  static void wt_status_print_updated(struct wt_status *s)
  {
        struct rev_info rev;
        init_revisions(&rev, NULL);
-       setup_revisions(0, NULL, &rev, s->reference);
+       setup_revisions(0, NULL, &rev,
+               s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference);
        rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
        rev.diffopt.format_callback = wt_status_print_updated_cb;
        rev.diffopt.format_callback_data = s;
@@@ -298,20 -279,12 +279,21 @@@ static void wt_status_print_verbose(str
        struct rev_info rev;
  
        init_revisions(&rev, NULL);
-       setup_revisions(0, NULL, &rev, s->reference);
+       setup_revisions(0, NULL, &rev,
+               s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference);
        rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
        rev.diffopt.detect_rename = 1;
 +      DIFF_OPT_SET(&rev.diffopt, ALLOW_TEXTCONV);
        rev.diffopt.file = s->fp;
        rev.diffopt.close_file = 0;
 +      /*
 +       * If we're not going to stdout, then we definitely don't
 +       * want color, since we are going to the commit message
 +       * file (and even the "auto" setting won't work, since it
 +       * will have checked isatty on stdout).
 +       */
 +      if (s->fp != stdout)
 +              DIFF_OPT_CLR(&rev.diffopt, COLOR_DIFF);
        run_diff_index(&rev, 1);
  }
  
@@@ -360,12 -333,9 +342,9 @@@ void wt_status_print(struct wt_status *
                color_fprintf_ln(s->fp, color(WT_STATUS_HEADER), "#");
                color_fprintf_ln(s->fp, color(WT_STATUS_HEADER), "# Initial commit");
                color_fprintf_ln(s->fp, color(WT_STATUS_HEADER), "#");
-               wt_status_print_initial(s);
-       }
-       else {
-               wt_status_print_updated(s);
        }
  
+       wt_status_print_updated(s);
        wt_status_print_changed(s);
        if (wt_status_submodule_summary)
                wt_status_print_submodule_summary(s);
        else if (s->commitable)
                 fprintf(s->fp, "# Untracked files not listed (use -u option to show untracked files)\n");
  
-       if (s->verbose && !s->is_initial)
+       if (s->verbose)
                wt_status_print_verbose(s);
        if (!s->commitable) {
                if (s->amend)
@@@ -431,5 -401,5 +410,5 @@@ int git_status_config(const char *k, co
                        return error("Invalid untracked files mode '%s'", v);
                return 0;
        }
 -      return git_color_default_config(k, v, cb);
 +      return git_diff_ui_config(k, v, cb);
  }