Git development
 help / color / mirror / Atom feed
* Re: [PATCH] Add contrib/credentials/netrc with GPG support, try #2
From: Jeff King @ 2013-02-04 23:23 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Ted Zlatanov, git
In-Reply-To: <7vd2wf1yex.fsf@alter.siamese.dyndns.org>

On Mon, Feb 04, 2013 at 02:56:06PM -0800, Junio C Hamano wrote:

> > +my $mode = shift @ARGV;
> > +
> > +# credentials may get 'get', 'store', or 'erase' as parameters but
> > +# only acknowledge 'get'
> > +die "Syntax: $0 [-f AUTHFILE] [-d] get" unless defined $mode;
> > +
> > +# only support 'get' mode
> > +exit unless $mode eq 'get';
> 
> The above looks strange.  Why does the invoker get the error message
> only when it runs this without arguments?  Did you mean to say more
> like this?
> 
> 	unless (defined $mode && $mode eq 'get') {
> 		die "...";
> 	}

Not having a mode is an invocation error; the credential-helper
documentation indicates that the helper will always be invoked with an
action. The likely culprit for not having one is the user invoking it
manually, and showing the usage there is a sensible action.

Whereas invoking it with a mode other than "get" is not an error at all.
Git will run it with the "store" and "erase" actions, too. Those happen
to be no-ops for this helper, so it exits silently. The credential docs
specify that any other actions should be ignored, too, to allow for
future expansion.

> > +my $debug = $options{debug};
> > +my $file = $options{file};
> > +
> > +unless (defined $file) {
> > +	print STDERR "Please specify an existing netrc file (with or without a .gpg extension) with -f AUTHFILE\n" if $debug;
> > +	exit 0;
> > +}
> > +
> > +unless (-f $file) {
> > +	print STDERR "Sorry, the specified netrc $file is not accessible\n" if $debug;
> > +	exit 0;
> > +}
> 
> Perhaps "-r $file", if you say "is not accessible"?

Even better: look at whether opening the file was successful. Though I
guess that is complicated by the use of gpg, who will probably not
distinguish ENOENT from other failures for us.

> Is it sensible to squelch the error message by default and force
> user to specify --debug?  You could argue that the option is to
> debug the user's configuration, but the name of the option sounds
> more like it is for debugging this script itself.
> 
> I saw Peff already pointed out error conditions, but I am not sure
> why all of these exit with 0.  If the user has configured

It was from my suggestion to ignore missing files, which is that the
user might have the helper configured (e.g., via /etc/gitconfig, or by a
shared ~/.gitconfig) but not actually have a netrc.

It gets confusing because the contents of $file may have been
auto-detected, or it may have come from the command-line, and we do not
remember which at this point.

I was trying not to be too nit-picky with my review, but here is how I
would have written the outer logic of the script:

  my $tokens = read_credential_data_from_stdin();
  if ($options{file}) {
          my @entries = load_netrc($options{file})
                  or die "unable to open $options{file}: $!";
          check_netrc($tokens, @entries);
  }
  else {
          foreach my $ext ('.gpg', '') {
                  foreach my $base (qw(authinfo netrc)) {
                          my @entries = load_netrc("$base$ext")
                                  or next;
                          if (check_netrc($tokens, @entries)) {
                                  last;
                          }
                  }
          }
  }

I.e., to fail on "-f", but otherwise treat unreadable auto-selected
files as a no-op, for whatever reason. I'd also consider checking all
files if they are available, in case the user has multiple (e.g., they
keep low-quality junk unencrypted but some high-security passwords in a
.gpg file). Not that likely, but not any harder to implement.

-Peff

^ permalink raw reply

* Re: [PATCH 1/3] Add contrib/credentials/netrc with GPG support
From: Junio C Hamano @ 2013-02-04 23:10 UTC (permalink / raw)
  To: Ted Zlatanov; +Cc: git, Jeff King
In-Reply-To: <87lib3uats.fsf@lifelogs.com>

Ted Zlatanov <tzz@lifelogs.com> writes:

> JCH> I thought that we tend to avoid Emacs/Vim formatting cruft left in
> JCH> the file.  Do we have any in existing file outside contrib/?
>
> No, but it's a nice way to express the settings so no one is guessing
> what the project prefers.  At least for me it's not an issue anymore,
> since I understand your criteria better now, so let me know if you want
> me to express it in the CodingGuidelines, in a dir-locals.el file, or
> somewhere else.

Historically we treated this from CodingGuidelines a sufficient
clue:

    As for more concrete guidelines, just imitate the existing code
    (this is a good guideline, no matter which project you are
    contributing to). It is always preferable to match the _local_
    convention. New code added to git suite is expected to match
    the overall style of existing code. Modifications to existing
    code is expected to match the style the surrounding code already
    uses (even if it doesn't match the overall style of existing code).

but over time people wanted more specific guidelines and added
language specific style guides there.  We have sections that cover
C, shell and Python, and I do not think adding Perl would not hurt.

^ permalink raw reply

* Re: [PATCH] Add contrib/credentials/netrc with GPG support, try #2
From: Junio C Hamano @ 2013-02-04 22:56 UTC (permalink / raw)
  To: Ted Zlatanov; +Cc: Jeff King, git
In-Reply-To: <87mwvjsqjc.fsf_-_@lifelogs.com>

Ted Zlatanov <tzz@lifelogs.com> writes:

> Signed-off-by: Ted Zlatanov <tzz@lifelogs.com>

The space above your S-o-b: could be utilized a bit better ;-)

> @@ -0,0 +1,236 @@
> +#!/usr/bin/perl
> +
> +use strict;
> +use warnings;
> +
> +use Getopt::Long;
> +use File::Basename;
> +
> +my $VERSION = "0.1";
> +
> +my %options = (
> +               help => 0,
> +               debug => 0,
> +
> +               # identical token maps, e.g. host -> host, will be inserted later
> +               tmap => {
> +                        port => 'protocol',
> +                        machine => 'host',
> +                        path => 'path',
> +                        login => 'username',
> +                        user => 'username',
> +                        password => 'password',
> +                       }
> +              );
> +
> +# map each credential protocol token to itself on the netrc side
> +$options{tmap}->{$_} = $_ foreach values %{$options{tmap}};
> +
> +foreach my $suffix ('.gpg', '') {
> +	foreach my $base (qw/authinfo netrc/) {
> +		my $file = glob("~/.$base$suffix");
> +		next unless (defined $file && -f $file);
> +		$options{file} = $file ;
> +	}
> +}

This checks .gpg first and then unencrypted, and checks authinfo
first and netrc second, both of which makes sense.  It is good to
encourage use of encrypted files, and it is good to use newer
authinfo files over netrc files.

However, it is strange that you let the ones that are discovered
later in the loop to override the ones that are discovered earlier.
Perhaps you meant

	next unless (... exists there ...);
        $options{"file"} = $file;
        last;

instead?

> +Getopt::Long::Configure("bundling");

Hmm, OK.

> +# TODO: maybe allow the token map $options{tmap} to be configurable.
> +GetOptions(\%options,
> +           "help|h",
> +           "debug|d",
> +           "file|f=s",
> +          );
> +
> +if ($options{help}) {
> +	my $shortname = basename($0);
> +	$shortname =~ s/git-credential-//;
> +
> +	print <<EOHIPPUS;
> +
> +$0 [-f AUTHFILE] [-d] get
> +
> +Version $VERSION by tzz\@lifelogs.com.  License: BSD.
> +
> +Options:
> +  -f AUTHFILE: specify a netrc-style file
> +  -d: turn on debugging
> +
> +To enable (note that Git will prepend "git-credential-" to the helper
> +name and look for it in the path):
> +
> +  git config credential.helper '$shortname -f AUTHFILE'
> +
> +And if you want lots of debugging info:
> +
> +  git config credential.helper '$shortname -f AUTHFILE -d'
> +
> +Only "get" mode is supported by this credential helper.  It opens
> +AUTHFILE and looks for entries that match the requested search
> +criteria:
> +
> + 'port|protocol':
> +   The protocol that will be used (e.g., https). (protocol=X)
> +
> + 'machine|host':
> +   The remote hostname for a network credential. (host=X)
> +
> + 'path':
> +   The path with which the credential will be used. (path=X)
> +
> + 'login|user|username':
> +   The credential’s username, if we already have one. (username=X)
> +
> +Thus, when we get this query on STDIN:
> +
> +protocol=https
> +username=tzz
> +
> +this credential helper will look for lines in AUTHFILE that match
> +
> +port https login tzz
> +
> +OR
> +
> +protocol https login tzz
> +
> +OR... etc. acceptable tokens as listed above.  Any unknown tokens are
> +simply ignored.

I recall that netrc/authinfo files are _not_ line oriented.  Earlier
you said "looks for entries that match" which is a lot more correct,
but then we see "look for lines in authfile".

> +Then, the helper will print out whatever tokens it got from the line,
> +including "password" tokens, mapping e.g. "port" back to "protocol".

Again "line" is mentioned twice, above and below.

> +The first matching line is used.  Tokens can be quoted as 'STRING' or
> +"STRING".
> +
> +No caching is performed by this credential helper.
> +
> +EOHIPPUS
> +
> +	exit;
> +}

> +my $mode = shift @ARGV;
> +
> +# credentials may get 'get', 'store', or 'erase' as parameters but
> +# only acknowledge 'get'
> +die "Syntax: $0 [-f AUTHFILE] [-d] get" unless defined $mode;
> +
> +# only support 'get' mode
> +exit unless $mode eq 'get';

The above looks strange.  Why does the invoker get the error message
only when it runs this without arguments?  Did you mean to say more
like this?

	unless (defined $mode && $mode eq 'get') {
		die "...";
	}

By the way, I think statement modifiers tend to get overused and
make the resulting program harder to read.  die "..." at the
beginning of line makes the reader go "Whoa, it already is done and
existing on error", and then forces the eyes to scan the error
message to find "unless" and the condition.

It may be a cute syntax and some may find it even cool, but cuteness
or coolness is less valuable compared with the readability.

> +my $debug = $options{debug};
> +my $file = $options{file};
> +
> +unless (defined $file) {
> +	print STDERR "Please specify an existing netrc file (with or without a .gpg extension) with -f AUTHFILE\n" if $debug;
> +	exit 0;
> +}
> +
> +unless (-f $file) {
> +	print STDERR "Sorry, the specified netrc $file is not accessible\n" if $debug;
> +	exit 0;
> +}

Perhaps "-r $file", if you say "is not accessible"?

Is it sensible to squelch the error message by default and force
user to specify --debug?  You could argue that the option is to
debug the user's configuration, but the name of the option sounds
more like it is for debugging this script itself.

I saw Peff already pointed out error conditions, but I am not sure
why all of these exit with 0.  If the user has configured

	git config credential.helper 'netrc -f $HOME/.netcr'

shouldn't it be diagnosed as an error?  It is understandable to let
this go silently

	git config credential.helper 'netrc'

and let other credential helpers take over when no $HOME/.{netrc,authinfo}{,.gpg}
file exist, but in that case the user may still want to remove the
config item that is not doing anything useful and erroring out with
a message may be a way to help the user know about the situation.

> +my @data;
> +if ($file =~ m/\.gpg$/) {
> +	@data = load('-|', qw(gpg --decrypt), $file)
> +}
> +else {
> +	@data = load('<', $file);
> +}
> +
> +chomp @data;
> +
> +unless (scalar @data) {

Shouldn't this error check come logically before chomping?

> +	print STDERR "Sorry, we could not load data from [$file]\n" if $debug;
> +	exit;
> +}

Is this really an error?  The file perhaps was empty.  Shouldn't
that case treated the same way as the case where no entry that
matches the criteria invoker gave you was found?

^ permalink raw reply

* [PATCH] Add contrib/credentials/netrc with GPG support, try #2
From: Ted Zlatanov @ 2013-02-04 21:44 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, git
In-Reply-To: <20130204211726.GB13186@sigill.intra.peff.net>



