Merge branch 'jk/maint-ls-files-other' into maint
authorJunio C Hamano <gitster@pobox.com>
Sun, 2 Nov 2008 21:37:13 +0000 (13:37 -0800)
committerJunio C Hamano <gitster@pobox.com>
Sun, 2 Nov 2008 21:37:13 +0000 (13:37 -0800)
* jk/maint-ls-files-other:
refactor handling of "other" files in ls-files and status

1  2 
cache.h
read-cache.c
diff --combined cache.h
index 8ab2fd8fd082bc0c263fc055cab8e248b56985e0,76730cee61441ce694c48addf02e935237addc71..74339edaaa2bc5fbf3e920d66a8bca9cc5b785d3
+++ b/cache.h
@@@ -270,6 -270,7 +270,7 @@@ static inline void remove_name_hash(str
  #define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options))
  #define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options))
  #define cache_name_exists(name, namelen, igncase) index_name_exists(&the_index, (name), (namelen), (igncase))
+ #define cache_name_is_other(name, namelen) index_name_is_other(&the_index, (name), (namelen))
  #endif
  
  enum object_type {
@@@ -382,6 -383,7 +383,7 @@@ extern int add_to_index(struct index_st
  extern int add_file_to_index(struct index_state *, const char *path, int flags);
  extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh);
  extern int ce_same_name(struct cache_entry *a, struct cache_entry *b);
+ extern int index_name_is_other(const struct index_state *, const char *, int);
  
  /* do stat comparison even if CE_VALID is true */
  #define CE_MATCH_IGNORE_VALID         01
@@@ -411,8 -413,6 +413,8 @@@ struct lock_file 
        char on_list;
        char filename[PATH_MAX];
  };
 +#define LOCK_DIE_ON_ERROR 1
 +#define LOCK_NODEREF 2
  extern int hold_lock_file_for_update(struct lock_file *, const char *path, int);
  extern int hold_lock_file_for_append(struct lock_file *, const char *path, int);
  extern int commit_lock_file(struct lock_file *);
diff --combined read-cache.c
index 15e1a9d471daa2fd5c54a9f8562b1dfc52161213,4e067e489743aca27dc13e3d04d4e41f4ffec95b..967f483f783693eff4fd4e252dae7a0cc8b12ada
@@@ -1460,28 -1460,51 +1460,56 @@@ int write_index(const struct index_stat
  int read_index_unmerged(struct index_state *istate)
  {
        int i;
 -      struct cache_entry **dst;
 -      struct cache_entry *last = NULL;
 +      int unmerged = 0;
  
        read_index(istate);
 -      dst = istate->cache;
        for (i = 0; i < istate->cache_nr; i++) {
                struct cache_entry *ce = istate->cache[i];
 -              if (ce_stage(ce)) {
 -                      remove_name_hash(ce);
 -                      if (last && !strcmp(ce->name, last->name))
 -                              continue;
 -                      cache_tree_invalidate_path(istate->cache_tree, ce->name);
 -                      last = ce;
 +              struct cache_entry *new_ce;
 +              int size, len;
 +
 +              if (!ce_stage(ce))
                        continue;
 -              }
 -              *dst++ = ce;
 +              unmerged = 1;
 +              len = strlen(ce->name);
 +              size = cache_entry_size(len);
 +              new_ce = xcalloc(1, size);
 +              hashcpy(new_ce->sha1, ce->sha1);
 +              memcpy(new_ce->name, ce->name, len);
 +              new_ce->ce_flags = create_ce_flags(len, 0);
 +              new_ce->ce_mode = ce->ce_mode;
 +              if (add_index_entry(istate, new_ce, 0))
 +                      return error("%s: cannot drop to stage #0",
 +                                   ce->name);
 +              i = index_name_pos(istate, new_ce->name, len);
        }
 -      istate->cache_nr = dst - istate->cache;
 -      return !!last;
 +      return unmerged;
  }
+ /*
+  * Returns 1 if the path is an "other" path with respect to
+  * the index; that is, the path is not mentioned in the index at all,
+  * either as a file, a directory with some files in the index,
+  * or as an unmerged entry.
+  *
+  * We helpfully remove a trailing "/" from directories so that
+  * the output of read_directory can be used as-is.
+  */
+ int index_name_is_other(const struct index_state *istate, const char *name,
+               int namelen)
+ {
+       int pos;
+       if (namelen && name[namelen - 1] == '/')
+               namelen--;
+       pos = index_name_pos(istate, name, namelen);
+       if (0 <= pos)
+               return 0;       /* exact match */
+       pos = -pos - 1;
+       if (pos < istate->cache_nr) {
+               struct cache_entry *ce = istate->cache[pos];
+               if (ce_namelen(ce) == namelen &&
+                   !memcmp(ce->name, name, namelen))
+                       return 0; /* Yup, this one exists unmerged */
+       }
+       return 1;
+ }