Thread (22 messages) flat view 22 messages, 7 authors, 2016-06-15

Re: Get rid of .git/branches/ and .git/remotes/?

From: Linus Torvalds <torvalds@osdl.org>
Date: 2016-06-15 22:42:12
Subsystem: the rest · Maintainer: Linus Torvalds


On Sun, 20 Nov 2005, Johannes Schindelin wrote:
I just had a crazy idea. Since we have a framework in place to read/write 
.git/config, I thought that maybe it would be a nice thing to move the 
information which is in .git/branches or .git/remotes into the config.
I considered it, but thee thing is, it really wants "nested names", ie 
having multi-level base-names for the variables. At the same time, I 
absolutely _abhor_ horrible crap like XML, which make nesting a 
fundamental part of their structure.

XML may be "logical", but it has absolutely zero to do with being 
human-readable and clean. In short, XML is total and absolute CRAP (in 
fact, the "X" in "XML" stands for "Crap", but the XML designers were also 
incredibly bad spellers).

So while the basic notion of the git ini file does support nesting (we 
could just make variable names be "base.level1.final" or any number of 
levels deep), I don't know what a sane format would be. I have one 
suggestion that in my opinion "fits" the .ini file syntax (see below), but 
people may well hate it.

Basically I've considered saying that one or more '.' characters at the 
start of a section name would mean "re-use the previous one", so we could 
have (this is a really bad example, just to show the implications):

	[core]
		[.values]
			fixed = true
			nested = fine
			[..example]
				test = Hell yes
		[.other]
			example = strange
		[.]
			name = hi

	[section]
		example = yet another

and that would result in a parse of

	core.values.fixed = true
	core.values.nested = fine
	core.values.example.test = Hell yes
	core.other.example = strange
	core.name = hi
	secontion.example = yet another

and that seems reasonably clean. I'd also allow explicit 
multi-level section names:

	[core.values]
		fixed = true

so you could always write the above config file in an alternate format:

	[core.values] fixed = true
	[core.values] nested = fine
	[core.values.example] test = Hell yes
	[core.other] example = strange
	[core] name = hi
	[section] example = yet another

instead, using no implicit nesting at all (or, indeed, even re-using 
sections like "core.values").

That would allow things like

	[branches]
		[.origin]
			url = master.kernel.org:/pub/scm/git/git.git
			pull = master:origin
		[.mine]
			url = my.domain.com:/other/repo
			pull = master:mine

(which could also be written as

	[branches.origin]
		url = master.kernel.org:/pub/scm/git/git.git
		pull = master:origin

	[branches.mine]
		url = my.domain.com:/other/repo
		pull = master:mine

and the following mixed-indentation usage would be technically correct, 
but perhaps crazy:

	[branches.origin]
		url = master.kernel.org:/pub/scm/git/git.git
		pull = master:origin

	    [.mine]
		url = my.domain.com:/other/repo
		pull = master:mine

Basically, right now we only allow alphanumeric characters in the base 
name, and a new section name completely clears the old one. The above 
would be a very simple extension of that: we would allow '.' in addition 
to alphanumerics, and any initial '.' characters would _keep_ that many 
levels of the old name.

I dunno. That seems a nice extension, and it would make these things 
very unambiguous. But how do other .ini-file-like things do this?

And I'm not 100% convinced that putting these branches in the config file 
has any real advantages over keeping them as separate files. Having 
everything in one place is nice, of course, and being able to copy just 
one file around might be convenient, but it _does_ make the config file 
more complicated.

Anyway, if you want to play with this, here's a trivial patch that may or 
may not work.

		Linus

----
diff --git a/config.c b/config.c
index 915bb97..3b9f300 100644
--- a/config.c
+++ b/config.c
@@ -136,6 +136,19 @@ static int get_base_var(char *name)
 			return -1;
 		if (c == ']')
 			return baselen;
+		if (c == '.') {
+			if (!baselen || name[baselen-1] == '.') {
+				for (;;) {
+					if (!name[baselen])
+						return -1;
+					if (name[baselen++] == '.')
+						break;
+				}
+				continue;
+			}
+			name[baselen++] = c;
+			continue;
+		}
 		if (!isalnum(c))
 			return -1;
 		if (baselen > MAXNAME / 2)
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help