Signed-off-by: Ted Zlatanov <tzz@lifelogs.com>
---
 contrib/credential/netrc/git-credential-netrc |  236 +++++++++++++++++++++++++
 1 files changed, 236 insertions(+), 0 deletions(-)
 create mode 100755 contrib/credential/netrc/git-credential-netrc

diff --git a/contrib/credential/netrc/git-credential-netrc b/contrib/credential/netrc/git-credential-netrc
new file mode 100755
index 0000000..d265fde
--- /dev/null
+++ b/contrib/credential/netrc/git-credential-netrc
@@ -0,0 +1,236 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Getopt::Long;
+use File::Basename;
+
+my $VERSION = "0.1";
+
+my %options = (
+               help => 0,
+               debug => 0,
+
+               # identical token maps, e.g. host -> host, will be inserted later
+               tmap => {
+                        port => 'protocol',
+                        machine => 'host',
+                        path => 'path',
+                        login => 'username',
+                        user => 'username',
+                        password => 'password',
+                       }
+              );
+
+# map each credential protocol token to itself on the netrc side
+$options{tmap}->{$_} = $_ foreach values %{$options{tmap}};
+
+foreach my $suffix ('.gpg', '') {
+	foreach my $base (qw/authinfo netrc/) {
+		my $file = glob("~/.$base$suffix");
+		next unless (defined $file && -f $file);
+		$options{file} = $file ;
+	}
+}
+
+Getopt::Long::Configure("bundling");
+
+# TODO: maybe allow the token map $options{tmap} to be configurable.
+GetOptions(\%options,
+           "help|h",
+           "debug|d",
+           "file|f=s",
+          );
+
+if ($options{help}) {
+	my $shortname = basename($0);
+	$shortname =~ s/git-credential-//;
+
+	print <<EOHIPPUS;
+
+$0 [-f AUTHFILE] [-d] get
+
+Version $VERSION by tzz\@lifelogs.com.  License: BSD.
+
+Options:
+  -f AUTHFILE: specify a netrc-style file
+  -d: turn on debugging
+
+To enable (note that Git will prepend "git-credential-" to the helper
+name and look for it in the path):
+
+  git config credential.helper '$shortname -f AUTHFILE'
+
+And if you want lots of debugging info:
+
+  git config credential.helper '$shortname -f AUTHFILE -d'
+
+Only "get" mode is supported by this credential helper.  It opens
+AUTHFILE and looks for entries that match the requested search
+criteria:
+
+ 'port|protocol':
+   The protocol that will be used (e.g., https). (protocol=X)
+
+ 'machine|host':
+   The remote hostname for a network credential. (host=X)
+
+ 'path':
+   The path with which the credential will be used. (path=X)
+
+ 'login|user|username':
+   The credential’s username, if we already have one. (username=X)
+
+Thus, when we get this query on STDIN:
+
+protocol=https
+username=tzz
+
+this credential helper will look for lines in AUTHFILE that match
+
+port https login tzz
+
+OR
+
+protocol https login tzz
+
+OR... etc. acceptable tokens as listed above.  Any unknown tokens are
+simply ignored.
+
+Then, the helper will print out whatever tokens it got from the line,
+including "password" tokens, mapping e.g. "port" back to "protocol".
+
+The first matching line is used.  Tokens can be quoted as 'STRING' or
+"STRING".
+
+No caching is performed by this credential helper.
+
+EOHIPPUS
+
+	exit;
+}
+
+my $mode = shift @ARGV;
+
+# credentials may get 'get', 'store', or 'erase' as parameters but
+# only acknowledge 'get'
+die "Syntax: $0 [-f AUTHFILE] [-d] get" unless defined $mode;
+
+# only support 'get' mode
+exit unless $mode eq 'get';
+
+my $debug = $options{debug};
+my $file = $options{file};
+
+unless (defined $file) {
+	print STDERR "Please specify an existing netrc file (with or without a .gpg extension) with -f AUTHFILE\n" if $debug;
+	exit 0;
+}
+
+unless (-f $file) {
+	print STDERR "Sorry, the specified netrc $file is not accessible\n" if $debug;
+	exit 0;
+}
+
+my @data;
+if ($file =~ m/\.gpg$/) {
+	@data = load('-|', qw(gpg --decrypt), $file)
+}
+else {
+	@data = load('<', $file);
+}
+
+chomp @data;
+
+unless (scalar @data) {
+	print STDERR "Sorry, we could not load data from [$file]\n" if $debug;
+	exit;
+}
+
+# the query: start with every token with no value
+my %q = map { $_ => undef } values(%{$options{tmap}});
+
+while (<STDIN>) {
+	next unless m/^([^=]+)=(.+)/;
+
+	my ($token, $value) = ($1, $2);
+	die "Unknown search token $1" unless exists $q{$token};
+	$q{$token} = $value;
+}
+
+# build reverse token map
+my %rmap;
+foreach my $k (keys %{$options{tmap}}) {
+	push @{$rmap{$options{tmap}->{$k}}}, $k;
+}
+
+# there are CPAN modules to do this better, but we want to avoid
+# dependencies and generally, complex netrc-style files are rare
+
+if ($debug) {
+	printf STDERR "searching for %s = %s\n", $_, $q{$_} || '(any value)'
+		foreach sort keys %q;
+}
+
+LINE: foreach my $line (@data) {
+
+	print STDERR "line [$line]\n" if $debug;
+	my @tok;
+	# gratefully stolen from Net::Netrc
+	while (length $line &&
+	       $line =~ s/^("((?:[^"]+|\\.)*)"|((?:[^\\\s]+|\\.)*))\s*//) {
+		(my $tok = $+) =~ s/\\(.)/$1/g;
+		push(@tok, $tok);
+	}
+
+	# skip blank lines, comments, etc.
+	next LINE unless scalar @tok;
+
+	my %tokens;
+	my $num_port;
+	while (@tok) {
+		my ($k, $v) = (shift @tok, shift @tok);
+		next unless defined $v;
+		next unless exists $options{tmap}->{$k};
+		$tokens{$options{tmap}->{$k}} = $v;
+		$num_port = $v if $k eq 'port' && $v =~ m/^\d+$/;
+	}
+
+	# for "host X port Y" where Y is an integer (captured by
+	# $num_port above), set the host to "X:Y"
+	$tokens{host} = join(':', $tokens{host}, $num_port)
+		if defined $tokens{host} && defined $num_port;
+
+	foreach my $check (sort keys %q) {
+		if (exists $tokens{$check} && defined $q{$check}) {
+			print STDERR "comparing [$tokens{$check}] to [$q{$check}] in line [$line]\n" if $debug;
+			next LINE unless $tokens{$check} eq $q{$check};
+		}
+		else {
+			print STDERR "we could not find [$check] but it's OK\n" if $debug;
+		}
+	}
+
+	print STDERR "line has passed all the search checks\n" if $debug;
+ TOKEN:
+	foreach my $token (sort keys %rmap) {
+		print STDERR "looking for useful token $token\n" if $debug;
+		next unless exists $tokens{$token}; # did we match?
+
+		foreach my $rctoken (@{$rmap{$token}}) {
+			next TOKEN if defined $q{$rctoken};           # don't re-print given tokens
+		}
+
+		print STDERR "FOUND: $token=$tokens{$token}\n" if $debug;
+		printf "%s=%s\n", $token, $tokens{$token};
+	}
+
+	last;
+}
+
+sub load {
+	# this supports pipes too
+	my $io = new IO::File(@_) or die "Could not open [@_]: $!\n";
+	return <$io>;                          # whole file
+}
-- 
1.7.9.rc2

^ permalink raw reply related

* Re: [PATCH] git-send-email: add ~/.authinfo parsing
From: Ted Zlatanov @ 2013-02-04 21:41 UTC (permalink / raw)
  To: Jeff King; +Cc: Michal Nazarewicz, Junio C Hamano, git, Krzysztof Mazur
In-Reply-To: <20130204212203.GC13186@sigill.intra.peff.net>

On Mon, 4 Feb 2013 16:22:03 -0500 Jeff King <peff@peff.net> wrote: 

>> Currently, we map both the "port" and "protocol" netrc tokens to the
>> credential helper protocol's "protocol".  So this will have undefined
>> results.  To do what you specify could be pretty simple: we could do a
>> preliminary scan of the tokens, looking for "host X port Y" where Y is
>> an integer, and rewriting the host to be "X:Y".  That would be clean and
>> simple, unless the user breaks it with "host x:23 port 22".  Let me know
>> if you agree and I'll do.

JK> Yeah, I think that is simple and obvious. If the user is saying "host
JK> x:23 port 22", that is nonsensical.

OK; added.

Ted

^ permalink raw reply

* Re: [PATCH] Add contrib/credentials/netrc with GPG support
From: Ted Zlatanov @ 2013-02-04 21:32 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, git
In-Reply-To: <20130204211726.GB13186@sigill.intra.peff.net>

On Mon, 4 Feb 2013 16:17:26 -0500 Jeff King <peff@peff.net> wrote: 

JK> Do you need to quote "\n" here?

Fixed.

JK> Hmm, so it's not an error (just a warning) to say:

JK>   git credential-netrc -f /does/not/exist

JK> but it is an error to say:

JK>   git credential-netrc

JK> and have it fail to find any netrc files. Shouldn't the latter be a
JK> lesser error than the former?

Fixed, they should both exit(0).

>> +	next unless m/([^=]+)=(.+)/;

JK> Should this regex be anchored at the start of the string?

Fixed.

>> +	printf STDERR "searching for %s = %s\n", $_, $q{$_} || '(any value)'
>> +	 foreach sort keys %q;
JK> Leftover one-char indent.

Fixed.

Ted

^ permalink raw reply

* Re: [PATCH] git-send-email: add ~/.authinfo parsing
From: Jeff King @ 2013-02-04 21:22 UTC (permalink / raw)
  To: Ted Zlatanov; +Cc: Michal Nazarewicz, Junio C Hamano, git, Krzysztof Mazur
In-Reply-To: <8738xbu6qj.fsf@lifelogs.com>

On Mon, Feb 04, 2013 at 04:08:52PM -0500, Ted Zlatanov wrote:

> >> That would create the following possibilities:
> >> 
> >> * host example.com:31337, protocol https
> >> * host example.com:31337, protocol unspecified
> >> * host example.com, protocol https
> >> * host example.com, protocol unspecified
> 
> JK> Possibilities for .netrc, or for git? Git will always specify the
> JK> protocol.
> 
> Possibilities for the netrc data.  How clever do we want to be with
> taking 31337 and mapping it to the "protocol"?  My preference is to be
> very simple here.

I think simple is OK, as we can iterate on it as specific use-cases come
up. The important thing is to make sure we err on the side of "does not
match" and not "oops, we accidentally sent your plaintext credentials to
the wrong server".

> Currently, we map both the "port" and "protocol" netrc tokens to the
> credential helper protocol's "protocol".  So this will have undefined
> results.  To do what you specify could be pretty simple: we could do a
> preliminary scan of the tokens, looking for "host X port Y" where Y is
> an integer, and rewriting the host to be "X:Y".  That would be clean and
> simple, unless the user breaks it with "host x:23 port 22".  Let me know
> if you agree and I'll do.

Yeah, I think that is simple and obvious. If the user is saying "host
x:23 port 22", that is nonsensical.

-Peff

^ permalink raw reply

* Re: [PATCH] Add contrib/credentials/netrc with GPG support
From: Jeff King @ 2013-02-04 21:17 UTC (permalink / raw)
  To: Ted Zlatanov; +Cc: Junio C Hamano, git
In-Reply-To: <87ehgvua6h.fsf@lifelogs.com>

On Mon, Feb 04, 2013 at 02:54:30PM -0500, Ted Zlatanov wrote:

> +	print <<EOHIPPUS;
> +
> +$0 [-f AUTHFILE] [-d] get
> +
> +Version $VERSION by tzz\@lifelogs.com.  License: BSD.

