Merge branch 'tg/fix-check-order-with-split-index' into maint
authorJunio C Hamano <gitster@pobox.com>
Sat, 28 Mar 2015 16:33:07 +0000 (09:33 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sat, 28 Mar 2015 16:33:07 +0000 (09:33 -0700)
The split-index mode introduced at v2.3.0-rc0~41 was broken in the
codepath to protect us against a broken reimplementation of Git
that writes an invalid index with duplicated index entries, etc.

* tg/fix-check-order-with-split-index:
read-cache: fix reading of split index

1  2 
read-cache.c
diff --combined read-cache.c
index 8d71860f692ffa5deafe7f23774b1b9ab2f31378,6871af2602e4c6f31049246c3510bb43deb80665..1bf78a445fc9e397d1e8c7d91867b093bbcea775
@@@ -725,7 -725,7 +725,7 @@@ struct cache_entry *make_cache_entry(un
                unsigned int refresh_options)
  {
        int size, len;
 -      struct cache_entry *ce;
 +      struct cache_entry *ce, *ret;
  
        if (!verify_path(path)) {
                error("Invalid path '%s'", path);
        ce->ce_namelen = len;
        ce->ce_mode = create_ce_mode(mode);
  
 -      return refresh_cache_entry(ce, refresh_options);
 +      ret = refresh_cache_entry(ce, refresh_options);
 +      if (!ret) {
 +              free(ce);
 +              return NULL;
 +      } else {
 +              return ret;
 +      }
  }
  
  int ce_same_name(const struct cache_entry *a, const struct cache_entry *b)
@@@ -1486,18 -1480,25 +1486,25 @@@ static struct cache_entry *create_from_
        return ce;
  }
  
- static void check_ce_order(struct cache_entry *ce, struct cache_entry *next_ce)
+ static void check_ce_order(struct index_state *istate)
  {
-       int name_compare = strcmp(ce->name, next_ce->name);
-       if (0 < name_compare)
-               die("unordered stage entries in index");
-       if (!name_compare) {
-               if (!ce_stage(ce))
-                       die("multiple stage entries for merged file '%s'",
-                               ce->name);
-               if (ce_stage(ce) > ce_stage(next_ce))
-                       die("unordered stage entries for '%s'",
-                               ce->name);
+       unsigned int i;
+       for (i = 1; i < istate->cache_nr; i++) {
+               struct cache_entry *ce = istate->cache[i - 1];
+               struct cache_entry *next_ce = istate->cache[i];
+               int name_compare = strcmp(ce->name, next_ce->name);
+               if (0 < name_compare)
+                       die("unordered stage entries in index");
+               if (!name_compare) {
+                       if (!ce_stage(ce))
+                               die("multiple stage entries for merged file '%s'",
+                                   ce->name);
+                       if (ce_stage(ce) > ce_stage(next_ce))
+                               die("unordered stage entries for '%s'",
+                                   ce->name);
+               }
        }
  }
  
@@@ -1562,9 -1563,6 +1569,6 @@@ int do_read_index(struct index_state *i
                ce = create_from_disk(disk_ce, &consumed, previous_name);
                set_index_entry(istate, i, ce);
  
-               if (i > 0)
-                       check_ce_order(istate->cache[i - 1], ce);
                src_offset += consumed;
        }
        strbuf_release(&previous_name_buf);
@@@ -1608,11 -1606,10 +1612,10 @@@ int read_index_from(struct index_state 
  
        ret = do_read_index(istate, path, 0);
        split_index = istate->split_index;
-       if (!split_index)
-               return ret;
-       if (is_null_sha1(split_index->base_sha1))
+       if (!split_index || is_null_sha1(split_index->base_sha1)) {
+               check_ce_order(istate);
                return ret;
+       }
  
        if (split_index->base)
                discard_index(split_index->base);
                                     sha1_to_hex(split_index->base_sha1)),
                    sha1_to_hex(split_index->base->sha1));
        merge_base_index(istate);
+       check_ce_order(istate);
        return ret;
  }