On Jul 12, 2013, at 02:59, Jeff King wrote:
On Thu, Jul 11, 2013 at 02:50:03PM -0700, Kyle J. McKay wrote:

A few comments on the implementation:

+enum http_option_type {
+       opt_post_buffer = 0,
+       opt_min_sessions,

We usually put enum fields in ALL_CAPS to mark them as constants (though
you can find few exceptions in the code).


+static size_t http_options_url_match_prefix(const char *url,
+                                           const char *url_prefix,
+                                           size_t url_prefix_len)

It looks like you're matching the URLs as raw strings, and I don't see
any canonicalization going on. What happens if I have
"https://example.com/foo+bar"; in my config, but then I visit

The documentation for http.<url>.* says:

+ Note that <url> must match the url exactly (other than possibly being a + prefix). This means any user, password and/or port setting that appears + in a url must also appear in <url> to have a successful match.

Or what about optional components? If I have "https://example.com"; in my
config, but I am visiting "https://p...@example.com/";, shouldn't it
match? The config spec is more general than my specific URL; you would
not want it to match in the opposite direction, though.

They have to be included to match. Any URL-encoding present in the URL given to git needs to be duplicated in the URL in the config file exactly or there will not be a match.

That does make your by-length ordering impossible, but I don't think you
can do it in the general case. If I have:

 [http "http://p...@example.com";] foo = 1
 [http "http://example.com:8080";] foo = 2

and I visit "http://p...@example.com:8080";, which one is the winner?

If I were to spilt everything out, then I would only have the second one match. The first config is on a different port, quite possibly an entirely different service. It shouldn't match. Consider if you were port forwarding with ssh, services from many different machines would all be on localhost on different ports. The second one is on the same port and matches because it's slightly more general (missing the user name), but it's clearly talking to the same service.

As the patch stands now, neither of them would match since the documentation requires an exact match (except for possibly being a prefix).

I don't think it's necessary to split the URL apart though. Whatever URL the user gave to git on the command line (at some point even if it's now stored as a remote setting in config) complete with URL- encoding, user names, port names, etc. is the same url, possibly shortened, that needs to be used for the http.<url>.option setting.

I think that's simple and very easy to explain and avoids user confusion and surprise while still allowing a default to be set for a site but easily overridden for a portion of that site without needing to worry about the order config files are processed or the order of the [http "<url>"] sections within them.

I don't think there is an unambiguous definition. I'd suggest instead just
using the usual "last one wins" strategy that our config uses. It has
the unfortunate case that:

 [http "http://example.com";]
    foo = 1
    foo = 2

will always choose http.foo=2, but I don't think that is a big problem
in practice.

I think that violates the principle of least surprise.  In this case:

[http "https://cacert.org";]
  sslVerify = false
  sslVerify = true

the intention here is very clear -- for cacert.org only, sslVerify should be false. To have the [http] setting step on the [http "https://cacert.org "] setting seems completely surprising and unexpected.

The "last one wins" is still in effect though for the same paths. If you have:

# System config
[http "https://cacert.org";]
  sslVerify = false

# Global config
[http "https://cacert.org";]
  sslVerify = true

The setting from the Global config still wins.

You often only set one or the other, and in the cases where
you want to have a non-standard default and then override it with
another host-specific case, the "last one wins" rule makes it simple to
explain that you need to specify keys in most-general to most-specific

Unless, of course, different config files are involved and that's not possible without duplicating entries into the later-processed config file.

static int http_options(const char *var, const char *value, void *cb)
-       if (!strcmp("http.sslverify", var)) {
+       const char *url = (const char *)cb;

No need to cast from void, this isn't C++. :)


The rest of the http_options() changes look like what I'd expect.

@@ -344,7 +479,7 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)

        http_is_verbose = 0;

-       git_config(http_options, NULL);
+       git_config(http_options, (void *)url);

No need to cast again. :)

Ah, but there is in order to avoid a warning:

http.c: In function ‘http_init’:
http.c:481: warning: passing argument 2 of ‘git_config’ discards qualifiers from pointer target type

url is a const char * and git_config takes a void *.

However, it may be worth mentioning in the documentation that the config options operate on the URL you give git, _not_ necessarily on the actual
URL you are hitting at any given moment (the gitcredentials(7) page
should probably make the same distinction).

Can do that. Will have to think about the wording for a while and mention the %XX escapes as well.--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to