This here-doc is interpolated so you can use $0 and $VERSION, and
therefore have to quote the @-sign. But later in the here-doc...

> +Thus, when we get "protocol=https\nusername=tzz", this credential
> +helper will look for lines in AUTHFILE that match

Do you need to quote "\n" here?

> +die "Sorry, you need to specify an existing netrc file (with or without a .gpg extension) with -f AUTHFILE"
> + unless defined $file;
> +
> +unless (-f $file) {
> +	print STDERR "Sorry, the specified netrc $file is not accessible\n" if $debug;
> +	exit 0;
> +}

Hmm, so it's not an error (just a warning) to say:

  git credential-netrc -f /does/not/exist

but it is an error to say:

  git credential-netrc

and have it fail to find any netrc files. Shouldn't the latter be a
lesser error than the former?

> +while (<STDIN>) {
> +	next unless m/([^=]+)=(.+)/;
> +
> +	my ($token, $value) = ($1, $2);
> +	die "Unknown search token $1" unless exists $q{$token};
> +	$q{$token} = $value;
> +}

Should this regex be anchored at the start of the string? I think the
left-to-right matching means we will correctly match:

  key=value with=in it

so it may be OK.

> +if ($debug) {
> +	printf STDERR "searching for %s = %s\n", $_, $q{$_} || '(any value)'
> +	 foreach sort keys %q;
> +}

Leftover one-char indent.

> [...]

The rest looks OK to me.

^ permalink raw reply

* Re: [PATCH] git-send-email: add ~/.authinfo parsing
From: Ted Zlatanov @ 2013-02-04 21:08 UTC (permalink / raw)
  To: Jeff King; +Cc: Michal Nazarewicz, Junio C Hamano, git, Krzysztof Mazur
In-Reply-To: <20130204205911.GA13186@sigill.intra.peff.net>

On Mon, 4 Feb 2013 15:59:11 -0500 Jeff King <peff@peff.net> wrote: 

JK> On Mon, Feb 04, 2013 at 03:28:52PM -0500, Ted Zlatanov wrote:
JK> You might want to map this to "port" in .autoinfo separately if it's
JK> available.
>> 
>> That would create the following possibilities:
>> 
>> * host example.com:31337, protocol https
>> * host example.com:31337, protocol unspecified
>> * host example.com, protocol https
>> * host example.com, protocol unspecified

JK> Possibilities for .netrc, or for git? Git will always specify the
JK> protocol.

Possibilities for the netrc data.  How clever do we want to be with
taking 31337 and mapping it to the "protocol"?  My preference is to be
very simple here.

JK> What I was more wondering (and I know very little about .netrc, so this
JK> might not be a possibility at all) is a line like:

JK>   host example.com port 5001 protocol https username foo password bar

JK> To match git's representation on a token-by-token basis, you would have
JK> to either split out git's "host:port" pair, or combine the .netrc's
JK> representation to "example.com:5001".

Currently, we map both the "port" and "protocol" netrc tokens to the
credential helper protocol's "protocol".  So this will have undefined
results.  To do what you specify could be pretty simple: we could do a
preliminary scan of the tokens, looking for "host X port Y" where Y is
an integer, and rewriting the host to be "X:Y".  That would be clean and
simple, unless the user breaks it with "host x:23 port 22".  Let me know
if you agree and I'll do.

Ted

^ permalink raw reply

* Re: [PATCH] git-send-email: add ~/.authinfo parsing
From: Jeff King @ 2013-02-04 20:59 UTC (permalink / raw)
  To: Ted Zlatanov; +Cc: Michal Nazarewicz, Junio C Hamano, git, Krzysztof Mazur
In-Reply-To: <87a9rju8l7.fsf@lifelogs.com>

On Mon, Feb 04, 2013 at 03:28:52PM -0500, Ted Zlatanov wrote:

> JK> You might want to map this to "port" in .autoinfo separately if it's
> JK> available.
> 
> That would create the following possibilities:
> 
> * host example.com:31337, protocol https
> * host example.com:31337, protocol unspecified
> * host example.com, protocol https
> * host example.com, protocol unspecified

Possibilities for .netrc, or for git? Git will always specify the
protocol.

> How would you like each one to be handled?  My preference would be to
> make the user say "host example.com:31337" in the netrc file (the
> current situation); that's what we do in Emacs and it lets applications
> request credentials for a logical service no matter what the port is.
> 
> It means that example.com credentials won't be used for
> example.com:31337.  In practice, that has not been a problem for us.

Yeah, I think that is a good thing. The credentials used for
example.com:31337 are not necessarily the same as for the main site.
It's less convenient, but a more secure default.

What I was more wondering (and I know very little about .netrc, so this
might not be a possibility at all) is a line like:

  host example.com port 5001 protocol https username foo password bar

To match git's representation on a token-by-token basis, you would have
to either split out git's "host:port" pair, or combine the .netrc's
representation to "example.com:5001".

-Peff

^ permalink raw reply

* Re: [PATCH v3] submodule: add 'deinit' command
From: Junio C Hamano @ 2013-02-04 20:55 UTC (permalink / raw)
  To: Jens Lehmann
  Cc: Git Mailing List, Heiko Voigt, Michael J Gruber, Phil Hord,
	Marc Branchaud, W. Trevor King
In-Reply-To: <5110157A.2040402@web.de>

Jens Lehmann <Jens.Lehmann@web.de> writes:

> With "git submodule init" the user is able to tell git he cares about one
> or more submodules and wants to have it populated on the next call to "git
> submodule update". But currently there is no easy way he could tell git he
> does not care about a submodule anymore and wants to get rid of his local
> work tree (except he knows a lot about submodule internals and removes the
> "submodule.$name.url" setting from .git/config together with the work tree
> himself).
>
> Help those users by providing a 'deinit' command. This removes the whole
> submodule.<name> section from .git/config either for the given
> submodule(s) (or for all those which have been initialized if '.' is
> given). Fail if the current work tree contains modifications unless
> forced. Complain when for a submodule given on the command line the url
> setting can't be found in .git/config, but nonetheless don't fail.
>
> Add tests and link the man pages of "git submodule deinit" and "git rm"
> to assist the user in deciding whether removing or unregistering the
> submodule is the right thing to do for him.
>
> Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>
> ---
>
> Ok, here is the reroll following the discussion in $gmane/212884.
>
> Changes since v2 are:
> - deinit always needs an argument; if the user wants to deinit all initialized
>   submodules he can use "." (and we tell him that when failing without any
>   arguments).
> - We also remove the work tree of the submodule. When it contains local changes
>   (tested with "git rm -n") this fails unless forced.
>
>
>  Documentation/git-rm.txt        |  4 +++
>  Documentation/git-submodule.txt | 18 ++++++++++-
>  git-submodule.sh                | 70 ++++++++++++++++++++++++++++++++++++++++-
>  t/t7400-submodule-basic.sh      | 24 ++++++++++++++
>  4 files changed, 114 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt
> index 262436b..8ae72f7 100644
> --- a/Documentation/git-rm.txt
> +++ b/Documentation/git-rm.txt
> @@ -149,6 +149,10 @@ files that aren't ignored are present in the submodules work tree.
>  Ignored files are deemed expendable and won't stop a submodule's work
>  tree from being removed.
>
> +If you only want to remove the local checkout of a submodule from your
> +work tree without committing that use linkgit:git-submodule[1] `deinit`
> +instead.
> +
>  EXAMPLES
>  --------
>  `git rm Documentation/\*.txt`::
> diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
> index b1996f1..9a20e1d 100644
> --- a/Documentation/git-submodule.txt
> +++ b/Documentation/git-submodule.txt
> @@ -13,6 +13,7 @@ SYNOPSIS
>  	      [--reference <repository>] [--] <repository> [<path>]
>  'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...]
>  'git submodule' [--quiet] init [--] [<path>...]
> +'git submodule' [--quiet] deinit [-f|--force] [--] <path>...
>  'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch] [--rebase]
>  	      [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
>  'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) <n>]
> @@ -134,6 +135,19 @@ init::
>  	the explicit 'init' step if you do not intend to customize
>  	any submodule locations.
>
> +deinit::
> +	Unregister the given submodules, i.e. remove the whole
> +	`submodule.$name` section from .git/config together with their work
> +	tree. Further calls to `git submodule update`, `git submodule foreach`
> +	and `git submodule sync` will skip any unregistered submodules until
> +	they are initialized again, so use this command if you don't want to
> +	have a local checkout of the submodule in your work tree anymore. If
> +	you really want to remove a submodule from the repository and commit
> +	that use linkgit:git-rm[1] instead.
> ++
> +If `--force` is specified, the submodule's work tree will be removed even if
> +it contains local modifications.
> +
>  update::
>  	Update the registered submodules, i.e. clone missing submodules and
>  	checkout the commit specified in the index of the containing repository.
> @@ -213,8 +227,10 @@ OPTIONS
>
>  -f::
>  --force::
> -	This option is only valid for add and update commands.
> +	This option is only valid for add, deinit and update commands.
>  	When running add, allow adding an otherwise ignored submodule path.
> +	When running deinit the submodule work trees will be removed even if
> +	they contain local changes.
>  	When running update, throw away local changes in submodules when
>  	switching to a different commit; and always run a checkout operation
>  	in the submodule, even if the commit listed in the index of the
> diff --git a/git-submodule.sh b/git-submodule.sh
> index 22ec5b6..e01f6b5 100755
> --- a/git-submodule.sh
> +++ b/git-submodule.sh
> @@ -8,6 +8,7 @@ dashless=$(basename "$0" | sed -e 's/-/ /')
>  USAGE="[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--] <repository> [<path>]
>     or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
>     or: $dashless [--quiet] init [--] [<path>...]
> +   or: $dashless [--quiet] deinit [-f|--force] [--] <path>...
>     or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
>     or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
>     or: $dashless [--quiet] foreach [--recursive] <command>
> @@ -547,6 +548,73 @@ cmd_init()
>  }
>
>  #
> +# Unregister submodules from .git/config and remove their work tree
> +#
> +# $@ = requested paths (use '.' to deinit all submodules)
> +#
> +cmd_deinit()
> +{
> +	# parse $args after "submodule ... init".
> +	while test $# -ne 0
> +	do
> +		case "$1" in
> +		-f|--force)
> +			force=$1
> +			;;
> +		-q|--quiet)
> +			GIT_QUIET=1
> +			;;
> +		--)
> +			shift
> +			break
> +			;;
> +		-*)
> +			usage
> +			;;
> +		*)
> +			break
> +			;;
> +		esac
> +		shift
> +	done
> +
> +	if test "$#" == "0"

No need to quote either of these (imitate what you did above with
"while"); also use single "=" for string comparison.

> +	then
> +		die "$(eval_gettext "Use '.' if you really want to deinitialize all submodules")"
> +	fi
> +
> +	module_list "$@" |
> +	while read mode sha1 stage sm_path
> +	do
> +		die_if_unmatched "$mode"
> +		name=$(module_name "$sm_path") || exit
> +		url=$(git config submodule."$name".url)
> +		if test -z "$url"
> +		then
> +			# Only mention uninitialized submodules when its
> +			# path have been specified
> +			test "$@" != "." &&

If your $# is not 1, "test" will fail with "too many arguments"
here, I think.

I would probably set a variable before running module_list,

	needs_uninitialized_warning=
        if $# = 1 || $1 != .
	then
		needs_uninitialized_warning=yes
	fi

and check that variable here, perhaps.

But stepping back a bit, why does it warn only for non '.' case?

Shouldn't

	git submodule deinit 'foo*'

behave the same way between foo1 and foo2 when it sees foo1 has been
initialized but foo2 hasn't?

> +			say "$(eval_gettext "No url found for submodule path '\$sm_path' in .git/config")"
> +			continue
> +		fi
> +
> +		# Remove the submodule work tree
> +		if test -z $force

