From ad9e443f22a139c71f0cd05885cda3e418f27567 Mon Sep 17 00:00:00 2001
From: Joey Hess <joey@kodama.kitenet.net>
Date: Thu, 23 Oct 2008 16:56:40 -0400
Subject: [PATCH] check_canattach hooked up

---
 IkiWiki/Plugin/git.pm  | 33 ++++++++++++++++++++++++++-------
 IkiWiki/Receive.pm     |  9 ++++-----
 doc/plugins/write.mdwn |  5 ++++-
 3 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/IkiWiki/Plugin/git.pm b/IkiWiki/Plugin/git.pm
index 234e7af2e..bdac6f7a1 100644
--- a/IkiWiki/Plugin/git.pm
+++ b/IkiWiki/Plugin/git.pm
@@ -9,6 +9,7 @@ use open qw{:utf8 :std};
 
 my $sha1_pattern     = qr/[0-9a-fA-F]{40}/; # pattern to validate Git sha1sums
 my $dummy_commit_msg = 'dummy commit';      # message to skip in recent changes
+my $no_chdir=0;
 
 sub import { #{{{
 	hook(type => "checkconfig", id => "git", call => \&checkconfig);
@@ -127,8 +128,10 @@ sub safe_git (&@) { #{{{
 	if (!$pid) {
 		# In child.
 		# Git commands want to be in wc.
-		chdir $config{srcdir}
-		    or error("Cannot chdir to $config{srcdir}: $!");
+		if (! $no_chdir) {
+			chdir $config{srcdir}
+			    or error("Cannot chdir to $config{srcdir}: $!");
+		}
 		exec @cmdline or error("Cannot exec '@cmdline': $!");
 	}
 	# In parent.
@@ -606,13 +609,20 @@ sub rcs_receive () { #{{{
 	while (<>) {
 		chomp;
 		my ($oldrev, $newrev, $refname) = split(' ', $_, 3);
-
+		
 		# only allow changes to gitmaster_branch
 		if ($refname !~ /^refs\/heads\/\Q$config{gitmaster_branch}\E$/) {
 			error sprintf(gettext("you are not allowed to change %s"), $refname);
 		}
-
-		foreach my $ci (git_commit_info($oldrev."..".$newrev)) {
+		
+		# Avoid chdir when running git here, because the changes
+		# are in the master git repo, not the srcdir repo.
+		# The pre-recieve hook already puts us in the right place.
+		$no_chdir=1;
+		my @changes=git_commit_info($oldrev."..".$newrev);
+		$no_chdir=0;
+
+		foreach my $ci (@changes) {
 			foreach my $detail (@{ $ci->{'details'} }) {
 				my $file = $detail->{'file'};
 
@@ -623,8 +633,7 @@ sub rcs_receive () { #{{{
 					error sprintf(gettext("you are not allowed to change %s"), $file);
 				}
 
-				my $action;
-				my $mode;			
+				my ($action, $mode, $path);
 				if ($detail->{'status'} =~ /^[M]+\d*$/) {
 					$action="change";
 					$mode=$detail->{'mode_to'};
@@ -632,6 +641,15 @@ sub rcs_receive () { #{{{
 				elsif ($detail->{'status'} =~ /^[AM]+\d*$/) {
 					$action="add";
 					$mode=$detail->{'mode_to'};
+					if (! pagetype($file)) {
+						eval q{use File::Temp};
+						die $@ if $@;
+						my $fh;
+						($fh, $path)=tempfile("XXXXXXXXXX", UNLINK => 1);
+						if (system("git show ".$detail->{sha1_to}." > '$path'") != 0) {
+							error("failed writing temp file");
+						}
+					}
 				}
 				elsif ($detail->{'status'} =~ /^[DAM]+\d*/) {
 					$action="remove";
@@ -654,6 +672,7 @@ sub rcs_receive () { #{{{
 				push @rets, {
 					file => $file,
 					action => $action,
+					path => $path,
 				};
 			}
 		}
diff --git a/IkiWiki/Receive.pm b/IkiWiki/Receive.pm
index 63944bb81..4d437cf78 100644
--- a/IkiWiki/Receive.pm
+++ b/IkiWiki/Receive.pm
@@ -66,11 +66,10 @@ sub test () { #{{{
 				}
 			}
 			else {
-				# TODO
-				#if (IkiWiki::Plugin::attachment->can("check_canattach") &&
-				#    IkiWiki::Plugin::attachment::check_canattach($session, $file, $path)) {
-				#    	next;
-				#}
+				if (IkiWiki::Plugin::attachment->can("check_canattach") &&
+				    IkiWiki::Plugin::attachment::check_canattach($session, $file, $change->{path})) {
+				    	next;
+				}
 			}
 		}
 		elsif ($change->{action} eq 'remove') {
diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn
index 9f096e4f7..7fbe4bd57 100644
--- a/doc/plugins/write.mdwn
+++ b/doc/plugins/write.mdwn
@@ -829,13 +829,16 @@ sense to implement for all RCSs.
 
 It should examine the incoming changes, and do any sanity 
 checks that are appropriate for the RCS to limit changes to safe file adds,
-removes, and renames. If something bad is found, it should exit
+removes, and changes. If something bad is found, it should exit
 nonzero, to abort the push. Otherwise, it should return a list of
 files that were changed, in the form:
 
 	{
 		file => # name of file that was changed
 		action => # either "add", "change", or "remove"
+		path => # temp file containing the new file content, only
+			# needed for "add", and only if the file is an
+			# attachment, not a page
 	}
 
 The list will then be checked to make sure that each change is one that
-- 
2.26.2