From ac62a47ea431271447909b17e883eeaefa87aaea Mon Sep 17 00:00:00 2001
From: Joey Hess <joey@kodama.kitenet.net>
Date: Thu, 17 Jul 2008 16:03:16 -0400
Subject: [PATCH] git: Put web committer name/openid/address in the git author
 field

The committer's email address is not used (because leaking email addresses
is not liked by many users). Closes: #451023

A "Web-commit" trailer is added, to allow telling the difference between
web commits and direct commits.
---
 IkiWiki/Rcs/git.pm            | 58 ++++++++++++++++++++---------------
 debian/changelog              |  3 ++
 doc/todo/git_attribution.mdwn |  2 ++
 3 files changed, 38 insertions(+), 25 deletions(-)

diff --git a/IkiWiki/Rcs/git.pm b/IkiWiki/Rcs/git.pm
index 425536f62..f71b57774 100644
--- a/IkiWiki/Rcs/git.pm
+++ b/IkiWiki/Rcs/git.pm
@@ -180,14 +180,14 @@ sub _parse_diff_tree ($@) { #{{{
 			$ci{ "${who}_epoch" } = $epoch;
 			$ci{ "${who}_tz"    } = $tz;
 
-			if ($name =~ m/^([^<]+) <([^@>]+)/) {
-				my ($fullname, $username) = ($1, $2);
-				$ci{"${who}_fullname"}    = $fullname;
-				$ci{"${who}_username"}    = $username;
+			if ($name =~ m/^[^<]+\s+<([^@>]+)/) {
+				$ci{"${who}_username"} = $1;
+			}
+			elsif ($name =~ m/^([^<]+)\s+<>$/) {
+				$ci{"${who}_username"} = $1;
 			}
 			else {
-				$ci{"${who}_fullname"} =
-					$ci{"${who}_username"} = $name;
+				$ci{"${who}_username"} = $name;
 			}
 		}
 		elsif ($line =~ m/^$/) {
@@ -311,15 +311,6 @@ sub rcs_commit ($$$;$$) { #{{{
 
 	my ($file, $message, $rcstoken, $user, $ipaddr) = @_;
 
-	if (defined $user) {
-		$message = "web commit by $user" .
-		    (length $message ? ": $message" : "");
-	}
-	elsif (defined $ipaddr) {
-		$message = "web commit from $ipaddr" .
-		    (length $message ? ": $message" : "");
-	}
-
 	# Check to see if the page has been changed by someone else since
 	# rcs_prepedit was called.
 	my $cur    = git_sha1($file);
@@ -329,6 +320,14 @@ sub rcs_commit ($$$;$$) { #{{{
 		my $conflict = _merge_past($prev, $file, $dummy_commit_msg);
 		return $conflict if defined $conflict;
 	}
+	
+	# Set the commit author to the web committer.
+	my %env=%ENV;
+	if (defined $user || defined $ipaddr) {
+		$ENV{GIT_AUTHOR_NAME}=defined $user ? $user : $ipaddr;
+		$ENV{GIT_AUTHOR_EMAIL}="";
+		$message.="\n\nWeb-commit: true\n";
+	}
 
 	# git commit returns non-zero if file has not been really changed.
 	# so we should ignore its exit status (hence run_or_non).
@@ -338,7 +337,8 @@ sub rcs_commit ($$$;$$) { #{{{
 			run_or_cry('git', 'push', $config{gitorigin_branch});
 		}
 	}
-
+	
+	%ENV=%env;
 	return undef; # success
 } #}}}
 
@@ -368,7 +368,7 @@ sub rcs_recentchanges ($) { #{{{
 			$ci->{'author_epoch'}
 		);
 
-		my (@pages, @messages);
+		my @pages;
 		foreach my $detail (@{ $ci->{'details'} }) {
 			my $file = $detail->{'file'};
 
@@ -384,26 +384,34 @@ sub rcs_recentchanges ($) { #{{{
 			};
 		}
 
-		push @messages, { line => $_ } foreach grep {
-			! m/^ *(signed[ \-]off[ \-]by[ :]|acked[ \-]by[ :]|cc[ :])/i
-		}  @{$ci->{'comment'}};
-
-		my ($user, $type) = (q{}, "web");
+		my $web_commit=0;
+		my @messages;
+		my $pastblank=0;
+		foreach my $line (@{$ci->{'comment'}}) {
+			$pastblank=1 if $line eq '';
+			next if $pastblank && $line=~m/^ *(signed[ \-]off[ \-]by[ :]|acked[ \-]by[ :]|cc[ :])/i;
+			if ($pastblank && $line=~m/^ *web-commit: true$/i) {
+				$web_commit=1;
+				next;
+			}
+			push @messages, { line => $line };
+		}
 
-		if (defined $messages[0] &&
+		my $user;
+		# compatability code for old web commit messages
+		if (! $web_commit && defined $messages[0] &&
 		    $messages[0]->{line} =~ m/$config{web_commit_regexp}/) {
 			$user = defined $2 ? "$2" : "$3";
 			$messages[0]->{line} = $4;
 		}
 		else {
-			$type ="git";
 			$user = $ci->{'author_username'};
 		}
 
 		push @rets, {
 			rev        => $sha1,
 			user       => $user,
-			committype => $type,
+			committype => $web_commit ? "web" : "git",
 			when       => $when,
 			message    => [@messages],
 			pages      => [@pages],
diff --git a/debian/changelog b/debian/changelog
index ff907655e..16b352766 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -28,6 +28,9 @@ ikiwiki (2.54) UNRELEASED; urgency=low
     work. Markdown removes one level of escaping.
   * Add a postscan hook.
   * search: Use postscan hook, avoid updating index when previewing.
+  * git: Put web committer name/openid/address in the git author field.
+    The committer's email address is not used (because leaking email addresses
+    is not liked by many users). Closes: #451023
 
   [ Simon McVittie ]
   * meta, inline: Support guid options, to allow forcing a particular url or
diff --git a/doc/todo/git_attribution.mdwn b/doc/todo/git_attribution.mdwn
index 0d3f97fed..ef59c221f 100644
--- a/doc/todo/git_attribution.mdwn
+++ b/doc/todo/git_attribution.mdwn
@@ -5,3 +5,5 @@ the user or by the script?), it could also set `GIT_COMMITTER_NAME` and
 `GIT_COMMITTER_EMAIL` to the same values.  --[[JoshTriplett]]
 
 > See [[debbug 451023]] for a [[patch]] --[[Joey]]
+
+[[done]]
-- 
2.39.5