As $force is initialized to an empty string, this without dq around
it will become a syntax error, feeding "test" with a single argument
"-z".

> +		then
> +			git rm -n "$sm_path" ||
> +			die "$(eval_gettext "Submodule work tree $sm_path contains local modifications, use '-f' to discard them")"
> +		fi
> +		rm -rf "$sm_path"

Do we want to make sure that $sm_path/.git is a gitfile here?  I do
not think it matters that much, but the user may have local commits
that he has not pushed out, in which case it would be nicer to give
a way to preserve them.

> +		mkdir "$sm_path"

Also can these rm -rf or mkdir fail, and what would we want to do
when they do?

I think it is preferrable to run "config --remove-section"
regardless, but we may want to tell the user what happened (i.e. the
submodule has been unregistered as far as Git is concerned, but the
worktree may have some cruft we couldn't remove).

> +
> +		# Remove the whole section so we have a clean state when the
> +		# user later decides to init this submodule again
> +		git config --remove-section submodule."$name" &&
> +		say "$(eval_gettext "Submodule '\$name' (\$url) unregistered for path '\$sm_path'")"
> +	done
> +}
> +
> +#
>  # Update each submodule path to correct revision, using clone and checkout as needed
>  #
>  # $@ = requested paths (default to all)
> @@ -1157,7 +1225,7 @@ cmd_sync()
>  while test $# != 0 && test -z "$command"
>  do
>  	case "$1" in
> -	add | foreach | init | update | status | summary | sync)
> +	add | foreach | init | deinit | update | status | summary | sync)
>  		command=$1
>  		;;
>  	-q|--quiet)

^ permalink raw reply

* Re: [PATCH] git-send-email: add ~/.authinfo parsing
From: Ted Zlatanov @ 2013-02-04 20:28 UTC (permalink / raw)
  To: Jeff King; +Cc: Michal Nazarewicz, Junio C Hamano, git, Krzysztof Mazur
In-Reply-To: <20130204201040.GA13272@sigill.intra.peff.net>

On Mon, 4 Feb 2013 15:10:40 -0500 Jeff King <peff@peff.net> wrote: 

JK> Technically you can speak a particular protocol on an alternate port:

JK>   https://example.com:31337/repo.git

JK> In this case, git will send you the host as:

JK>   example.com:31337

JK> You might want to map this to "port" in .autoinfo separately if it's
JK> available.

That would create the following possibilities:

* host example.com:31337, protocol https
* host example.com:31337, protocol unspecified
* host example.com, protocol https
* host example.com, protocol unspecified

How would you like each one to be handled?  My preference would be to
make the user say "host example.com:31337" in the netrc file (the
current situation); that's what we do in Emacs and it lets applications
request credentials for a logical service no matter what the port is.

It means that example.com credentials won't be used for
example.com:31337.  In practice, that has not been a problem for us.

Ted

^ permalink raw reply

* Re: [New Feature] git-submodule-move - Easily move submodules
From: Jens Lehmann @ 2013-02-04 20:14 UTC (permalink / raw)
  To: TJ; +Cc: git, W. Trevor King
In-Reply-To: <510EE661.8060600@iam.tj>

Am 03.02.2013 23:36, schrieb TJ:
> I've recently had need to re-arrange more than ten submodules within a project and discovered there is apparently no easy way to do it.
> 
> Using some suggestions I found on Stack Overflow I eventually figured out the steps required. Because the steps can be
> complex I thought it would be handy to have a tool to automate the functionality.
> 
> I have put together a reasonably bullet-proof shell script "git-submodule-move" that does the job pretty well. I've put it through quite a bit of testing and trusted it with my own project and it has
> performed well.
> 
> I've published to github so others can use and improve it.
> 
> https://github.com/iam-TJ/git-submodule-move

I'd propose to drop these two steps:
 updating super-repository's submodule name
 moving super-repository's submodule repository

Changing the name makes the moved submodule a completely new entity and will
lead to a reclone of the repository as soon as recursive checkout materializes.
And Trevor already mentioned the long term solution which is to teach "git mv"
to do all that, which is next on my list.

^ permalink raw reply

* Re: [PATCH] git-send-email: add ~/.authinfo parsing
From: Jeff King @ 2013-02-04 20:10 UTC (permalink / raw)
  To: Ted Zlatanov; +Cc: Michal Nazarewicz, Junio C Hamano, git, Krzysztof Mazur
In-Reply-To: <878v74vwst.fsf@lifelogs.com>

On Mon, Feb 04, 2013 at 12:00:34PM -0500, Ted Zlatanov wrote:

> On Mon, 04 Feb 2013 17:33:58 +0100 Michal Nazarewicz <mina86@mina86.com> wrote: 
> 
> MN> As far as I understand, there could be a git-credential helper that
> MN> reads ~/.authinfo and than git-send-email would just call “git
> MN> credential fill”, right?
> 
> MN> I've noticed though, that git-credential does not support port argument,
> MN> which makes it slightly incompatible with ~/.authinfo.
> 
> My proposed netrc credential helper does this :)
> 
> The token mapping I use:
> 
> port, protocol        => protocol
> machine, host         => host
> path                  => path
> login, username, user => username
> password              => password
> 
> I think that's sensible.

Technically you can speak a particular protocol on an alternate port:

  https://example.com:31337/repo.git

In this case, git will send you the host as:

  example.com:31337

You might want to map this to "port" in .autoinfo separately if it's
available.

-Peff

^ permalink raw reply

* [PATCH v3] submodule: add 'deinit' command
From: Jens Lehmann @ 2013-02-04 20:09 UTC (permalink / raw)
  To: Git Mailing List
  Cc: Junio C Hamano, Heiko Voigt, Michael J Gruber, Phil Hord,
	Marc Branchaud, W. Trevor King

With "git submodule init" the user is able to tell git he cares about one
or more submodules and wants to have it populated on the next call to "git
submodule update". But currently there is no easy way he could tell git he
does not care about a submodule anymore and wants to get rid of his local
work tree (except he knows a lot about submodule internals and removes the
"submodule.$name.url" setting from .git/config together with the work tree
himself).

Help those users by providing a 'deinit' command. This removes the whole
submodule.<name> section from .git/config either for the given
submodule(s) (or for all those which have been initialized if '.' is
given). Fail if the current work tree contains modifications unless
forced. Complain when for a submodule given on the command line the url
setting can't be found in .git/config, but nonetheless don't fail.

Add tests and link the man pages of "git submodule deinit" and "git rm"
to assist the user in deciding whether removing or unregistering the
submodule is the right thing to do for him.

Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>
---

Ok, here is the reroll following the discussion in $gmane/212884.

Changes since v2 are:
- deinit always needs an argument; if the user wants to deinit all initialized
  submodules he can use "." (and we tell him that when failing without any
  arguments).
- We also remove the work tree of the submodule. When it contains local changes
  (tested with "git rm -n") this fails unless forced.


 Documentation/git-rm.txt        |  4 +++
 Documentation/git-submodule.txt | 18 ++++++++++-
 git-submodule.sh                | 70 ++++++++++++++++++++++++++++++++++++++++-
 t/t7400-submodule-basic.sh      | 24 ++++++++++++++
 4 files changed, 114 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt
index 262436b..8ae72f7 100644
--- a/Documentation/git-rm.txt
+++ b/Documentation/git-rm.txt
@@ -149,6 +149,10 @@ files that aren't ignored are present in the submodules work tree.
 Ignored files are deemed expendable and won't stop a submodule's work
 tree from being removed.

+If you only want to remove the local checkout of a submodule from your
+work tree without committing that use linkgit:git-submodule[1] `deinit`
+instead.
+
 EXAMPLES
 --------
 `git rm Documentation/\*.txt`::
diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index b1996f1..9a20e1d 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -13,6 +13,7 @@ SYNOPSIS
 	      [--reference <repository>] [--] <repository> [<path>]
 'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...]
 'git submodule' [--quiet] init [--] [<path>...]
+'git submodule' [--quiet] deinit [-f|--force] [--] <path>...
 'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch] [--rebase]
 	      [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
 'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) <n>]
@@ -134,6 +135,19 @@ init::
 	the explicit 'init' step if you do not intend to customize
 	any submodule locations.

+deinit::
+	Unregister the given submodules, i.e. remove the whole
+	`submodule.$name` section from .git/config together with their work
+	tree. Further calls to `git submodule update`, `git submodule foreach`
+	and `git submodule sync` will skip any unregistered submodules until
+	they are initialized again, so use this command if you don't want to
+	have a local checkout of the submodule in your work tree anymore. If
+	you really want to remove a submodule from the repository and commit
+	that use linkgit:git-rm[1] instead.
++
+If `--force` is specified, the submodule's work tree will be removed even if
+it contains local modifications.
+
 update::
 	Update the registered submodules, i.e. clone missing submodules and
 	checkout the commit specified in the index of the containing repository.
@@ -213,8 +227,10 @@ OPTIONS

 -f::
 --force::
-	This option is only valid for add and update commands.
+	This option is only valid for add, deinit and update commands.
 	When running add, allow adding an otherwise ignored submodule path.
+	When running deinit the submodule work trees will be removed even if
+	they contain local changes.
 	When running update, throw away local changes in submodules when
 	switching to a different commit; and always run a checkout operation
 	in the submodule, even if the commit listed in the index of the
diff --git a/git-submodule.sh b/git-submodule.sh
index 22ec5b6..e01f6b5 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -8,6 +8,7 @@ dashless=$(basename "$0" | sed -e 's/-/ /')
 USAGE="[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--] <repository> [<path>]
    or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
    or: $dashless [--quiet] init [--] [<path>...]
+   or: $dashless [--quiet] deinit [-f|--force] [--] <path>...
    or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
    or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
    or: $dashless [--quiet] foreach [--recursive] <command>
@@ -547,6 +548,73 @@ cmd_init()
 }

 #
+# Unregister submodules from .git/config and remove their work tree
+#
+# $@ = requested paths (use '.' to deinit all submodules)
+#
+cmd_deinit()
+{
+	# parse $args after "submodule ... init".
+	while test $# -ne 0
+	do
+		case "$1" in
+		-f|--force)
+			force=$1
+			;;
+		-q|--quiet)
+			GIT_QUIET=1
+			;;
+		--)
+			shift
+			break
+			;;
+		-*)
+			usage
+			;;
+		*)
+			break
+			;;
+		esac
+		shift
+	done
+
+	if test "$#" == "0"
+	then
+		die "$(eval_gettext "Use '.' if you really want to deinitialize all submodules")"
+	fi
+
+	module_list "$@" |
+	while read mode sha1 stage sm_path
+	do
+		die_if_unmatched "$mode"
+		name=$(module_name "$sm_path") || exit
+		url=$(git config submodule."$name".url)
+		if test -z "$url"
+		then
+			# Only mention uninitialized submodules when its
+			# path have been specified
+			test "$@" != "." &&
+			say "$(eval_gettext "No url found for submodule path '\$sm_path' in .git/config")"
+			continue
+		fi
+
+		# Remove the submodule work tree
+		if test -z $force
+		then
+			git rm -n "$sm_path" ||
+			die "$(eval_gettext "Submodule work tree $sm_path contains local modifications, use '-f' to discard them")"
+		fi
+		rm -rf "$sm_path"
+		mkdir "$sm_path"
+
+		# Remove the whole section so we have a clean state when the
+		# user later decides to init this submodule again
+		git config --remove-section submodule."$name" &&
+		say "$(eval_gettext "Submodule '\$name' (\$url) unregistered for path '\$sm_path'")"
+	done
+}
+
+#
 # Update each submodule path to correct revision, using clone and checkout as needed
 #
 # $@ = requested paths (default to all)
@@ -1157,7 +1225,7 @@ cmd_sync()
 while test $# != 0 && test -z "$command"
 do
 	case "$1" in
-	add | foreach | init | update | status | summary | sync)
+	add | foreach | init | deinit | update | status | summary | sync)
 		command=$1
 		;;
 	-q|--quiet)
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index 2683cba..34d8274 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -757,4 +757,28 @@ test_expect_success 'submodule add with an existing name fails unless forced' '
 	)
 '

