* Re: [BUG] git config gets confused
2007-05-12 23:52 [BUG] git config gets confused Frank Lichtenheld
@ 2007-05-13 4:49 ` Junio C Hamano
2007-05-13 10:46 ` Johannes Schindelin
0 siblings, 1 reply; 3+ messages in thread
From: Junio C Hamano @ 2007-05-13 4:49 UTC (permalink / raw)
To: Frank Lichtenheld; +Cc: git, Johannes Schindelin
Frank Lichtenheld <frank@lichtenheld.de> writes:
> While working on test cases for git-cvsserver, especially the config
> file handling I noticed the following bug in git-config:
>
> $ git-config gitcvs.enabled true
> $ git-config gitcvs.ext.dbname %Ggitcvs1.%a.%m.sqlite
> $ git-config gitcvs.dbname %Ggitcvs2.%a.%m.sqlite
>
> expected result:
>
> [gitcvs]
> enabled = true
> dbname = %Ggitcvs2.%a.%m.sqlite
> [gitcvs "ext"]
> dbname = %Ggitcvs1.%a.%m.sqlite
>
> actual result:
>
> [gitcvs]
> enabled = true
> [gitcvs "ext"]
> dbname = %Ggitcvs1.%a.%m.sqlite
> dbname = %Ggitcvs2.%a.%m.sqlite
Oh, boy.
Why am I not surprised by another bug in config writer?
Dscho, does this look good?
-- >8 --
git-config: do not forget "a.b.var" already ends "a.var" section.
Earlier code tried to be half-careful and knew the logic that
seeing "a.var" after seeing "a.b.var" is a sign of the previous
"a.b." section has ended, but forgot it has to handle the other
way. Seeing "a.b.var" after seeing "a.var" is a sign that "a."
section has ended, so a new "a.var2" variable should be added
before the location "a.b.var" appears.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
config.c | 26 ++++++++++++++++++++++----
1 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/config.c b/config.c
index 70d1055..70e6e7e 100644
--- a/config.c
+++ b/config.c
@@ -451,6 +451,9 @@ static int matches(const char* key, const char* value)
static int store_aux(const char* key, const char* value)
{
+ const char *ep;
+ size_t section_len;
+
switch (store.state) {
case KEY_SEEN:
if (matches(key, value)) {
@@ -468,12 +471,27 @@ static int store_aux(const char* key, const char* value)
}
break;
case SECTION_SEEN:
- if (strncmp(key, store.key, store.baselen+1)) {
+ /*
+ * What we are looking for is in store.key (both
+ * section and var), and its section part is baselen
+ * long. We found key (again, both section and var).
+ * We would want to know if this key is in the same
+ * section as what we are looking for.
+ */
+ ep = strrchr(key, '.');
+ section_len = ep - key;
+
+ if ((section_len != store.baselen) ||
+ memcmp(key, store.key, section_len+1)) {
store.state = SECTION_END_SEEN;
break;
- } else
- /* do not increment matches: this is no match */
- store.offset[store.seen] = ftell(config_file);
+ }
+
+ /*
+ * Do not increment matches: this is no match, but we
+ * just made sure we are in the desired section.
+ */
+ store.offset[store.seen] = ftell(config_file);
/* fallthru */
case SECTION_END_SEEN:
case START:
^ permalink raw reply related [flat|nested] 3+ messages in thread