git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* credential.<url>.helper with partial url path
@ 2018-09-21 16:56 Zych, David M
  2018-09-21 22:55 ` Jeff King
  0 siblings, 1 reply; 2+ messages in thread
From: Zych, David M @ 2018-09-21 16:56 UTC (permalink / raw)
  To: git@vger.kernel.org

Suppose I need to use different credential.helper values for different 
repositories on the same HTTPS host.  Ideally I would like to be able to 
write this logic using a partial URL path prefix, for example in 
~/.gitconfig

[credential "https://example.com/prefix1/foo.git"]
         helper = !ZZZ
[credential "https://example.com/prefix1/"]
         helper = !YYY
[credential "https://example.com/"]
         useHttpPath = true
         helper = !XXX

For prefix1/foo.git (exact path match) this tries ZZZ first as desired:

$ git credential fill
protocol=https
host=example.com
path=prefix1/foo.git

ZZZ get: ZZZ: command not found
XXX get: XXX: command not found
Username for 'https://example.com/prefix1/foo.git': ^C

However, prefix1/bar.git does not try YYY:

$ git credential fill
protocol=https
host=example.com
path=prefix1/bar.git

XXX get: XXX: command not found
Username for 'https://example.com/prefix1/bar.git': ^C

even though (AFAICT) the general behavior of git-config seems to imply 
that it would do so:

$ git config --get-urlmatch credential https://example.com/prefix1/bar.git
credential.helper !YYY
credential.usehttppath true

Is this discrepancy intended?

The documentation in `man gitcredentials` 
(https://git-scm.com/docs/gitcredentials) points out quite explicitly 
that my patterns will not match foo.example.com nor plain http, but both 
of those rules are consistent with what git-config reports:

$ git config --get-urlmatch credential https://foo.example.com/
credential.helper osxkeychain
$ git config --get-urlmatch credential http://example.com/
credential.helper osxkeychain

If indeed the current behavior of git-credential is as intended, I think 
it would be helpful for that manpage to explicitly mention it (i.e. that 
you may specify a URL path component but that it must match exactly). 
Right now the only example given is one in which 'the "pattern" URL does 
not care about the path component at all.'

I'm testing against

$ git --version
git version 2.19.0

installed via homebrew on Mac OS X.

Thanks,
David

-- 
David Zych
Lead Network Service Engineer
University of Illinois Technology Services

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: credential.<url>.helper with partial url path
  2018-09-21 16:56 credential.<url>.helper with partial url path Zych, David M
@ 2018-09-21 22:55 ` Jeff King
  0 siblings, 0 replies; 2+ messages in thread
From: Jeff King @ 2018-09-21 22:55 UTC (permalink / raw)
  To: Zych, David M; +Cc: git@vger.kernel.org

On Fri, Sep 21, 2018 at 04:56:20PM +0000, Zych, David M wrote:

> Suppose I need to use different credential.helper values for different 
> repositories on the same HTTPS host.  Ideally I would like to be able to 
> write this logic using a partial URL path prefix, for example in 
> ~/.gitconfig
> 
> [credential "https://example.com/prefix1/foo.git"]
>          helper = !ZZZ
> [credential "https://example.com/prefix1/"]
>          helper = !YYY
> [credential "https://example.com/"]
>          useHttpPath = true
>          helper = !XXX
> [...]
> $ git config --get-urlmatch credential https://example.com/prefix1/bar.git
> credential.helper !YYY
> credential.usehttppath true
> 
> Is this discrepancy intended?

Sort of. The matching done by the credential code predates the config
code learning about url matching, so it uses a much more basic system.
It walks through the config in order for a particular request, throwing
away any entries whose subsections don't match, and then applying (in
the order it finds them) any entries which do. The matching for paths is
done using the whole path, not a prefix match.

There's something else going on, too: credential.helper is a
multi-valued variable, so it's going to try each matching helper in
turn. Whereas "git config --get" (and "--get-urlmatch") assume you're
looking for a single value, and use the last-one-wins rule that most
variables use.

Normally you'd want to use "--get-all" for that, though I don't know if
there's a way to combine it with url matching.

So what you're seeing is the code working as designed, but I agree the
result kind of sucks. I wouldn't be sad to see the credential code moved
over to use the same url-matching as http.* uses. It would technically
be backwards-incompatible in a few cases, but I think the new behavior
would almost always be what the person intended in the first place.

With the current code, you'd have to teach your helper to be more clever
about matching the path. E.g., by wrapping your existing helper with
something like:

-- >8 --
#!/usr/bin/perl

my %input = map { /(.*?)=(.*)/ } <STDIN>;
my $helper =
  $input{path} =~ m{^prefix1/foo\.git} ? 'ZZZ' :
  $input{path} =~ m{^prefix1/} ? 'YYY' :
  'XXX';

my $pid = open(my $out, '|-', $helper, @ARGV);
print $out "$_=$input{$_}\n" for keys(%input);
close($out);
waitpid $pid, 0;
-- >8 --

I know that's pretty nasty for your simple use case, but I think it's
the best you can do with the current system.

> If indeed the current behavior of git-credential is as intended, I think 
> it would be helpful for that manpage to explicitly mention it (i.e. that 
> you may specify a URL path component but that it must match exactly). 
> Right now the only example given is one in which 'the "pattern" URL does 
> not care about the path component at all.'

Yes, I think this could be more clear in the "credential contexts"
section of gitcredentials(7). Do you want to try to make a patch?

-Peff

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2018-09-21 22:55 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-21 16:56 credential.<url>.helper with partial url path Zych, David M
2018-09-21 22:55 ` Jeff King

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).