+test_expect_success 'submodule deinit should remove the whole submodule section from .git/config' '
+	git config submodule.example.foo bar &&
+	git submodule deinit init &&
+	test -z "$(git config submodule.example.url)" &&
+	test -z "$(git config submodule.example.foo)"
+'
+
+test_expect_success 'submodule deinit . deinits all initialized submodules' '
+	git submodule update --init &&
+	git config submodule.example.foo bar &&
+	test_must_fail git submodule deinit &&
+	git submodule deinit . &&
+	test -z "$(git config submodule.example.url)" &&
+	test -z "$(git config submodule.example.foo)"
+'
+
+test_expect_success 'submodule deinit complains when explicitly used on an uninitialized submodule' '
+	git submodule update --init &&
+	git submodule deinit init >actual &&
+	test_i18ngrep "Submodule .example. (.*) unregistered for path .init" actual
+	git submodule deinit init >actual &&
+	test_i18ngrep "No url found for submodule path .init. in .git/config" actual
+'
+
 test_done
-- 
1.8.1.2.460.gae7a4e0

^ permalink raw reply related

* What's cooking in git.git (Feb 2013, #02; Mon, 4)
From: Junio C Hamano @ 2013-02-04 20:08 UTC (permalink / raw)
  To: git

Here are the topics that have been cooking.  Commits prefixed with
'-' are only in 'pu' (proposed updates) while commits prefixed with
'+' are in 'next'.

As usual, this cycle is expected to last for 8 to 10 weeks, with a
preview -rc0 sometime in the middle of this month.

You can find the changes described here in the integration branches of the
repositories listed at

    http://git-blame.blogspot.com/p/git-public-repositories.html

--------------------------------------------------
[Graduated to "master"]

* jc/custom-comment-char (2013-01-16) 1 commit
  (merged to 'next' on 2013-01-25 at 91d8a5d)
 + Allow custom "comment char"

 Allow a configuration variable core.commentchar to customize the
 character used to comment out the hint lines in the edited text
 from the default '#'.

 This is half my work and half by Ralf Thielow.  There may still be
 leftover '#' lurking around, though.  My "git grep" says C code
 should be already fine, but git-rebase--interactive.sh could be
 converted (it should not matter, as the file is not really a
 free-form text).


* jc/push-reject-reasons (2013-01-24) 4 commits
  (merged to 'next' on 2013-01-28 at b60be93)
 + push: finishing touches to explain REJECT_ALREADY_EXISTS better
 + push: introduce REJECT_FETCH_FIRST and REJECT_NEEDS_FORCE
 + push: further simplify the logic to assign rejection reason
 + push: further clean up fields of "struct ref"

 Improve error and advice messages given locally when "git push"
 refuses when it cannot compute fast-forwardness by separating these
 cases from the normal "not a fast-forward; merge first and push
 again" case.


* jk/config-parsing-cleanup (2013-01-23) 8 commits
  (merged to 'next' on 2013-01-28 at 9bc9411)
 + reflog: use parse_config_key in config callback
 + help: use parse_config_key for man config
 + submodule: simplify memory handling in config parsing
 + submodule: use parse_config_key when parsing config
 + userdiff: drop parse_driver function
 + convert some config callbacks to parse_config_key
 + archive-tar: use parse_config_key when parsing config
 + config: add helper function for parsing key names

 Configuration parsing for tar.* configuration variables were
 broken. Introduce a new config-keyname parser API to make the
 callers much less error prone.


* jk/read-commit-buffer-data-after-free (2013-01-26) 3 commits
  (merged to 'next' on 2013-01-30 at c6d7e16)
 + logmsg_reencode: lazily load missing commit buffers
 + logmsg_reencode: never return NULL
 + commit: drop useless xstrdup of commit message

 Clarify the ownership rule for commit->buffer field, which some
 callers incorrectly accessed without making sure it is populated.


* jk/remote-helpers-in-python-3 (2013-01-30) 10 commits
  (merged to 'next' on 2013-01-31 at 5a948aa)
 + git_remote_helpers: remove GIT-PYTHON-VERSION upon "clean"
  (merged to 'next' on 2013-01-28 at d898471)
 + git-remote-testpy: fix path hashing on Python 3
  (merged to 'next' on 2013-01-25 at acf9419)
 + git-remote-testpy: call print as a function
 + git-remote-testpy: don't do unbuffered text I/O
 + git-remote-testpy: hash bytes explicitly
 + svn-fe: allow svnrdump_sim.py to run with Python 3
 + git_remote_helpers: use 2to3 if building with Python 3
 + git_remote_helpers: force rebuild if python version changes
 + git_remote_helpers: fix input when running under Python 3
 + git_remote_helpers: allow building with Python 3

 Prepare remote-helper test written in Python to be run with Python3.


* mm/add-u-A-sans-pathspec (2013-01-28) 1 commit
  (merged to 'next' on 2013-01-28 at fe762a6)
 + add: warn when -u or -A is used without pathspec

 Forbid "git add -u" and "git add -A" without pathspec run from a
 subdirectory, to train people to type "." (or ":/") to make the
 choice of default does not matter.


* pw/git-p4-on-cygwin (2013-01-26) 21 commits
  (merged to 'next' on 2013-01-30 at 958ae3a)
 + git p4: introduce gitConfigBool
 + git p4: avoid shell when calling git config
 + git p4: avoid shell when invoking git config --get-all
 + git p4: avoid shell when invoking git rev-list
 + git p4: avoid shell when mapping users
 + git p4: disable read-only attribute before deleting
 + git p4 test: use test_chmod for cygwin
 + git p4: cygwin p4 client does not mark read-only
 + git p4 test: avoid wildcard * in windows
 + git p4 test: use LineEnd unix in windows tests too
 + git p4 test: newline handling
 + git p4: scrub crlf for utf16 files on windows
 + git p4: remove unreachable windows \r\n conversion code
 + git p4 test: translate windows paths for cygwin
 + git p4 test: start p4d inside its db dir
 + git p4 test: use client_view in t9806
 + git p4 test: avoid loop in client_view
 + git p4 test: use client_view to build the initial client
 + git p4: generate better error message for bad depot path
 + git p4: remove unused imports
 + git p4: temp branch name should use / even on windows

 Improve "git p4" on Cygwin.

--------------------------------------------------
[New Topics]

* jn/auto-depend-workaround-buggy-ccache (2013-02-01) 1 commit
  (merged to 'next' on 2013-02-02 at db5940a)
 + Makefile: explicitly set target name for autogenerated dependencies

 An age-old workaround to prevent buggy versions of ccache from
 breaking the auto-generation of dependencies, which unfortunately
 is still relevant because some people use ancient distros.

 Will merge to 'master'.


* ct/autoconf-htmldir (2013-02-02) 1 commit
 - Honor configure's htmldir switch

 The autoconf subsystem passed --mandir down to generated
 config.mak.autogen but forgot to do the same for --htmldir.

 Will merge to 'next'.


* mk/tcsh-complete-only-known-paths (2013-02-03) 1 commit
 - completion: handle path completion and colon for tcsh script
 (this branch uses mp/complete-paths.)

 Manlio's "complete with known paths only" update to completion
 scripts returns directory names without trailing slash to
 compensate the addition of '/' done by bash that reads from our
 completion result.  tcsh completion code that reads from our
 internal completion result does not add '/', so let it ask our
 complletion code to keep the '/' at the end.

 Will merge to 'next'.


* jc/combine-diff-many-parents (2013-02-03) 1 commit
 - combine-diff: lift 32-way limit of combined diff

 We used to have an arbitrary 32 limit for combined diff input,
 resulting in incorrect number of leading colons shown when showing
 the "--raw --cc" output.

 May want a couple of new tests.


* jc/remove-export-from-config-mak-in (2013-02-03) 1 commit
 - config.mak.in: remove unused definitions

 config.mak.in template had an "export" line to cause a few
 common makefile variables to be exported; if they need to be
 expoted for autoconf/configure users, they should also be exported
 for people who write config.mak the same way.  Move the "export" to
 the main Makefile.


* jk/apply-similaritly-parsing (2013-02-03) 1 commit
 - builtin/apply: tighten (dis)similarity index parsing

 Make sure the similarity value shown in the "apply --summary"
 output is sensible, even when the input had a bogus value.

 Will merge to 'next'.


* nd/status-show-in-progress (2013-02-03) 1 commit
 - status: show the branch name if possible in in-progress info

--------------------------------------------------
[Stalled]

* dg/subtree-fixes (2013-01-08) 7 commits
 - contrib/subtree: mkdir the manual directory if needed
 - contrib/subtree: honor $(DESTDIR)
 - contrib/subtree: fix synopsis and command help
 - contrib/subtree: better error handling for "add"
 - contrib/subtree: add --unannotate option
 - contrib/subtree: use %B for split Subject/Body
 - t7900: remove test number comments

 contrib/subtree updates; there are a few more from T. Zheng that
 were posted separately, with an overlap.

 Expecting a reroll.


* mp/diff-algo-config (2013-01-16) 3 commits
 - diff: Introduce --diff-algorithm command line option
 - config: Introduce diff.algorithm variable
 - git-completion.bash: Autocomplete --minimal and --histogram for git-diff

 Add diff.algorithm configuration so that the user does not type
 "diff --histogram".

 Looking better; may want tests to protect it from future breakages,
 but otherwise it looks ready for 'next'.

 Expecting a follow-up to add tests.


* mb/gitweb-highlight-link-target (2012-12-20) 1 commit
 - Highlight the link target line in Gitweb using CSS

 Expecting a reroll.
 $gmane/211935


* jl/submodule-deinit (2012-12-04) 1 commit
 - submodule: add 'deinit' command

 There was no Porcelain way to say "I no longer am interested in
 this submodule", once you express your interest in a submodule with
 "submodule init".  "submodule deinit" is the way to do so.

 Expecting a reroll.
 $gmane/212884


* jk/lua-hackery (2012-10-07) 6 commits
 - pretty: fix up one-off format_commit_message calls
 - Minimum compilation fixup
 - Makefile: make "lua" a bit more configurable
 - add a "lua" pretty format
 - add basic lua infrastructure
 - pretty: make some commit-parsing helpers more public

 Interesting exercise. When we do this for real, we probably would want
 to wrap a commit to make it more like an "object" with methods like
 "parents", etc.


* rc/maint-complete-git-p4 (2012-09-24) 1 commit
 - Teach git-completion about git p4

 Comment from Pete will need to be addressed ($gmane/206172).


* jc/maint-name-rev (2012-09-17) 7 commits
 - describe --contains: use "name-rev --algorithm=weight"
 - name-rev --algorithm=weight: tests and documentation
 - name-rev --algorithm=weight: cache the computed weight in notes
 - name-rev --algorithm=weight: trivial optimization
 - name-rev: --algorithm option
 - name_rev: clarify the logic to assign a new tip-name to a commit
 - name-rev: lose unnecessary typedef

 "git name-rev" names the given revision based on a ref that can be
 reached in the smallest number of steps from the rev, but that is
 not useful when the caller wants to know which tag is the oldest one
 that contains the rev.  This teaches a new mode to the command that
 uses the oldest ref among those which contain the rev.

 I am not sure if this is worth it; for one thing, even with the help
 from notes-cache, it seems to make the "describe --contains" even
 slower. Also the command will be unusably slow for a user who does
 not have a write access (hence unable to create or update the
 notes-cache).

 Stalled mostly due to lack of responses.


* jc/xprm-generation (2012-09-14) 1 commit
 - test-generation: compute generation numbers and clock skews

 A toy to analyze how bad the clock skews are in histories of real
 world projects.

 Stalled mostly due to lack of responses.


