SYNOPSIS
--------
[verse]
- 'git config' [<file-option>] [type] [-z|--null] name [value [value_regex]]
+ 'git config' [<file-option>] [type] [--show-origin] [-z|--null] name [value [value_regex]]
'git config' [<file-option>] [type] --add name value
'git config' [<file-option>] [type] --replace-all name value [value_regex]
- 'git config' [<file-option>] [type] [-z|--null] --get name [value_regex]
- 'git config' [<file-option>] [type] [-z|--null] --get-all name [value_regex]
- 'git config' [<file-option>] [type] [-z|--null] [--name-only] --get-regexp name_regex [value_regex]
+ 'git config' [<file-option>] [type] [--show-origin] [-z|--null] --get name [value_regex]
+ 'git config' [<file-option>] [type] [--show-origin] [-z|--null] --get-all name [value_regex]
+ 'git config' [<file-option>] [type] [--show-origin] [-z|--null] [--name-only] --get-regexp name_regex [value_regex]
'git config' [<file-option>] [type] [-z|--null] --get-urlmatch name URL
'git config' [<file-option>] --unset name [value_regex]
'git config' [<file-option>] --unset-all name [value_regex]
'git config' [<file-option>] --rename-section old_name new_name
'git config' [<file-option>] --remove-section name
- 'git config' [<file-option>] [-z|--null] [--name-only] -l | --list
+ 'git config' [<file-option>] [--show-origin] [-z|--null] [--name-only] -l | --list
'git config' [<file-option>] --get-color name [default]
'git config' [<file-option>] --get-colorbool name [stdout-is-tty]
'git config' [<file-option>] -e | --edit
Output only the names of config variables for `--list` or
`--get-regexp`.
+ --show-origin::
+ Augment the output of all queried config options with the
+ origin type (file, standard input, blob, command line) and
+ the actual origin (config file path, ref, or blob id if
+ applicable).
+
--get-colorbool name [stdout-is-tty]::
Find the color setting for `name` (e.g. `color.diff`) and output
--[no-]includes::
Respect `include.*` directives in config files when looking up
- values. Defaults to on.
+ values. Defaults to `off` when a specific file is given (e.g.,
+ using `--file`, `--global`, etc) and `on` when searching all
+ config files.
[[FILES]]
FILES
#include "convert.h"
#include "trace.h"
#include "string-list.h"
+#include "pack-revindex.h"
#include SHA1_HEADER
#ifndef platform_SHA_CTX
#define CE_INTENT_TO_ADD (1 << 29)
#define CE_SKIP_WORKTREE (1 << 30)
/* CE_EXTENDED2 is for future extension */
-#define CE_EXTENDED2 (1 << 31)
+#define CE_EXTENDED2 (1U << 31)
#define CE_EXTENDED_FLAGS (CE_INTENT_TO_ADD | CE_SKIP_WORKTREE)
#error "CE_EXTENDED_FLAGS out of range"
#endif
+/* Forward structure decls */
struct pathspec;
+struct child_process;
/*
* Copy the sha1 and stat state of a cache entry from one to
#define ce_uptodate(ce) ((ce)->ce_flags & CE_UPTODATE)
#define ce_skip_worktree(ce) ((ce)->ce_flags & CE_SKIP_WORKTREE)
#define ce_mark_uptodate(ce) ((ce)->ce_flags |= CE_UPTODATE)
+#define ce_intent_to_add(ce) ((ce)->ce_flags & CE_INTENT_TO_ADD)
#define ce_permissions(mode) (((mode) & 0100) ? 0755 : 0644)
static inline unsigned int create_ce_mode(unsigned int mode)
extern int is_inside_work_tree(void);
extern const char *get_git_dir(void);
extern const char *get_git_common_dir(void);
-extern int is_git_directory(const char *path);
extern char *get_object_directory(void);
extern char *get_index_file(void);
extern char *get_graft_file(void);
extern const char *strip_namespace(const char *namespaced_ref);
extern const char *get_git_work_tree(void);
+/*
+ * Return true if the given path is a git directory; note that this _just_
+ * looks at the directory itself. If you want to know whether "foo/.git"
+ * is a repository, you must feed that path, not just "foo".
+ */
+extern int is_git_directory(const char *path);
+
+/*
+ * Return 1 if the given path is the root of a git repository or
+ * submodule, else 0. Will not return 1 for bare repositories with the
+ * exception of creating a bare repository in "foo/.git" and calling
+ * is_git_repository("foo").
+ *
+ * If we run into read errors, we err on the side of saying "yes, it is",
+ * as we usually consider sub-repos precious, and would prefer to err on the
+ * side of not disrupting or deleting them.
+ */
+extern int is_nonbare_repository_dir(struct strbuf *path);
+
#define READ_GITFILE_ERR_STAT_FAILED 1
#define READ_GITFILE_ERR_NOT_A_FILE 2
#define READ_GITFILE_ERR_OPEN_FAILED 3
freshened:1,
do_not_close:1;
unsigned char sha1[20];
+ struct revindex_entry *revindex;
/* something like ".git/objects/pack/xxxxx.pack" */
char pack_name[FLEX_ARRAY]; /* more */
} *packed_git;
typedef int (*config_fn_t)(const char *, const char *, void *);
extern int git_default_config(const char *, const char *, void *);
extern int git_config_from_file(config_fn_t fn, const char *, void *);
- extern int git_config_from_buf(config_fn_t fn, const char *name,
- const char *buf, size_t len, void *data);
+ extern int git_config_from_mem(config_fn_t fn, const char *origin_type,
+ const char *name, const char *buf, size_t len, void *data);
extern void git_config_push_parameter(const char *text);
extern int git_config_from_parameters(config_fn_t fn, void *data);
extern void git_config(config_fn_t fn, void *);
extern const char *get_commit_output_encoding(void);
extern int git_config_parse_parameter(const char *, config_fn_t fn, void *data);
+ extern const char *current_config_origin_type(void);
+ extern const char *current_config_name(void);
struct config_include_data {
int depth;
extern int git_config_get_bool_or_int(const char *key, int *is_bool, int *dest);
extern int git_config_get_maybe_bool(const char *key, int *dest);
extern int git_config_get_pathname(const char *key, const char **dest);
+extern int git_config_get_untracked_cache(void);
+
+/*
+ * This is a hack for test programs like test-dump-untracked-cache to
+ * ensure that they do not modify the untracked cache when reading it.
+ * Do not use it otherwise!
+ */
+extern int ignore_untracked_cache_config;
struct key_value_info {
const char *filename;
extern int term_columns(void);
extern int decimal_width(uintmax_t);
extern int check_pager_config(const char *cmd);
+extern void prepare_pager_args(struct child_process *, const char *pager);
extern const char *editor_program;
extern const char *askpass_program;
size_t pos;
} buf;
} u;
+ const char *origin_type;
const char *name;
const char *path;
int die_on_error;
break;
}
if (cf->die_on_error)
- die(_("bad config file line %d in %s"), cf->linenr, cf->name);
+ die(_("bad config line %d in %s %s"), cf->linenr, cf->origin_type, cf->name);
else
- return error(_("bad config file line %d in %s"), cf->linenr, cf->name);
+ return error(_("bad config line %d in %s %s"), cf->linenr, cf->origin_type, cf->name);
}
static int parse_unit_factor(const char *end, uintmax_t *val)
if (!value)
value = "";
- if (cf && cf->name)
- die(_("bad numeric config value '%s' for '%s' in %s: %s"),
- value, name, cf->name, reason);
+ if (cf && cf->origin_type && cf->name)
+ die(_("bad numeric config value '%s' for '%s' in %s %s: %s"),
+ value, name, cf->origin_type, cf->name, reason);
die(_("bad numeric config value '%s' for '%s': %s"), value, name, reason);
}
}
static int do_config_from_file(config_fn_t fn,
- const char *name, const char *path, FILE *f, void *data)
+ const char *origin_type, const char *name, const char *path, FILE *f,
+ void *data)
{
struct config_source top;
top.u.file = f;
+ top.origin_type = origin_type;
top.name = name;
top.path = path;
top.die_on_error = 1;
static int git_config_from_stdin(config_fn_t fn, void *data)
{
- return do_config_from_file(fn, "<stdin>", NULL, stdin, data);
+ return do_config_from_file(fn, "standard input", "", NULL, stdin, data);
}
int git_config_from_file(config_fn_t fn, const char *filename, void *data)
f = fopen(filename, "r");
if (f) {
flockfile(f);
- ret = do_config_from_file(fn, filename, filename, f, data);
+ ret = do_config_from_file(fn, "file", filename, filename, f, data);
funlockfile(f);
fclose(f);
}
return ret;
}
- int git_config_from_buf(config_fn_t fn, const char *name, const char *buf,
- size_t len, void *data)
+ int git_config_from_mem(config_fn_t fn, const char *origin_type,
+ const char *name, const char *buf, size_t len, void *data)
{
struct config_source top;
top.u.buf.buf = buf;
top.u.buf.len = len;
top.u.buf.pos = 0;
+ top.origin_type = origin_type;
top.name = name;
top.path = NULL;
top.die_on_error = 0;
return error("reference '%s' does not point to a blob", name);
}
- ret = git_config_from_buf(fn, name, buf, size, data);
+ ret = git_config_from_mem(fn, "blob", name, buf, size, data);
free(buf);
return ret;
return ret;
}
+int git_config_get_untracked_cache(void)
+{
+ int val = -1;
+ const char *v;
+
+ /* Hack for test programs like test-dump-untracked-cache */
+ if (ignore_untracked_cache_config)
+ return -1;
+
+ if (!git_config_get_maybe_bool("core.untrackedcache", &val))
+ return val;
+
+ if (!git_config_get_value("core.untrackedcache", &v)) {
+ if (!strcasecmp(v, "keep"))
+ return -1;
+
+ error("unknown core.untrackedCache value '%s'; "
+ "using 'keep' default value", v);
+ return -1;
+ }
+
+ return -1; /* default value */
+}
+
NORETURN
void git_die_config_linenr(const char *key, const char *filename, int linenr)
{
* Validate the key and while at it, lower case it for matching.
*/
if (store_key)
- *store_key = xmalloc(strlen(key) + 1);
+ *store_key = xmallocz(strlen(key));
dot = 0;
for (i = 0; key[i]; i++) {
if (store_key)
(*store_key)[i] = c;
}
- if (store_key)
- (*store_key)[i] = 0;
return 0;
return 0;
}
+
+ const char *current_config_origin_type(void)
+ {
+ return cf && cf->origin_type ? cf->origin_type : "command line";
+ }
+
+ const char *current_config_name(void)
+ {
+ return cf && cf->name ? cf->name : "";
+ }