Merge branch 'jk/noetcconfig'
authorJunio C Hamano <gitster@pobox.com>
Sun, 17 Feb 2008 01:56:51 +0000 (17:56 -0800)
committerJunio C Hamano <gitster@pobox.com>
Sun, 17 Feb 2008 01:56:51 +0000 (17:56 -0800)
* jk/noetcconfig:
fix config reading in tests
allow suppressing of global and system config

Conflicts:

cache.h

1  2 
builtin-config.c
cache.h
config.c
diff --combined builtin-config.c
index 077d8ef2df4ae38d668293cc35810b39e0488f6b,404bb449aec1e24012b390b1d76f05d4cc9c74af..2b9a4261d4e98281855ce856041eb730565a4869
@@@ -79,9 -79,10 +79,10 @@@ static int get_value(const char* key_, 
                local = getenv(CONFIG_LOCAL_ENVIRONMENT);
                if (!local)
                        local = repo_config = xstrdup(git_path("config"));
-               if (home)
+               if (git_config_global() && home)
                        global = xstrdup(mkpath("%s/.gitconfig", home));
-               system_wide = git_etc_gitconfig();
+               if (git_config_system())
+                       system_wide = git_etc_gitconfig();
        }
  
        key = xstrdup(key_);
@@@ -168,8 -169,6 +169,8 @@@ static char parsed_color[COLOR_MAXLEN]
  static int git_get_color_config(const char *var, const char *value)
  {
        if (!strcmp(var, get_color_slot)) {
 +              if (!value)
 +                      config_error_nonbool(var);
                color_parse(value, var, parsed_color);
                get_color_found = 1;
        }
diff --combined cache.h
index cdcabe92b6e51fcda60ec68cd0ab21ae11cca66f,af74e203b71333c47b898ce7b7a36eb6c4f1608b..efd31d8569c27ca18f2f7a7e599c115c8be9251a
+++ b/cache.h
@@@ -3,7 -3,6 +3,7 @@@
  
  #include "git-compat-util.h"
  #include "strbuf.h"
 +#include "hash.h"
  
  #include SHA1_HEADER
  #include <zlib.h>
@@@ -95,84 -94,48 +95,84 @@@ struct cache_time 
   * We save the fields in big-endian order to allow using the
   * index file over NFS transparently.
   */
 +struct ondisk_cache_entry {
 +      struct cache_time ctime;
 +      struct cache_time mtime;
 +      unsigned int dev;
 +      unsigned int ino;
 +      unsigned int mode;
 +      unsigned int uid;
 +      unsigned int gid;
 +      unsigned int size;
 +      unsigned char sha1[20];
 +      unsigned short flags;
 +      char name[FLEX_ARRAY]; /* more */
 +};
 +
  struct cache_entry {
 -      struct cache_time ce_ctime;
 -      struct cache_time ce_mtime;
 +      struct cache_entry *next;
 +      unsigned int ce_ctime;
 +      unsigned int ce_mtime;
        unsigned int ce_dev;
        unsigned int ce_ino;
        unsigned int ce_mode;
        unsigned int ce_uid;
        unsigned int ce_gid;
        unsigned int ce_size;
 +      unsigned int ce_flags;
        unsigned char sha1[20];
 -      unsigned short ce_flags;
        char name[FLEX_ARRAY]; /* more */
  };
  
  #define CE_NAMEMASK  (0x0fff)
  #define CE_STAGEMASK (0x3000)
 -#define CE_UPDATE    (0x4000)
  #define CE_VALID     (0x8000)
  #define CE_STAGESHIFT 12
  
 -#define create_ce_flags(len, stage) htons((len) | ((stage) << CE_STAGESHIFT))
 -#define ce_namelen(ce) (CE_NAMEMASK & ntohs((ce)->ce_flags))
 +/* In-memory only */
 +#define CE_UPDATE    (0x10000)
 +#define CE_REMOVE    (0x20000)
 +#define CE_UPTODATE  (0x40000)
 +#define CE_UNHASHED  (0x80000)
 +
 +static inline unsigned create_ce_flags(size_t len, unsigned stage)
 +{
 +      if (len >= CE_NAMEMASK)
 +              len = CE_NAMEMASK;
 +      return (len | (stage << CE_STAGESHIFT));
 +}
 +
 +static inline size_t ce_namelen(const struct cache_entry *ce)
 +{
 +      size_t len = ce->ce_flags & CE_NAMEMASK;
 +      if (len < CE_NAMEMASK)
 +              return len;
 +      return strlen(ce->name + CE_NAMEMASK) + CE_NAMEMASK;
 +}
 +
  #define ce_size(ce) cache_entry_size(ce_namelen(ce))
 -#define ce_stage(ce) ((CE_STAGEMASK & ntohs((ce)->ce_flags)) >> CE_STAGESHIFT)
 +#define ondisk_ce_size(ce) ondisk_cache_entry_size(ce_namelen(ce))
 +#define ce_stage(ce) ((CE_STAGEMASK & (ce)->ce_flags) >> CE_STAGESHIFT)
 +#define ce_uptodate(ce) ((ce)->ce_flags & CE_UPTODATE)
 +#define ce_mark_uptodate(ce) ((ce)->ce_flags |= CE_UPTODATE)
  
  #define ce_permissions(mode) (((mode) & 0100) ? 0755 : 0644)
  static inline unsigned int create_ce_mode(unsigned int mode)
  {
        if (S_ISLNK(mode))
 -              return htonl(S_IFLNK);
 +              return S_IFLNK;
        if (S_ISDIR(mode) || S_ISGITLINK(mode))
 -              return htonl(S_IFGITLINK);
 -      return htonl(S_IFREG | ce_permissions(mode));
 +              return S_IFGITLINK;
 +      return S_IFREG | ce_permissions(mode);
  }
  static inline unsigned int ce_mode_from_stat(struct cache_entry *ce, unsigned int mode)
  {
        extern int trust_executable_bit, has_symlinks;
        if (!has_symlinks && S_ISREG(mode) &&
 -          ce && S_ISLNK(ntohl(ce->ce_mode)))
 +          ce && S_ISLNK(ce->ce_mode))
                return ce->ce_mode;
        if (!trust_executable_bit && S_ISREG(mode)) {
 -              if (ce && S_ISREG(ntohl(ce->ce_mode)))
 +              if (ce && S_ISREG(ce->ce_mode))
                        return ce->ce_mode;
                return create_ce_mode(0666);
        }
        S_ISLNK(mode) ? S_IFLNK : S_ISDIR(mode) ? S_IFDIR : S_IFGITLINK)
  
  #define cache_entry_size(len) ((offsetof(struct cache_entry,name) + (len) + 8) & ~7)
 +#define ondisk_cache_entry_size(len) ((offsetof(struct ondisk_cache_entry,name) + (len) + 8) & ~7)
  
  struct index_state {
        struct cache_entry **cache;
        unsigned int cache_nr, cache_alloc, cache_changed;
        struct cache_tree *cache_tree;
        time_t timestamp;
 -      void *mmap;
 -      size_t mmap_size;
 +      void *alloc;
 +      unsigned name_hash_initialized : 1;
 +      struct hash_table name_hash;
  };
  
  extern struct index_state the_index;
  #define refresh_cache(flags) refresh_index(&the_index, (flags), 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_name_exists(name, namelen) index_name_exists(&the_index, (name), (namelen))
  #endif
  
  enum object_type {
@@@ -303,7 -263,6 +303,7 @@@ extern int read_index_from(struct index
  extern int write_index(struct index_state *, int newfd);
  extern int discard_index(struct index_state *);
  extern int verify_path(const char *path);
 +extern int index_name_exists(struct index_state *istate, const char *name, int namelen);
  extern int index_name_pos(struct index_state *, const char *name, int namelen);
  #define ADD_CACHE_OK_TO_ADD 1         /* Ok to add */
  #define ADD_CACHE_OK_TO_REPLACE 2     /* Ok to replace file/directory */
@@@ -625,13 -584,14 +625,16 @@@ extern int git_parse_ulong(const char *
  extern int git_config_int(const char *, const char *);
  extern unsigned long git_config_ulong(const char *, const char *);
  extern int git_config_bool(const char *, const char *);
 +extern int git_config_string(const char **, const char *, const char *);
  extern int git_config_set(const char *, const char *);
  extern int git_config_set_multivar(const char *, const char *, const char *, int);
  extern int git_config_rename_section(const char *, const char *);
  extern const char *git_etc_gitconfig(void);
  extern int check_repository_format_version(const char *var, const char *value);
+ extern int git_env_bool(const char *, int);
+ extern int git_config_system(void);
+ extern int git_config_global(void);
 +extern int config_error_nonbool(const char *);
  
  #define MAX_GITNAME (1000)
  extern char git_default_email[MAX_GITNAME];
@@@ -651,12 -611,12 +654,12 @@@ extern int write_or_whine_pipe(int fd, 
  
  /* pager.c */
  extern void setup_pager(void);
 -extern char *pager_program;
 +extern const char *pager_program;
  extern int pager_in_use(void);
  extern int pager_use_color;
  
 -extern char *editor_program;
 -extern char *excludes_file;
 +extern const char *editor_program;
 +extern const char *excludes_file;
  
  /* base85 */
  int decode_85(char *dst, const char *line, int linelen);
diff --combined config.c
index ad47dc34f05c6cb7e8fb25a2975de487c2a484d3,2f85e9d3e3bcf2cc5ddc87223a797b833846af5b..7881bbc7782b7937e450ad99c4bb6bda67c1f2e3
+++ b/config.c
@@@ -309,14 -309,6 +309,14 @@@ int git_config_bool(const char *name, c
        return git_config_int(name, value) != 0;
  }
  
 +int git_config_string(const char **dest, const char *var, const char *value)
 +{
 +      if (!value)
 +              return config_error_nonbool(var);
 +      *dest = xstrdup(value);
 +      return 0;
 +}
 +
  int git_default_config(const char *var, const char *value)
  {
        /* This needs a better name */
        }
  
        if (!strcmp(var, "user.name")) {
 +              if (!value)
 +                      return config_error_nonbool(var);
                strlcpy(git_default_name, value, sizeof(git_default_name));
                return 0;
        }
  
        if (!strcmp(var, "user.email")) {
 +              if (!value)
 +                      return config_error_nonbool(var);
                strlcpy(git_default_email, value, sizeof(git_default_email));
                return 0;
        }
  
 -      if (!strcmp(var, "i18n.commitencoding")) {
 -              git_commit_encoding = xstrdup(value);
 -              return 0;
 -      }
 -
 -      if (!strcmp(var, "i18n.logoutputencoding")) {
 -              git_log_output_encoding = xstrdup(value);
 -              return 0;
 -      }
 +      if (!strcmp(var, "i18n.commitencoding"))
 +              return git_config_string(&git_commit_encoding, var, value);
  
 +      if (!strcmp(var, "i18n.logoutputencoding"))
 +              return git_config_string(&git_log_output_encoding, var, value);
  
        if (!strcmp(var, "pager.color") || !strcmp(var, "color.pager")) {
                pager_use_color = git_config_bool(var,value);
                return 0;
        }
  
 -      if (!strcmp(var, "core.pager")) {
 -              pager_program = xstrdup(value);
 -              return 0;
 -      }
 +      if (!strcmp(var, "core.pager"))
 +              return git_config_string(&pager_program, var, value);
  
 -      if (!strcmp(var, "core.editor")) {
 -              editor_program = xstrdup(value);
 -              return 0;
 -      }
 +      if (!strcmp(var, "core.editor"))
 +              return git_config_string(&editor_program, var, value);
  
 -      if (!strcmp(var, "core.excludesfile")) {
 -              if (!value)
 -                      die("core.excludesfile without value");
 -              excludes_file = xstrdup(value);
 -              return 0;
 -      }
 +      if (!strcmp(var, "core.excludesfile"))
 +              return git_config_string(&excludes_file, var, value);
  
        if (!strcmp(var, "core.whitespace")) {
 +              if (!value)
 +                      return config_error_nonbool(var);
                whitespace_rule_cfg = parse_whitespace_rule(value);
                return 0;
        }
@@@ -493,6 -492,22 +493,22 @@@ const char *git_etc_gitconfig(void
        return system_wide;
  }
  
+ int git_env_bool(const char *k, int def)
+ {
+       const char *v = getenv(k);
+       return v ? git_config_bool(k, v) : def;
+ }
+ int git_config_system(void)
+ {
+       return !git_env_bool("GIT_CONFIG_NOSYSTEM", 0);
+ }
+ int git_config_global(void)
+ {
+       return !git_env_bool("GIT_CONFIG_NOGLOBAL", 0);
+ }
  int git_config(config_fn_t fn)
  {
        int ret = 0;
         * config file otherwise. */
        filename = getenv(CONFIG_ENVIRONMENT);
        if (!filename) {
-               if (!access(git_etc_gitconfig(), R_OK))
+               if (git_config_system() && !access(git_etc_gitconfig(), R_OK))
                        ret += git_config_from_file(fn, git_etc_gitconfig());
                home = getenv("HOME");
                filename = getenv(CONFIG_LOCAL_ENVIRONMENT);
                        filename = repo_config = xstrdup(git_path("config"));
        }
  
-       if (home) {
+       if (git_config_global() && home) {
                char *user_config = xstrdup(mkpath("%s/.gitconfig", home));
                if (!access(user_config, R_OK))
                        ret = git_config_from_file(fn, user_config);
@@@ -702,17 -717,12 +718,17 @@@ static ssize_t find_beginning_of_line(c
        size_t equal_offset = size, bracket_offset = size;
        ssize_t offset;
  
 +contline:
        for (offset = offset_-2; offset > 0
                        && contents[offset] != '\n'; offset--)
                switch (contents[offset]) {
                        case '=': equal_offset = offset; break;
                        case ']': bracket_offset = offset; break;
                }
 +      if (offset > 0 && contents[offset-1] == '\\') {
 +              offset_ = offset;
 +              goto contline;
 +      }
        if (bracket_offset < equal_offset) {
                *found_bracket = 1;
                offset = bracket_offset+1;
@@@ -1080,12 -1090,3 +1096,12 @@@ int git_config_rename_section(const cha
        free(config_filename);
        return ret;
  }
 +
 +/*
 + * Call this to report error for your variable that should not
 + * get a boolean value (i.e. "[my] var" means "true").
 + */
 +int config_error_nonbool(const char *var)
 +{
 +      return error("Missing value for '%s'", var);
 +}