* jc/add-delete-default (2012-08-13) 1 commit
 - git add: notice removal of tracked paths by default

 "git add dir/" updated modified files and added new files, but does
 not notice removed files, which may be "Huh?" to some users.  They
 can of course use "git add -A dir/", but why should they?

 Resurrected from graveyard, as I thought it was a worthwhile thing
 to do in the longer term.

 Stalled mostly due to lack of responses.


* mb/remote-default-nn-origin (2012-07-11) 6 commits
 - Teach get_default_remote to respect remote.default.
 - Test that plain "git fetch" uses remote.default when on a detached HEAD.
 - Teach clone to set remote.default.
 - Teach "git remote" about remote.default.
 - Teach remote.c about the remote.default configuration setting.
 - Rename remote.c's default_remote_name static variables.

 When the user does not specify what remote to interact with, we
 often attempt to use 'origin'.  This can now be customized via a
 configuration variable.

 Expecting a reroll.
 $gmane/210151

 "The first remote becomes the default" bit is better done as a
 separate step.


* nd/parse-pathspec (2013-01-11) 20 commits
 . Convert more init_pathspec() to parse_pathspec()
 . Convert add_files_to_cache to take struct pathspec
 . Convert {read,fill}_directory to take struct pathspec
 . Convert refresh_index to take struct pathspec
 . Convert report_path_error to take struct pathspec
 . checkout: convert read_tree_some to take struct pathspec
 . Convert unmerge_cache to take struct pathspec
 . Convert read_cache_preload() to take struct pathspec
 . add: convert to use parse_pathspec
 . archive: convert to use parse_pathspec
 . ls-files: convert to use parse_pathspec
 . rm: convert to use parse_pathspec
 . checkout: convert to use parse_pathspec
 . rerere: convert to use parse_pathspec
 . status: convert to use parse_pathspec
 . commit: convert to use parse_pathspec
 . clean: convert to use parse_pathspec
 . Export parse_pathspec() and convert some get_pathspec() calls
 . Add parse_pathspec() that converts cmdline args to struct pathspec
 . pathspec: save the non-wildcard length part

 Uses the parsed pathspec structure in more places where we used to
 use the raw "array of strings" pathspec.

 Ejected from 'pu' for now; will take a look at the rerolled one
 later ($gmane/213340).

--------------------------------------------------
[Cooking]

* ft/transport-report-segv (2013-01-31) 1 commit
  (merged to 'next' on 2013-02-02 at 6c450a7)
 + push: fix segfault when HEAD points nowhere

 A failure to push due to non-ff while on an unborn branch
 dereferenced a NULL pointer when showing an error message.

 Will merge to 'master'.


* sb/gpg-i18n (2013-01-31) 1 commit
  (merged to 'next' on 2013-02-02 at 7a54574)
 + gpg: allow translation of more error messages

 Will merge to 'master'.


* sb/gpg-plug-fd-leak (2013-01-31) 1 commit
  (merged to 'next' on 2013-02-02 at c271a31)
 + gpg: close stderr once finished with it in verify_signed_buffer()

 We forgot to close the file descriptor reading from "gpg" output,
 killing "git log --show-signature" on a long history.

 Will merge to 'master'.


* sb/run-command-fd-error-reporting (2013-02-01) 1 commit
  (merged to 'next' on 2013-02-02 at be7e970)
 + run-command: be more informative about what failed

 Will merge to 'master'.


* jk/remote-helpers-doc (2013-02-01) 1 commit
  (merged to 'next' on 2013-02-02 at ce1461a)
 + Rename {git- => git}remote-helpers.txt

 "git help remote-helpers" did not work; 'remote-helpers' is not
 a subcommand name but a concept, so its documentation should have
 been in gitremote-helpers, not git-remote-helpers.

 Will merge to 'master'.


* sp/smart-http-content-type-check (2013-02-04) 1 commit
  (merged to 'next' on 2013-02-04 at d0759cb)
 + Verify Content-Type from smart HTTP servers

 The smart HTTP clients forgot to verify the content-type that comes
 back from the server side to make sure that the request is being
 handled properly.

 Will merge to 'master'.


* jc/mention-tracking-for-pull-default (2013-01-31) 1 commit
 - doc: mention tracking for pull.default

 We stopped mentioning `tracking` is a deprecated but supported
 synonym for `upstream` in pull.default even though we have no
 intention of removing the support for it.

 This is my "don't list it to catch readers' eyes, but make sure it
 can be found if the reader looks for it" version; I'm not married
 to the layout and am willing to take a replacement patch.


* jc/fake-ancestor-with-non-blobs (2013-01-31) 3 commits
  (merged to 'next' on 2013-02-02 at 86d457a)
 + apply: diagnose incomplete submodule object name better
 + apply: simplify build_fake_ancestor()
 + git-am: record full index line in the patch used while rebasing

 Rebasing the history of superproject with change in the submodule
 has been broken since v1.7.12.

 Will merge to 'master'.


* jk/doc-makefile-cleanup (2013-02-01) 1 commit
  (merged to 'next' on 2013-02-02 at 86ff373)
 + Documentation/Makefile: clean up MAN*_TXT lists

 Will merge to 'master'.


* ab/gitweb-use-same-scheme (2013-01-28) 1 commit
  (merged to 'next' on 2013-02-02 at 7e4a108)
 + gitweb: refer to picon/gravatar images over the same scheme

 Avoid mixed contents on a page coming via http and https when
 gitweb is hosted on a https server.

 Will merge to 'master'.


* jk/python-styles (2013-01-30) 1 commit
  (merged to 'next' on 2013-02-02 at 293edc1)
 + CodingGuidelines: add Python coding guidelines

 Will merge to 'master'.


* mn/send-email-authinfo (2013-01-29) 1 commit
 - git-send-email: add ~/.authinfo parsing

 Expecting a reroll.
 $gmane/215004, $gmane/215024.


* mp/complete-paths (2013-01-11) 1 commit
  (merged to 'next' on 2013-01-30 at 70e4f1a)
 + git-completion.bash: add support for path completion
 (this branch is used by mk/tcsh-complete-only-known-paths.)

 The completion script used to let the default completer to suggest
 pathnames, which gave too many irrelevant choices (e.g. "git add"
 would not want to add an unmodified path).  Teach it to use a more
 git-aware logic to enumerate only relevant ones.

 This is logically the right thing to do, and we would really love
 to see people who have been involved in completion code to review
 and comment on the implementation.

 Will cook in 'next' to see if anybody screams.


* ss/mergetools-tortoise (2013-02-01) 2 commits
  (merged to 'next' on 2013-02-03 at d306b83)
 + mergetools: teach tortoisemerge to handle filenames with SP correctly
 + mergetools: support TortoiseGitMerge

 Update mergetools to work better with newer merge helper tortoise ships.

 Will merge to 'master'.


* da/mergetool-docs (2013-02-02) 5 commits
  (merged to 'next' on 2013-02-03 at f822dcf)
 + doc: generate a list of valid merge tools
 + mergetool--lib: list user configured tools in '--tool-help'
 + mergetool--lib: add functions for finding available tools
 + mergetool--lib: improve the help text in guess_merge_tool()
 + mergetool--lib: simplify command expressions
 (this branch uses jk/mergetool.)

 Build on top of the clean-up done by jk/mergetool and automatically
 generate the list of mergetool and difftool backends the build
 supports to be included in the documentation.

 Will merge to 'master'.


* nd/branch-error-cases (2013-01-31) 6 commits
  (merged to 'next' on 2013-02-02 at cf5e745)
 + branch: let branch filters imply --list
 + docs: clarify git-branch --list behavior
 + branch: mark more strings for translation
 + Merge branch 'nd/edit-branch-desc-while-detached' into HEAD
 + branch: give a more helpful message on redundant arguments
 + branch: reject -D/-d without branch name

 Fix various error messages and conditions in "git branch", e.g. we
 advertised "branch -d/-D" to remove one or more branches but actually
 implemented removal of zero or more branches---request to remove no
 branches was not rejected.

 Will merge to 'master'.


* jk/mergetool (2013-01-28) 8 commits
  (merged to 'next' on 2013-02-03 at 2ff5dee)
 + mergetools: simplify how we handle "vim" and "defaults"
 + mergetool--lib: don't call "exit" in setup_tool
 + mergetool--lib: improve show_tool_help() output
 + mergetools/vim: remove redundant diff command
 + git-difftool: use git-mergetool--lib for "--tool-help"
 + git-mergetool: don't hardcode 'mergetool' in show_tool_help
 + git-mergetool: remove redundant assignment
 + git-mergetool: move show_tool_help to mergetool--lib
 (this branch is used by da/mergetool-docs.)

 Cleans up mergetool/difftool combo.

 Will merge to 'master'.


* jc/hidden-refs (2013-01-30) 8 commits
 - WIP: receive.allowupdatestohidden
 - fetch: fetch objects by their exact SHA-1 object names
 - upload-pack: optionally allow fetching from the tips of hidden refs
 - fetch: use struct ref to represent refs to be fetched
 - parse_fetch_refspec(): clarify the codeflow a bit
 - upload/receive-pack: allow hiding ref hierarchies
 - upload-pack: simplify request validation
 - upload-pack: share more code

 Allow the server side to unclutter the refs/ namespace it shows to
 the client.  Optionally allow requests for histories leading to the
 tips of hidden refs by updated clients.

 Will merge to 'next' after dropping the tip.


* ta/doc-no-small-caps (2013-02-01) 6 commits
  (merged to 'next' on 2013-02-02 at 77cbd0e)
 + Documentation: StGit is the right spelling, not StGIT
 + Documentation: describe the "repository" in repository-layout
 + Documentation: add a description for 'gitfile' to glossary
 + Documentation: do not use undefined terms git-dir and git-file
 + Documentation: the name of the system is 'Git', not 'git'
 + Documentation: avoid poor-man's small caps GIT

 Update documentation to change "GIT" which was a poor-man's small
 caps to "Git".  The latter was the intended spelling.

 Also change "git" spelled in all-lowercase to "Git" when it refers
 to the system as the whole or the concept it embodies, as opposed to
 the command the end users would type.

 Will merge to 'master'.


* jc/remove-treesame-parent-in-simplify-merges (2013-01-17) 1 commit
  (merged to 'next' on 2013-01-30 at b639b47)
 + simplify-merges: drop merge from irrelevant side branch

 The --simplify-merges logic did not cull irrelevant parents from a
 merge that is otherwise not interesting with respect to the paths
 we are following.

 This touches a fairly core part of the revision traversal
 infrastructure; even though I think this change is correct, please
 report immediately if you find any unintended side effect.

 Will cook in 'next'.


* jc/push-2.0-default-to-simple (2013-01-16) 14 commits
  (merged to 'next' on 2013-01-16 at 23f5df2)
 + t5570: do not assume the "matching" push is the default
 + t5551: do not assume the "matching" push is the default
 + t5550: do not assume the "matching" push is the default
  (merged to 'next' on 2013-01-09 at 74c3498)
 + doc: push.default is no longer "matching"
 + push: switch default from "matching" to "simple"
 + t9401: do not assume the "matching" push is the default
 + t9400: do not assume the "matching" push is the default
 + t7406: do not assume the "matching" push is the default
 + t5531: do not assume the "matching" push is the default
 + t5519: do not assume the "matching" push is the default
 + t5517: do not assume the "matching" push is the default
 + t5516: do not assume the "matching" push is the default
 + t5505: do not assume the "matching" push is the default
 + t5404: do not assume the "matching" push is the default

 Will cook in 'next' until Git 2.0 ;-).


* bc/append-signed-off-by (2013-01-27) 11 commits
 - Unify appending signoff in format-patch, commit and sequencer
 - format-patch: update append_signoff prototype
 - t4014: more tests about appending s-o-b lines
 - sequencer.c: teach append_signoff to avoid adding a duplicate newline
 - sequencer.c: teach append_signoff how to detect duplicate s-o-b
 - sequencer.c: always separate "(cherry picked from" from commit body
 - sequencer.c: recognize "(cherry picked from ..." as part of s-o-b footer
 - t/t3511: add some tests of 'cherry-pick -s' functionality
 - t/test-lib-functions.sh: allow to specify the tag name to test_commit
 - commit, cherry-pick -s: remove broken support for multiline rfc2822 fields
 - sequencer.c: rework search for start of footer to improve clarity

 Waiting for the final round of reroll before merging to 'next'.
 After that we will go incremental.

