X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/blobdiff_plain/441002e3e6b7f979eb4ef1d2525add2ea308ba6a..093ad8b890543d7fec8283fefeebaf1d23d27a09:/IkiWiki/Plugin/git.pm

diff --git a/IkiWiki/Plugin/git.pm b/IkiWiki/Plugin/git.pm
index 77c0678bc..bfca933fd 100644
--- a/IkiWiki/Plugin/git.pm
+++ b/IkiWiki/Plugin/git.pm
@@ -220,6 +220,21 @@ sub run_or_die ($@) { safe_git(\&error, undef, @_) }
 sub run_or_cry ($@) { safe_git(sub { warn @_ }, undef, @_) }
 sub run_or_non ($@) { safe_git(undef, undef, @_) }
 
+sub ensure_committer {
+	if (! length $ENV{GIT_AUTHOR_NAME} || ! length $ENV{GIT_COMMITTER_NAME}) {
+		my $name = join('', run_or_non("git", "config", "user.name"));
+		if (! length $name) {
+			run_or_die("git", "config", "user.name", "IkiWiki");
+		}
+	}
+
+	if (! length $ENV{GIT_AUTHOR_EMAIL} || ! length $ENV{GIT_COMMITTER_EMAIL}) {
+		my $email = join('', run_or_non("git", "config", "user.email"));
+		if (! length $email) {
+			run_or_die("git", "config", "user.email", "ikiwiki.info");
+		}
+	}
+}
 
 sub merge_past ($$$) {
 	# Unlike with Subversion, Git cannot make a 'svn merge -rN:M file'.
@@ -258,6 +273,8 @@ sub merge_past ($$$) {
 	my @undo;      # undo stack for cleanup in case of an error
 	my $conflict;  # file content with conflict markers
 
+	ensure_committer();
+
 	eval {
 		# Hide local changes from Git by renaming the modified file.
 		# Relative paths must be converted to absolute for renaming.
@@ -467,6 +484,11 @@ sub git_commit_info ($;$) {
 sub rcs_find_changes ($) {
 	my $oldrev=shift;
 
+	# Note that git log will sometimes show files being added that
+	# don't exist. Particularly, git merge -s ours can result in a
+	# merge commit where some files were not really added.
+	# This is why the code below verifies that the files really
+	# exist.
 	my @raw_lines = run_or_die('git', 'log',
 		'--pretty=raw', '--raw', '--abbrev=40', '--always', '-c',
 		'--no-renames', , '--reverse',
@@ -482,12 +504,16 @@ sub rcs_find_changes ($) {
 		foreach my $i (@{$ci->{details}}) {
 			my $file=$i->{file};
 			if ($i->{sha1_to} eq $nullsha) {
-				delete $changed{$file};
-				$deleted{$file}=1;
+				if (! -e "$config{srcdir}/$file") {
+					delete $changed{$file};
+					$deleted{$file}=1;
+				}
 			}
 			else {
-				delete $deleted{$file};
-				$changed{$file}=1;
+				if (-e "$config{srcdir}/$file") {
+					delete $deleted{$file};
+					$changed{$file}=1;
+				}
 			}
 		}
 	}
@@ -517,6 +543,8 @@ sub rcs_get_current_rev () {
 sub rcs_update () {
 	# Update working directory.
 
+	ensure_committer();
+
 	if (length $config{gitorigin_branch}) {
 		run_or_cry('git', 'pull', '--prune', $config{gitorigin_branch});
 	}
@@ -570,7 +598,7 @@ sub rcs_commit_helper (@) {
 			$u=$params{session}->remote_addr();
 		}
 		if (defined $u) {
-			$u=encode_utf8($u);
+			$u=encode_utf8(IkiWiki::cloak($u));
 			$ENV{GIT_AUTHOR_NAME}=$u;
 		}
 		if (defined $params{session}->param("nickname")) {
@@ -583,6 +611,8 @@ sub rcs_commit_helper (@) {
 		}
 	}
 
+	ensure_committer();
+
 	$params{message} = IkiWiki::possibly_foolish_untaint($params{message});
 	my @opts;
 	if ($params{message} !~ /\S/) {
@@ -609,7 +639,7 @@ sub rcs_commit_helper (@) {
 	# So we should ignore its exit status (hence run_or_non).
 	if (run_or_non('git', 'commit', '-m', $params{message}, '-q', @opts)) {
 		if (length $config{gitorigin_branch}) {
-			run_or_cry('git', 'push', $config{gitorigin_branch});
+			run_or_cry('git', 'push', $config{gitorigin_branch}, $config{gitmaster_branch});
 		}
 	}
 	
@@ -622,7 +652,9 @@ sub rcs_add ($) {
 
 	my ($file) = @_;
 
-	run_or_cry('git', 'add', $file);
+	ensure_committer();
+
+	run_or_cry('git', 'add', '--', $file);
 }
 
 sub rcs_remove ($) {
@@ -630,13 +662,17 @@ sub rcs_remove ($) {
 
 	my ($file) = @_;
 
-	run_or_cry('git', 'rm', '-f', $file);
+	ensure_committer();
+
+	run_or_cry('git', 'rm', '-f', '--', $file);
 }
 
 sub rcs_rename ($$) {
 	my ($src, $dest) = @_;
 
-	run_or_cry('git', 'mv', '-f', $src, $dest);
+	ensure_committer();
+
+	run_or_cry('git', 'mv', '-f', '--', $src, $dest);
 }
 
 sub rcs_recentchanges ($) {
@@ -660,7 +696,9 @@ sub rcs_recentchanges ($) {
 		my @pages;
 		foreach my $detail (@{ $ci->{'details'} }) {
 			my $file = $detail->{'file'};
-			my $efile = uri_escape_utf8($file);
+			my $efile = join('/',
+				map { uri_escape_utf8($_) } split('/', $file)
+			);
 
 			my $diffurl = defined $config{'diffurl'} ? $config{'diffurl'} : "";
 			$diffurl =~ s/\[\[file\]\]/$efile/go;
@@ -933,6 +971,8 @@ sub rcs_revert ($) {
 	my $rev = shift;
 	my ($sha1) = $rev =~ /^($sha1_pattern)$/; # untaint
 
+	ensure_committer();
+
 	if (run_or_non('git', 'revert', '--no-commit', $sha1)) {
 		return undef;
 	}