summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin-update-index.c2
-rw-r--r--builtin-write-tree.c2
-rw-r--r--config.c49
-rw-r--r--gitweb/gitweb.css272
-rw-r--r--repo-config.c39
-rw-r--r--t/Makefile2
-rwxr-xr-xt/t1300-repo-config.sh24
7 files changed, 319 insertions, 71 deletions
diff --git a/builtin-update-index.c b/builtin-update-index.c
index 325cd0944d..ef50243452 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
@@ -490,7 +490,7 @@ int cmd_update_index(int argc, const char **argv, char **envp)
git_config(git_default_config);
/* We can't free this memory, it becomes part of a linked list parsed atexit() */
- lock_file = xmalloc(sizeof(struct lock_file));
+ lock_file = xcalloc(1, sizeof(struct lock_file));
newfd = hold_lock_file_for_update(lock_file, get_index_file());
if (newfd < 0)
diff --git a/builtin-write-tree.c b/builtin-write-tree.c
index c3aac36024..70e9b6fcc6 100644
--- a/builtin-write-tree.c
+++ b/builtin-write-tree.c
@@ -16,7 +16,7 @@ int write_tree(unsigned char *sha1, int missing_ok, const char *prefix)
int entries, was_valid, newfd;
/* We can't free this memory, it becomes part of a linked list parsed atexit() */
- struct lock_file *lock_file = xmalloc(sizeof(struct lock_file));
+ struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
newfd = hold_lock_file_for_update(lock_file, get_index_file());
diff --git a/config.c b/config.c
index d46eb6d829..d064f429cb 100644
--- a/config.c
+++ b/config.c
@@ -317,17 +317,33 @@ int git_config_from_file(config_fn_t fn, const char *filename)
int git_config(config_fn_t fn)
{
- const char *filename = git_path("config");
- /* Forward-compatibility cue: $GIT_CONFIG makes git read _only_
- * the given config file, $GIT_CONFIG_LOCAL will make it process
- * it in addition to the global config file, the same way it would
- * the per-repository config file otherwise. */
- if (getenv("GIT_CONFIG")) {
- filename = getenv("GIT_CONFIG");
- } else if (getenv("GIT_CONFIG_LOCAL")) {
+ int ret = 0;
+ char *repo_config = NULL;
+ const char *home = NULL, *filename;
+
+ /* $GIT_CONFIG makes git read _only_ the given config file,
+ * $GIT_CONFIG_LOCAL will make it process it in addition to the
+ * global config file, the same way it would the per-repository
+ * config file otherwise. */
+ filename = getenv("GIT_CONFIG");
+ if (!filename) {
+ home = getenv("HOME");
filename = getenv("GIT_CONFIG_LOCAL");
+ if (!filename)
+ filename = repo_config = strdup(git_path("config"));
}
- return git_config_from_file(fn, filename);
+
+ if (home) {
+ char *user_config = strdup(mkpath("%s/.gitconfig", home));
+ if (access(user_config, R_OK) > 0)
+ ret = git_config_from_file(fn, user_config);
+ free(user_config);
+ }
+
+ ret += git_config_from_file(fn, filename);
+ if (repo_config)
+ free(repo_config);
+ return ret;
}
/*
@@ -500,10 +516,19 @@ int git_config_set_multivar(const char* key, const char* value,
int i, dot;
int fd = -1, in_fd;
int ret;
- char* config_filename = strdup(git_path("config"));
- char* lock_file = strdup(git_path("config.lock"));
+ char* config_filename;
+ char* lock_file;
const char* last_dot = strrchr(key, '.');
+ config_filename = getenv("GIT_CONFIG");
+ if (!config_filename) {
+ config_filename = getenv("GIT_CONFIG_LOCAL");
+ if (!config_filename)
+ config_filename = git_path("config");
+ }
+ config_filename = strdup(config_filename);
+ lock_file = strdup(mkpath("%s.lock", config_filename));
+
/*
* Since "key" actually contains the section name and the real
* key name separated by a dot, we have to know where the dot is.
@@ -610,7 +635,7 @@ int git_config_set_multivar(const char* key, const char* value,
* As a side effect, we make sure to transform only a valid
* existing config file.
*/
- if (git_config(store_aux)) {
+ if (git_config_from_file(store_aux, config_filename)) {
fprintf(stderr, "invalid config file\n");
free(store.key);
if (store.value_regex != NULL) {
diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css
index bf95e38496..4378067d3c 100644
--- a/gitweb/gitweb.css
+++ b/gitweb/gitweb.css
@@ -1,58 +1,230 @@
body {
- font-family: sans-serif; font-size: 12px; border:solid #d9d8d1; border-width:1px;
- margin:10px; background-color:#ffffff; color:#000000;
-}
-a { color:#0000cc; }
-a:hover, a:visited, a:active { color:#880000; }
-div.page_header { height:25px; padding:8px; font-size:18px; font-weight:bold; background-color:#d9d8d1; }
-div.page_header a:visited, a.header { color:#0000cc; }
-div.page_header a:hover { color:#880000; }
-div.page_nav { padding:8px; }
-div.page_nav a:visited { color:#0000cc; }
-div.page_path { padding:8px; border:solid #d9d8d1; border-width:0px 0px 1px}
-div.page_footer { height:17px; padding:4px 8px; background-color: #d9d8d1; }
-div.page_footer_text { float:left; color:#555555; font-style:italic; }
-div.page_body { padding:8px; }
+ font-family: sans-serif;
+ font-size: 12px;
+ border:solid #d9d8d1;
+ border-width: 1px;
+ margin: 10px;
+ background-color: #ffffff;
+ color: #000000;
+}
+
+a {
+ color: #0000cc;
+}
+
+a:hover, a:visited, a:active {
+ color: #880000;
+}
+
+div.page_header {
+ height: 25px;
+ padding: 8px;
+ font-size: 18px;
+ font-weight: bold;
+ background-color: #d9d8d1;
+}
+
+div.page_header a:visited, a.header {
+ color: #0000cc;
+}
+
+div.page_header a:hover {
+ color: #880000;
+}
+
+div.page_nav {
+ padding:8px;
+}
+
+div.page_nav a:visited {
+ color: #0000cc;
+}
+
+div.page_path {
+ padding: 8px;
+ border: solid #d9d8d1;
+ border-width: 0px 0px 1px;
+}
+
+div.page_footer {
+ height: 17px;
+ padding: 4px 8px;
+ background-color: #d9d8d1;
+}
+
+div.page_footer_text {
+ float: left;
+ color: #555555;
+ font-style: italic;
+}
+
+div.page_body {
+ padding: 8px;
+}
+
div.title, a.title {
- display:block; padding:6px 8px;
- font-weight:bold; background-color:#edece6; text-decoration:none; color:#000000;
+ display: block;
+ padding: 6px 8px;
+ font-weight: bold;
+ background-color: #edece6;
+ text-decoration: none;
+ color: #000000;
+}
+
+a.title:hover {
+ background-color: #d9d8d1;
+}
+
+div.title_text {
+ padding: 6px 0px;
+ border: solid #d9d8d1;
+ border-width: 0px 0px 1px;
}
-a.title:hover { background-color: #d9d8d1; }
-div.title_text { padding:6px 0px; border: solid #d9d8d1; border-width:0px 0px 1px; }
-div.log_body { padding:8px 8px 8px 150px; }
-span.age { position:relative; float:left; width:142px; font-style:italic; }
+
+div.log_body {
+ padding: 8px 8px 8px 150px;
+}
+
+span.age {
+ position: relative;
+ float: left;
+ width: 142px;
+ font-style:italic;
+}
+
div.log_link {
- padding:0px 8px;
- font-size:10px; font-family:sans-serif; font-style:normal;
- position:relative; float:left; width:136px;
-}
-div.list_head { padding:6px 8px 4px; border:solid #d9d8d1; border-width:1px 0px 0px; font-style:italic; }
-a.list { text-decoration:none; color:#000000; }
-a.list:hover { text-decoration:underline; color:#880000; }
-a.text { text-decoration:none; color:#0000cc; }
-a.text:visited { text-decoration:none; color:#880000; }
-a.text:hover { text-decoration:underline; color:#880000; }
-table { padding:8px 4px; }
-th { padding:2px 5px; font-size:12px; text-align:left; }
-tr.light:hover { background-color:#edece6; }
-tr.dark { background-color:#f6f6f0; }
-tr.dark:hover { background-color:#edece6; }
-td { padding:2px 5px; font-size:12px; vertical-align:top; }
-td.link { padding:2px 5px; font-family:sans-serif; font-size:10px; }
-div.pre { font-family:monospace; font-size:12px; white-space:pre; }
-div.diff_info { font-family:monospace; color:#000099; background-color:#edece6; font-style:italic; }
-div.index_include { border:solid #d9d8d1; border-width:0px 0px 1px; padding:12px 8px; }
-div.search { margin:4px 8px; position:absolute; top:56px; right:12px }
-a.linenr { color:#999999; text-decoration:none }
+ padding: 0px 8px;
+ font-size: 10px;
+ font-family: sans-serif;
+ font-style:normal;
+ position: relative;
+ float: left;
+ width: 136px;
+}
+
+div.list_head {
+ padding: 6px 8px 4px;
+ border: solid #d9d8d1;
+ border-width: 1px 0px 0px;
+ font-style: italic;
+}
+
+a.list {
+ text-decoration: none;
+ color: #000000;
+}
+
+a.list:hover {
+ text-decoration: underline;
+ color: #880000;
+}
+
+a.text {
+ text-decoration: none;
+ color: #0000cc;
+}
+
+a.text:visited {
+ text-decoration: none;
+ color: #880000;
+}
+
+a.text:hover {
+ text-decoration: underline;
+ color: #880000;
+}
+
+table {
+ padding: 8px 4px;
+}
+
+th {
+ padding: 2px 5px;
+ font-size: 12px;
+ text-align: left;
+}
+
+tr.light:hover {
+ background-color: #edece6;
+}
+
+tr.dark {
+ background-color: #f6f6f0;
+}
+
+tr.dark:hover {
+ background-color: #edece6;
+}
+
+
+td {
+ padding: 2px 5px;
+ font-size: 12px;
+ vertical-align:top;
+}
+
+td.link {
+ padding: 2px 5px;
+ font-family: sans-serif;
+ font-size: 10px;
+}
+
+div.pre {
+ font-family: monospace;
+ font-size: 12px;
+ white-space: pre;
+}
+
+div.diff_info {
+ font-family: monospace;
+ color: #000099;
+ background-color: #edece6;
+ font-style: italic;
+}
+
+div.index_include {
+ border: solid #d9d8d1;
+ border-width: 0px 0px 1px;
+ padding: 12px 8px;
+}
+
+div.search {
+ margin: 4px 8px;
+ position: absolute;
+ top: 56px;
+ right: 12px
+}
+
+a.linenr {
+ color: #999999;
+ text-decoration: none
+}
+
a.rss_logo {
- float:right; padding:3px 0px; width:35px; line-height:10px;
- border:1px solid; border-color:#fcc7a5 #7d3302 #3e1a01 #ff954e;
- color:#ffffff; background-color:#ff6600;
- font-weight:bold; font-family:sans-serif; font-size:10px;
- text-align:center; text-decoration:none;
+ float: right;
+ padding: 3px 0px;
+ width: 35px;
+ line-height: 10px;
+ border: 1px solid;
+ border-color: #fcc7a5 #7d3302 #3e1a01 #ff954e;
+ color: #ffffff;
+ background-color: #ff6600;
+ font-weight: bold;
+ font-family: sans-serif;
+ font-size: 10px;
+ text-align: center;
+ text-decoration: none;
+}
+
+a.rss_logo:hover {
+ background-color: #ee5500;
}
-a.rss_logo:hover { background-color:#ee5500; }
+
span.tag {
- padding:0px 4px; font-size:10px; font-weight:normal;
- background-color:#ffffaa; border:1px solid; border-color:#ffffcc #ffee00 #ffee00 #ffffcc;
+ padding: 0px 4px;
+ font-size: 10px;
+ font-weight: normal;
+ background-color: #ffffaa;
+ border: 1px solid;
+ border-color: #ffffcc #ffee00 #ffee00 #ffffcc;
}
diff --git a/repo-config.c b/repo-config.c
index 08fc4cc57d..03f108fe2f 100644
--- a/repo-config.c
+++ b/repo-config.c
@@ -64,7 +64,22 @@ static int show_config(const char* key_, const char* value_)
static int get_value(const char* key_, const char* regex_)
{
+ int ret = -1;
char *tl;
+ char *global = NULL, *repo_config = NULL;
+ const char *local;
+
+ local = getenv("GIT_CONFIG");
+ if (!local) {
+ const char *home = getenv("HOME");
+ local = getenv("GIT_CONFIG_LOCAL");
+ if (!local)
+ local = repo_config;
+ else
+ local = repo_config = strdup(git_path("config"));
+ if (home)
+ global = strdup(mkpath("%s/.gitconfig", home));
+ }
key = strdup(key_);
for (tl=key+strlen(key)-1; tl >= key && *tl != '.'; --tl)
@@ -76,7 +91,7 @@ static int get_value(const char* key_, const char* regex_)
key_regexp = (regex_t*)malloc(sizeof(regex_t));
if (regcomp(key_regexp, key, REG_EXTENDED)) {
fprintf(stderr, "Invalid key pattern: %s\n", key_);
- return -1;
+ goto free_strings;
}
}
@@ -89,11 +104,16 @@ static int get_value(const char* key_, const char* regex_)
regexp = (regex_t*)malloc(sizeof(regex_t));
if (regcomp(regexp, regex_, REG_EXTENDED)) {
fprintf(stderr, "Invalid pattern: %s\n", regex_);
- return -1;
+ goto free_strings;
}
}
- git_config(show_config);
+ if (do_all && global)
+ git_config_from_file(show_config, global);
+ git_config_from_file(show_config, local);
+ if (!do_all && !seen && global)
+ git_config_from_file(show_config, global);
+
free(key);
if (regexp) {
regfree(regexp);
@@ -101,9 +121,16 @@ static int get_value(const char* key_, const char* regex_)
}
if (do_all)
- return !seen;
-
- return (seen == 1) ? 0 : 1;
+ ret = !seen;
+ else
+ ret = (seen == 1) ? 0 : 1;
+
+free_strings:
+ if (repo_config)
+ free(repo_config);
+ if (global)
+ free(global);
+ return ret;
}
int main(int argc, const char **argv)
diff --git a/t/Makefile b/t/Makefile
index 549598575b..632c55f6d5 100644
--- a/t/Makefile
+++ b/t/Makefile
@@ -19,7 +19,7 @@ endif
all: $(T) clean
$(T):
- @echo "*** $@ ***"; '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)
+ @echo "*** $@ ***"; GIT_CONFIG=.git/config '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)
clean:
rm -fr trash
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index 8260d57b63..0de2497746 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -309,5 +309,29 @@ EOF
test_expect_success 'new variable inserts into proper section' 'cmp .git/config expect'
+cat > other-config << EOF
+[ein]
+ bahn = strasse
+EOF
+
+cat > expect << EOF
+ein.bahn=strasse
+EOF
+
+GIT_CONFIG=other-config git-repo-config -l > output
+
+test_expect_success 'alternative GIT_CONFIG' 'cmp output expect'
+
+GIT_CONFIG=other-config git-repo-config anwohner.park ausweis
+
+cat > expect << EOF
+[ein]
+ bahn = strasse
+[anwohner]
+ park = ausweis
+EOF
+
+test_expect_success '--set in alternative GIT_CONFIG' 'cmp other-config expect'
+
test_done