^ permalink raw reply

* [PATCH] Add contrib/credentials/netrc with GPG support
From: Ted Zlatanov @ 2013-02-04 19:54 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Jeff King


Signed-off-by: Ted Zlatanov <tzz@lifelogs.com>
---
 contrib/credential/netrc/git-credential-netrc |  223 +++++++++++++++++++++++++
 1 files changed, 223 insertions(+), 0 deletions(-)
 create mode 100755 contrib/credential/netrc/git-credential-netrc

diff --git a/contrib/credential/netrc/git-credential-netrc b/contrib/credential/netrc/git-credential-netrc
new file mode 100755
index 0000000..7b43aa9
--- /dev/null
+++ b/contrib/credential/netrc/git-credential-netrc
@@ -0,0 +1,223 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Getopt::Long;
+use File::Basename;
+
+my $VERSION = "0.1";
+
+my %options = (
+               help => 0,
+               debug => 0,
+
+               # identical token maps, e.g. host -> host, will be inserted later
+               tmap => {
+                        port => 'protocol',
+                        machine => 'host',
+                        path => 'path',
+                        login => 'username',
+                        user => 'username',
+                        password => 'password',
+                       }
+              );
+
+# map each credential protocol token to itself on the netrc side
+$options{tmap}->{$_} = $_ foreach my $v (values %{$options{tmap}});
+
+foreach my $suffix ('.gpg', '') {
+	foreach my $base (qw/authinfo netrc/) {
+		my $file = glob("~/.$base$suffix");
+		next unless (defined $file && -f $file);
+		$options{file} = $file ;
+	}
+}
+
+Getopt::Long::Configure("bundling");
+
+# TODO: maybe allow the token map $options{tmap} to be configurable.
+GetOptions(\%options,
+           "help|h",
+           "debug|d",
+           "file|f=s",
+          );
+
+if ($options{help}) {
+	my $shortname = basename($0);
+	$shortname =~ s/git-credential-//;
+
+	print <<EOHIPPUS;
+
+$0 [-f AUTHFILE] [-d] get
+
+Version $VERSION by tzz\@lifelogs.com.  License: BSD.
+
+Options:
+  -f AUTHFILE: specify a netrc-style file
+  -d: turn on debugging
+
+To enable (note that Git will prepend "git-credential-" to the helper
+name and look for it in the path):
+
+  git config credential.helper '$shortname -f AUTHFILE'
+
+And if you want lots of debugging info:
+
+  git config credential.helper '$shortname -f AUTHFILE -d'
+
+Only "get" mode is supported by this credential helper.  It opens
+AUTHFILE and looks for entries that match the requested search
+criteria:
+
+ 'port|protocol':
+   The protocol that will be used (e.g., https). (protocol=X)
+
+ 'machine|host':
+   The remote hostname for a network credential. (host=X)
+
+ 'path':
+   The path with which the credential will be used. (path=X)
+
+ 'login|user|username':
+   The credential’s username, if we already have one. (username=X)
+
+Thus, when we get "protocol=https\nusername=tzz", this credential
+helper will look for lines in AUTHFILE that match
+
+port https login tzz
+
+OR
+
+protocol https login tzz
+
+OR... etc. acceptable tokens as listed above.  Any unknown tokens are
+simply ignored.
+
+Then, the helper will print out whatever tokens it got from the line,
+including "password" tokens, mapping e.g. "port" back to "protocol".
+
+The first matching line is used.  Tokens can be quoted as 'STRING' or
+"STRING".
+
+No caching is performed by this credential helper.
+
+EOHIPPUS
+
+	exit;
+}
+
+my $mode = shift @ARGV;
+
+# credentials may get 'get', 'store', or 'erase' as parameters but
+# only acknowledge 'get'
+die "Syntax: $0 [-f AUTHFILE] [-d] get" unless defined $mode;
+
+# only support 'get' mode
+exit unless $mode eq 'get';
+
+my $debug = $options{debug};
+my $file = $options{file};
+
+die "Sorry, you need to specify an existing netrc file (with or without a .gpg extension) with -f AUTHFILE"
+ unless defined $file;
+
+unless (-f $file) {
+	print STDERR "Sorry, the specified netrc $file is not accessible\n" if $debug;
+	exit 0;
+}
+
+my @data;
+if ($file =~ m/\.gpg$/) {
+	@data = load('-|', qw(gpg --decrypt), $file)
+}
+else {
+	@data = load('<', $file);
+}
+
+chomp @data;
+
+unless (scalar @data) {
+	print STDERR "Sorry, we could not load data from [$file]\n" if $debug;
+	exit;
+}
+
+# the query: start with every token with no value
+my %q = map { $_ => undef } values(%{$options{tmap}});
+
+while (<STDIN>) {
+	next unless m/([^=]+)=(.+)/;
+
+	my ($token, $value) = ($1, $2);
+	die "Unknown search token $1" unless exists $q{$token};
+	$q{$token} = $value;
+}
+
+# build reverse token map
+my %rmap;
+foreach my $k (keys %{$options{tmap}}) {
+	push @{$rmap{$options{tmap}->{$k}}}, $k;
+}
+
+# there are CPAN modules to do this better, but we want to avoid
+# dependencies and generally, complex netrc-style files are rare
+
+if ($debug) {
+	printf STDERR "searching for %s = %s\n", $_, $q{$_} || '(any value)'
+	 foreach sort keys %q;
+}
+
+LINE: foreach my $line (@data) {
+
+	print STDERR "line [$line]\n" if $debug;
+	my @tok;
+	# gratefully stolen from Net::Netrc
+	while (length $line &&
+	       $line =~ s/^("((?:[^"]+|\\.)*)"|((?:[^\\\s]+|\\.)*))\s*//) {
+		(my $tok = $+) =~ s/\\(.)/$1/g;
+		push(@tok, $tok);
+	}
+
+	# skip blank lines, comments, etc.
+	next LINE unless scalar @tok;
+
+	my %tokens;
+	while (@tok) {
+		my ($k, $v) = (shift @tok, shift @tok);
+		next unless defined $v;
+		next unless exists $options{tmap}->{$k};
+		$tokens{$options{tmap}->{$k}} = $v;
+	}
+
+	foreach my $check (sort keys %q) {
+		if (exists $tokens{$check} && defined $q{$check}) {
+			print STDERR "comparing [$tokens{$check}] to [$q{$check}] in line [$line]\n" if $debug;
+			next LINE unless $tokens{$check} eq $q{$check};
+		}
+		else {
+			print STDERR "we could not find [$check] but it's OK\n" if $debug;
+		}
+	}
+
+	print STDERR "line has passed all the search checks\n" if $debug;
+ TOKEN:
+	foreach my $token (sort keys %rmap) {
+		print STDERR "looking for useful token $token\n" if $debug;
+		next unless exists $tokens{$token}; # did we match?
+
+		foreach my $rctoken (@{$rmap{$token}}) {
+			next TOKEN if defined $q{$rctoken};           # don't re-print given tokens
+		}
+
+		print STDERR "FOUND: $token=$tokens{$token}\n" if $debug;
+		printf "%s=%s\n", $token, $tokens{$token};
+	}
+
+	last;
+}
+
+sub load {
+	# this supports pipes too
+	my $io = new IO::File(@_) or die "Could not open [@_]: $!\n";
+	return <$io>;                          # whole file
+}
-- 
1.7.9.rc2

^ permalink raw reply related

* Re: [PATCH 1/3] Add contrib/credentials/netrc with GPG support
From: Ted Zlatanov @ 2013-02-04 19:40 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Jeff King
In-Reply-To: <7vvca7291z.fsf@alter.siamese.dyndns.org>

On Mon, 04 Feb 2013 11:06:16 -0800 Junio C Hamano <gitster@pobox.com> wrote: 

JCH> Ted Zlatanov <tzz@lifelogs.com> writes:
>> Sorry, I didn't realize contrib/ stuff was under the same rules.

JCH> I had a feeling that this may start out from contrib/ but will soon
JCH> prove to be fairly important to be part of the Git proper.

Cool!

>> It would help if the requirements were codified as the fairly standard
>> Emacs file-local variables, so I can just put them in the Perl code or
>> in .dir-locals.el in the source tree.  At least for Perl I'd like that,
>> and it could be nice for the Emacs users who write C too.
>> 
>> Would you like me to propose that as a patch?

JCH> I thought that we tend to avoid Emacs/Vim formatting cruft left in
JCH> the file.  Do we have any in existing file outside contrib/?

No, but it's a nice way to express the settings so no one is guessing
what the project prefers.  At least for me it's not an issue anymore,
since I understand your criteria better now, so let me know if you want
me to express it in the CodingGuidelines, in a dir-locals.el file, or
somewhere else.

>> Either way, I guessed that these settings are what you want as far as
>> tabs and indentation (I use cperl-mode but perl-mode is the same):
>> 
>> # -*- mode: cperl; tab-width: 8; cperl-indent-level: 4; indent-tabs-mode: t; -*-

JCH> Indent is done with a Tab and indent level is 8 places (check add--interactive.perl
JCH> and imitate it, perhaps?).

Yup, got it.  My mistake on the size-4 indents.

I found this helpful, at least while I was indenting, for anyone else
who might want to indent Perl appropriately to imitate existing Perl code:

# -*- mode: cperl; tab-width: 8; cperl-indent-level: 8; indent-tabs-mode: t; -*-

I'll resubmit now.

Thanks
Ted

^ permalink raw reply

* Re: Bug: file named - on git commit
From: Jonathan Nieder @ 2013-02-04 19:32 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Thomas Rast, Rene Moser, git
In-Reply-To: <7v8v742cwh.fsf@alter.siamese.dyndns.org>

Junio C Hamano wrote:

>            (some may be too minor to be worth backproting, for
> example).

Yes, this is the part I was asking for help with.  Backporting is easy
but convincing the release team and upgrade-averse sysadmins to like
the result generally isn't.  Occasional nominations of the form "this
change is important in my workflow" could help.

Continuing to stick to fixes to very severe bugs that stand out plus a
random assortment of problems people have reported can also work fine,
though.

Thanks,
Jonathan

^ permalink raw reply

* Re: [PATCH 1/3] Add contrib/credentials/netrc with GPG support
From: Junio C Hamano @ 2013-02-04 19:06 UTC (permalink / raw)
  To: Ted Zlatanov; +Cc: git, Jeff King
In-Reply-To: <87k3qoudxp.fsf@lifelogs.com>

Ted Zlatanov <tzz@lifelogs.com> writes:

> Sorry, I didn't realize contrib/ stuff was under the same rules.

I had a feeling that this may start out from contrib/ but will soon
prove to be fairly important to be part of the Git proper.

> It would help if the requirements were codified as the fairly standard
> Emacs file-local variables, so I can just put them in the Perl code or
> in .dir-locals.el in the source tree.  At least for Perl I'd like that,
> and it could be nice for the Emacs users who write C too.
>
> Would you like me to propose that as a patch?

I thought that we tend to avoid Emacs/Vim formatting cruft left in
the file.  Do we have any in existing file outside contrib/?

> Either way, I guessed that these settings are what you want as far as
> tabs and indentation (I use cperl-mode but perl-mode is the same):
>
> # -*- mode: cperl; tab-width: 8; cperl-indent-level: 4; indent-tabs-mode: t; -*-

Indent is done with a Tab and indent level is 8 places (check add--interactive.perl
and imitate it, perhaps?).

Thanks.

^ permalink raw reply

