Merge branch 'es/name-hash-no-trailing-slash-in-dirs'
authorJunio C Hamano <gitster@pobox.com>
Thu, 17 Oct 2013 22:55:15 +0000 (15:55 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 17 Oct 2013 22:55:16 +0000 (15:55 -0700)
Clean up the internal of the name-hash mechanism used to work
around case insensitivity on some filesystems to cleanly fix a
long-standing API glitch where the caller of cache_name_exists()
that ask about a directory with a counted string was required to
have '/' at one location past the end of the string.

* es/name-hash-no-trailing-slash-in-dirs:
dir: revert work-around for retired dangerous behavior
name-hash: stop storing trailing '/' on paths in index_state.dir_hash
employ new explicit "exists in index?" API
name-hash: refactor polymorphic index_name_exists()

1  2 
cache.h
read-cache.c
diff --combined cache.h
index 51d6602cd9da8f8da6b5176ea352574bcc7036f5,038afe128e56a917f1b5e09d78e506b1831a0425..2d86b695a9fbf6828375e0818aaf503a9e46a427
+++ b/cache.h
@@@ -314,6 -314,8 +314,8 @@@ extern void free_name_hash(struct index
  #define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL, NULL)
  #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_dir_exists(name, namelen) index_dir_exists(&the_index, (name), (namelen))
+ #define cache_file_exists(name, namelen, igncase) index_file_exists(&the_index, (name), (namelen), (igncase))
  #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))
  #define resolve_undo_clear() resolve_undo_clear_index(&the_index)
@@@ -463,6 -465,8 +465,8 @@@ extern int write_index(struct index_sta
  extern int discard_index(struct index_state *);
  extern int unmerged_index(const struct index_state *);
  extern int verify_path(const char *path);
+ extern struct cache_entry *index_dir_exists(struct index_state *istate, const char *name, int namelen);
+ extern struct cache_entry *index_file_exists(struct index_state *istate, const char *name, int namelen, int igncase);
  extern struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen, int igncase);
  extern int index_name_pos(const struct index_state *, const char *name, int namelen);
  #define ADD_CACHE_OK_TO_ADD 1         /* Ok to add */
@@@ -880,7 -884,7 +884,7 @@@ extern char *resolve_refdup(const char 
  
  extern int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref);
  extern int dwim_log(const char *str, int len, unsigned char *sha1, char **ref);
 -extern int interpret_branch_name(const char *str, struct strbuf *);
 +extern int interpret_branch_name(const char *str, int len, struct strbuf *);
  extern int get_sha1_mb(const char *str, unsigned char *sha1);
  
  extern int refname_match(const char *abbrev_name, const char *full_name, const char **rules);
diff --combined read-cache.c
index 6bbe1b1fb3435247e1114cbf496cd9d7640f3def,e25de322d2d8433cab4200e4f3d008c9d68a82ac..33dd676ccbbd24e0bace49347f1f5d81b5099bcc
@@@ -643,7 -643,7 +643,7 @@@ int add_to_index(struct index_state *is
                        if (*ptr == '/') {
                                struct cache_entry *foundce;
                                ++ptr;
-                               foundce = index_name_exists(istate, ce->name, ptr - ce->name, ignore_case);
+                               foundce = index_dir_exists(istate, ce->name, ptr - ce->name - 1);
                                if (foundce) {
                                        memcpy((void *)startPtr, foundce->name + (startPtr - ce->name), ptr - startPtr);
                                        startPtr = ptr;
                }
        }
  
-       alias = index_name_exists(istate, ce->name, ce_namelen(ce), ignore_case);
+       alias = index_file_exists(istate, ce->name, ce_namelen(ce), ignore_case);
        if (alias && !ce_stage(alias) && !ie_match_stat(istate, alias, st, ce_option)) {
                /* Nothing changed, really */
                free(ce);
@@@ -1818,17 -1818,8 +1818,17 @@@ int write_index(struct index_state *ist
                        continue;
                if (!ce_uptodate(ce) && is_racy_timestamp(istate, ce))
                        ce_smudge_racily_clean_entry(ce);
 -              if (is_null_sha1(ce->sha1))
 -                      return error("cache entry has null sha1: %s", ce->name);
 +              if (is_null_sha1(ce->sha1)) {
 +                      static const char msg[] = "cache entry has null sha1: %s";
 +                      static int allow = -1;
 +
 +                      if (allow < 0)
 +                              allow = git_env_bool("GIT_ALLOW_NULL_SHA1", 0);
 +                      if (allow)
 +                              warning(msg, ce->name);
 +                      else
 +                              return error(msg, ce->name);
 +              }
                if (ce_write_entry(&c, newfd, ce, previous_name) < 0)
                        return -1;
        }