* Re: [PATCH 3/3] Fix contrib/credentials/netrc minor issues: exit quietly; use 3-parameter open; etc.
From: Ted Zlatanov @ 2013-02-04 18:41 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Jeff King
In-Reply-To: <7vfw1c2dm5.fsf@alter.siamese.dyndns.org>

On Mon, 04 Feb 2013 09:27:46 -0800 Junio C Hamano <gitster@pobox.com> wrote: 

JCH> Ted Zlatanov <tzz@lifelogs.com> writes:
>> Signed-off-by: Ted Zlatanov <tzz@lifelogs.com>
>> ---
>> contrib/credential/netrc/git-credential-netrc |   38 +++++++++++++------------
>> 1 files changed, 20 insertions(+), 18 deletions(-)

JCH> Especially because this is an initial submission, please equash
JCH> three patches into one, instead of sending three "here is my first
JCH> attempt with many problems I know I do not want to be there", "one
JCH> small improvement", "another one to fix remaining issues".

JCH> Otherwise you will waste reviewers' time, getting distracted by
JCH> undesirable details they find in an earlier patch while reviewing,
JCH> without realizing that some of them are fixed in a later one.

OK, thanks.  I wasn't sure, since Jeff already reviewed it, if it was
better to squash or not.  Ignore this same question in my other reply to
you, and thanks for your patience.

Ted

^ permalink raw reply

* Re: Segmentation fault with latest git (070c57df)
From: Jonathan Nieder @ 2013-02-04 18:34 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, jongman.heo, Thomas Rast, git, Antoine Pelisse
In-Reply-To: <7vboc03u3e.fsf@alter.siamese.dyndns.org>

Junio C Hamano wrote:

> The only case that worries me is when make or cc gets interrupted.
> As long as make removes the ultimate target *.o in such a case, it
> is fine to leave a half-written .depend/foo.o.d (or getting it
> removed) behind.

gcc removes the target .o in its signal handler in such a case.  In
cases where it doesn't get a chance to (e.g., sudden power failure),
there is a partially written .o file already in place, the linker
produces errors, and the operator is convinced to run "make clean",
all without .depend's help.

^ permalink raw reply

* Re: [PATCH 1/3] Add contrib/credentials/netrc with GPG support
From: Ted Zlatanov @ 2013-02-04 18:33 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Jeff King
In-Reply-To: <7vk3qo2dsc.fsf@alter.siamese.dyndns.org>

[-- Attachment #1: Type: text/plain, Size: 1969 bytes --]

On Mon, 04 Feb 2013 09:24:03 -0800 Junio C Hamano <gitster@pobox.com> wrote: 

JCH> [administrivia: I would really wish you didn't put "Mail-copies-to:
JCH> never" above].

I normally post through GMane and don't need the extra CC on any list I
read.  I'll make an effort to remove that header here, and apologize for
the inconvenience.

JCH> Ted Zlatanov <tzz@lifelogs.com> writes:

>> +foreach my $v (values %{$options{tmap}})
>> +{
>> + $options{tmap}->{$v} = $v;
>> +}

JCH> Please follow the styles of existing Perl scripts, e.g. indent with
JCH> tab, etc.  Style requests are not optional; it is a prerequisite to
JCH> make the patch readable and reviewable.

Sorry, I didn't realize contrib/ stuff was under the same rules.  I will
attempt to make my contributions fit the project's requirements.

It would help if the requirements were codified as the fairly standard
Emacs file-local variables, so I can just put them in the Perl code or
in .dir-locals.el in the source tree.  At least for Perl I'd like that,
and it could be nice for the Emacs users who write C too.

Would you like me to propose that as a patch?

Either way, I guessed that these settings are what you want as far as
tabs and indentation (I use cperl-mode but perl-mode is the same):

# -*- mode: cperl; tab-width: 8; cperl-indent-level: 4; indent-tabs-mode: t; -*-

...plus hanging braces and avoiding one-line blocks.  I hope that's right.

>> + print <<EOHIPPUS;
>> + ...
>> +EOHIPPUS

JCH> Do we really need to refer readers to Wikipedia or something to
JCH> learn about extinct equid ungulates ;-)?

I think the marker's name is irrelevant, and hope you are OK with
leaving it.

Since the change is a pretty big reformatting, should I squash my 3
commits plus the reformatting commit into one patch, or keep them as a
series?

I am appending the script in its current form so you can review it and
tell me if there's anything else I should add or change in the
formatting.

Thanks
Ted


[-- Attachment #2: git-credential-netrc --]
[-- Type: text/plain, Size: 5958 bytes --]

#!/usr/bin/perl
# -*- mode: cperl; tab-width: 8; cperl-indent-level: 4; indent-tabs-mode: t; -*-

use strict;
use warnings;

use Getopt::Long;
use File::Basename;

my $VERSION = "0.1";

my %options = (
               help => 0,
               debug => 0,

               # identical token maps, e.g. host -> host, will be inserted later
               tmap => {
                        port => 'protocol',
                        machine => 'host',
                        path => 'path',
                        login => 'username',
                        user => 'username',
                        password => 'password',
                       }
              );

# map each credential protocol token to itself on the netrc side
$options{tmap}->{$_} = $_ foreach my $v (values %{$options{tmap}});

foreach my $suffix ('.gpg', '') {
    foreach my $base (qw/authinfo netrc/) {
	my $file = glob("~/.$base$suffix");
	next unless (defined $file && -f $file);
	$options{file} = $file ;
    }
}

Getopt::Long::Configure("bundling");

# TODO: maybe allow the token map $options{tmap} to be configurable.
GetOptions(\%options,
           "help|h",
           "debug|d",
           "file|f=s",
          );

if ($options{help}) {
    my $shortname = basename($0);
    $shortname =~ s/git-credential-//;

    print <<EOHIPPUS;

$0 [-f AUTHFILE] [-d] get

Version $VERSION by tzz\@lifelogs.com.  License: BSD.

Options:
  -f AUTHFILE: specify a netrc-style file
  -d: turn on debugging

To enable (note that Git will prepend "git-credential-" to the helper
name and look for it in the path):

  git config credential.helper '$shortname -f AUTHFILE'

And if you want lots of debugging info:

  git config credential.helper '$shortname -f AUTHFILE -d'

Only "get" mode is supported by this credential helper.  It opens
AUTHFILE and looks for entries that match the requested search
criteria:

 'port|protocol':
   The protocol that will be used (e.g., https). (protocol=X)

 'machine|host':
   The remote hostname for a network credential. (host=X)

 'path':
   The path with which the credential will be used. (path=X)

 'login|user|username':
   The credential’s username, if we already have one. (username=X)

Thus, when we get "protocol=https\nusername=tzz", this credential
helper will look for lines in AUTHFILE that match

port https login tzz

OR

protocol https login tzz

OR... etc. acceptable tokens as listed above.  Any unknown tokens are
simply ignored.

Then, the helper will print out whatever tokens it got from the line,
including "password" tokens, mapping e.g. "port" back to "protocol".

The first matching line is used.  Tokens can be quoted as 'STRING' or
"STRING".

No caching is performed by this credential helper.

EOHIPPUS

    exit;
}

my $mode = shift @ARGV;

# credentials may get 'get', 'store', or 'erase' as parameters but
# only acknowledge 'get'
die "Syntax: $0 [-f AUTHFILE] [-d] get" unless defined $mode;

# only support 'get' mode
exit unless $mode eq 'get';

my $debug = $options{debug};
my $file = $options{file};

die "Sorry, you need to specify an existing netrc file (with or without a .gpg extension) with -f AUTHFILE"
 unless defined $file;

unless (-f $file) {
    print STDERR "Sorry, the specified netrc $file is not accessible\n" if $debug;
    exit 0;
}

my @data;
if ($file =~ m/\.gpg$/) {
    @data = load('-|', qw(gpg --decrypt), $file)
}
else {
    @data = load('<', $file);
}

chomp @data;

unless (scalar @data) {
    print STDERR "Sorry, we could not load data from [$file]\n" if $debug;
    exit;
}

# the query: start with every token with no value
my %q = map { $_ => undef } values(%{$options{tmap}});

while (<STDIN>) {
    next unless m/([^=]+)=(.+)/;

    my ($token, $value) = ($1, $2);
    die "Unknown search token $1" unless exists $q{$token};
    $q{$token} = $value;
}

# build reverse token map
my %rmap;
foreach my $k (keys %{$options{tmap}}) {
    push @{$rmap{$options{tmap}->{$k}}}, $k;
}

# there are CPAN modules to do this better, but we want to avoid
# dependencies and generally, complex netrc-style files are rare

if ($debug) {
    printf STDERR "searching for %s = %s\n", $_, $q{$_} || '(any value)'
     foreach sort keys %q;
}

LINE: foreach my $line (@data) {

    print STDERR "line [$line]\n" if $debug;
    my @tok;
    # gratefully stolen from Net::Netrc
    while (length $line &&
	   $line =~ s/^("((?:[^"]+|\\.)*)"|((?:[^\\\s]+|\\.)*))\s*//) {
	(my $tok = $+) =~ s/\\(.)/$1/g;
	push(@tok, $tok);
    }

    # skip blank lines, comments, etc.
    next LINE unless scalar @tok;

    my %tokens;
    while (@tok) {
	my ($k, $v) = (shift @tok, shift @tok);
	next unless defined $v;
	next unless exists $options{tmap}->{$k};
	$tokens{$options{tmap}->{$k}} = $v;
    }

    foreach my $check (sort keys %q) {
	if (exists $tokens{$check} && defined $q{$check}) {
	    print STDERR "comparing [$tokens{$check}] to [$q{$check}] in line [$line]\n" if $debug;
	    next LINE unless $tokens{$check} eq $q{$check};
	}
	else {
	    print STDERR "we could not find [$check] but it's OK\n" if $debug;
	}
    }

    print STDERR "line has passed all the search checks\n" if $debug;
 TOKEN:
    foreach my $token (sort keys %rmap) {
	print STDERR "looking for useful token $token\n" if $debug;
	next unless exists $tokens{$token}; # did we match?

	foreach my $rctoken (@{$rmap{$token}}) {
	    next TOKEN if defined $q{$rctoken};           # don't re-print given tokens
	}

	print STDERR "FOUND: $token=$tokens{$token}\n" if $debug;
	printf "%s=%s\n", $token, $tokens{$token};
    }

    last;
}

sub load {
    # this supports pipes too
    my $io = new IO::File(@_) or die "Could not open [@_]: $!\n";
    return <$io>;                          # whole file
}

^ permalink raw reply

* Re: "git archve --format=tar" output changed from 1.8.1 to 1.8.2.1
From: Greg KH @ 2013-02-04 18:26 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Rene Scharfe, git, Konstantin Ryabitsev
In-Reply-To: <7vvca8653g.fsf@alter.siamese.dyndns.org>

On Sun, Feb 03, 2013 at 09:05:55PM -0800, Junio C Hamano wrote:
> Greg KH <gregkh@linuxfoundation.org> writes:
> > The number of people this affects right now is only one (me), given that
> > the offending file is not in Linus's tree right now, so he doesn't have
> > issues with uploading new releases.
> 
> As a tree grows larger over time, it may be just a matter of time
> for somebody else to be hit by another deep path, though.

I agree, and over time, everyone will have updated to a version of git
newer than 1.8.2.1 so we all will be fine again :)

thanks,

greg k-h

^ permalink raw reply

* Re: Feature request: Allow extracting revisions into directories
From: Andreas Schwab @ 2013-02-04 18:21 UTC (permalink / raw)
  To: Robert Clausecker; +Cc: Michael J Gruber, git
In-Reply-To: <1359980045.24730.32.camel@t520>

Robert Clausecker <fuzxxl@gmail.com> writes:

> I have a server that hosts a bare git repository. This git repository
> contains a branch production. Whenever somebody pushes to production a
> hook automatically puts a copy of the current production branch
> into /var/www/foo. I could of course use pull for that but it just does
> not feels right. Why should I have a repository twice on the server? 

You can avoid the separate repo copy by using git new-workdir.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox