From f6bd81db15340bd1bfa69e98f377099036308b7b Mon Sep 17 00:00:00 2001
From: Joey Hess <joey@kodama.kitenet.net>
Date: Sat, 29 Mar 2008 21:02:47 -0400
Subject: [PATCH] Added a hardlink option in the setup file, useful if the
 source and dest are on the same filesystem and the wiki includes large media
 files, which would normally be copied, wasting time and space.

---
 IkiWiki.pm        | 33 +++++++++++++-------
 IkiWiki/Render.pm | 12 +++++++-
 debian/changelog  |  3 ++
 doc/ikiwiki.setup |  3 ++
 po/ikiwiki.pot    | 76 +++++++++++++++++++++++++----------------------
 5 files changed, 79 insertions(+), 48 deletions(-)

diff --git a/IkiWiki.pm b/IkiWiki.pm
index 684713821..d1b65cd51 100644
--- a/IkiWiki.pm
+++ b/IkiWiki.pm
@@ -87,6 +87,7 @@ sub defaultconfig () { #{{{
 	numbacklinks => 10,
 	account_creation_password => "",
 	prefix_directives => 0,
+	hardlink => 0,
 } #}}}
 
 sub checkconfig () { #{{{
@@ -323,12 +324,9 @@ sub readfile ($;$$) { #{{{
 	return $ret;
 } #}}}
 
-sub writefile ($$$;$$) { #{{{
-	my $file=shift; # can include subdirs
-	my $destdir=shift; # directory to put file in
-	my $content=shift;
-	my $binary=shift;
-	my $writer=shift;
+sub prep_writefile ($$) {
+	my $file=shift;
+	my $destdir=shift;
 	
 	my $test=$file;
 	while (length $test) {
@@ -337,12 +335,8 @@ sub writefile ($$$;$$) { #{{{
 		}
 		$test=dirname($test);
 	}
-	my $newfile="$destdir/$file.ikiwiki-new";
-	if (-l $newfile) {
-		error("cannot write to a symlink ($newfile)");
-	}
 
-	my $dir=dirname($newfile);
+	my $dir=dirname("$destdir/$file");
 	if (! -d $dir) {
 		my $d="";
 		foreach my $s (split(m!/+!, $dir)) {
@@ -353,6 +347,23 @@ sub writefile ($$$;$$) { #{{{
 		}
 	}
 
+	return 1;
+}
+
+sub writefile ($$$;$$) { #{{{
+	my $file=shift; # can include subdirs
+	my $destdir=shift; # directory to put file in
+	my $content=shift;
+	my $binary=shift;
+	my $writer=shift;
+	
+	prep_writefile($file, $destdir);
+	
+	my $newfile="$destdir/$file.ikiwiki-new";
+	if (-l $newfile) {
+		error("cannot write to a symlink ($newfile)");
+	}
+	
 	my $cleanup = sub { unlink($newfile) };
 	open (my $out, '>', $newfile) || error("failed to write $newfile: $!", $cleanup);
 	binmode($out) if ($binary);
diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm
index 302b18395..18324914b 100644
--- a/IkiWiki/Render.pm
+++ b/IkiWiki/Render.pm
@@ -211,9 +211,19 @@ sub render ($) { #{{{
 		writefile($output, $config{destdir}, genpage($page, $content));
 	}
 	else {
-		my $srcfd=readfile($srcfile, 1, 1);
 		delete $depends{$file};
 		will_render($file, $file, 1);
+		
+		if ($config{hardlink}) {
+			prep_writefile($file, $config{destdir});
+			unlink($config{destdir}."/".$file);
+			if (link($srcfile, $config{destdir}."/".$file)) {
+				return;
+			}
+			# if hardlink fails, fall back top copying
+		}
+		
+		my $srcfd=readfile($srcfile, 1, 1);
 		writefile($file, $config{destdir}, undef, 1, sub {
 			my $destfd=shift;
 			my $cleanup=shift;
diff --git a/debian/changelog b/debian/changelog
index a514c42d9..abb36d860 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -63,6 +63,9 @@ ikiwiki (2.41) UNRELEASED; urgency=low
     a special sentinal value.
   * inline: Allow the "feedshow" parameter to take values greater than the
     value for "show".
+  * Added a hardlink option in the setup file, useful if the source and
+    dest are on the same filesystem and the wiki includes large media files,
+    which would normally be copied, wasting time and space.
 
  -- martin f. krafft <madduck@debian.org>  Sun, 02 Mar 2008 17:46:38 +0100
 
diff --git a/doc/ikiwiki.setup b/doc/ikiwiki.setup
index 9468e7508..99c81cf04 100644
--- a/doc/ikiwiki.setup
+++ b/doc/ikiwiki.setup
@@ -129,6 +129,9 @@ use IkiWiki::Setup::Standard {
 	#recentchangesnum => 100,
 	# Use new '!'-prefixed preprocessor directive syntax
 	#prefix_directives => 0,
+	# Attempt to make hardlinks to source files instead of copying them.
+	# Useful if the wiki contains large media files.
+	#hardlink => 1,
 
 	# To add plugins, list them here.
 	#add_plugins => [qw{goodstuff search wikitext camelcase
diff --git a/po/ikiwiki.pot b/po/ikiwiki.pot
index 7ba12899a..a3f7cafcb 100644
--- a/po/ikiwiki.pot
+++ b/po/ikiwiki.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-03-12 15:42-0400\n"
+"POT-Creation-Date: 2008-03-29 21:01-0400\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -45,25 +45,25 @@ msgstr ""
 msgid "%s is not an editable page"
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:385 ../IkiWiki/Plugin/brokenlinks.pm:24
-#: ../IkiWiki/Plugin/inline.pm:237 ../IkiWiki/Plugin/opendiscussion.pm:17
+#: ../IkiWiki/CGI.pm:395 ../IkiWiki/Plugin/brokenlinks.pm:24
+#: ../IkiWiki/Plugin/inline.pm:265 ../IkiWiki/Plugin/opendiscussion.pm:17
 #: ../IkiWiki/Plugin/orphans.pm:28 ../IkiWiki/Render.pm:95
 #: ../IkiWiki/Render.pm:172
 msgid "discussion"
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:441
+#: ../IkiWiki/CGI.pm:451
 #, perl-format
 msgid "creating %s"
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:459 ../IkiWiki/CGI.pm:477 ../IkiWiki/CGI.pm:487
-#: ../IkiWiki/CGI.pm:521 ../IkiWiki/CGI.pm:566
+#: ../IkiWiki/CGI.pm:469 ../IkiWiki/CGI.pm:487 ../IkiWiki/CGI.pm:497
+#: ../IkiWiki/CGI.pm:531 ../IkiWiki/CGI.pm:576
 #, perl-format
 msgid "editing %s"
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:656
+#: ../IkiWiki/CGI.pm:666
 msgid "You are banned."
 msgstr ""
 
@@ -84,50 +84,50 @@ msgstr ""
 msgid "new"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:309
+#: ../IkiWiki/Plugin/aggregate.pm:307
 #, perl-format
 msgid "expiring %s (%s days old)"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:316
+#: ../IkiWiki/Plugin/aggregate.pm:314
 #, perl-format
 msgid "expiring %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:345
+#: ../IkiWiki/Plugin/aggregate.pm:341
 #, perl-format
 msgid "processed ok at %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:349
+#: ../IkiWiki/Plugin/aggregate.pm:345
 #, perl-format
 msgid "checking feed %s ..."
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:354
+#: ../IkiWiki/Plugin/aggregate.pm:350
 #, perl-format
 msgid "could not find feed at %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:369
+#: ../IkiWiki/Plugin/aggregate.pm:365
 msgid "feed not found"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:380
+#: ../IkiWiki/Plugin/aggregate.pm:376
 #, perl-format
 msgid "(invalid UTF-8 stripped from feed)"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:386
+#: ../IkiWiki/Plugin/aggregate.pm:382
 #, perl-format
 msgid "(feed entities escaped)"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:392
+#: ../IkiWiki/Plugin/aggregate.pm:388
 msgid "feed crashed XML::Feed!"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:466
+#: ../IkiWiki/Plugin/aggregate.pm:462
 #, perl-format
 msgid "creating new page %s"
 msgstr ""
@@ -200,29 +200,29 @@ msgstr ""
 msgid "failed to determine size of image %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/inline.pm:44
+#: ../IkiWiki/Plugin/inline.pm:46
 msgid "Must specify url to wiki with --url when using --rss or --atom"
 msgstr ""
 
-#: ../IkiWiki/Plugin/inline.pm:136
+#: ../IkiWiki/Plugin/inline.pm:153
 #, perl-format
 msgid "unknown sort type %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/inline.pm:196
+#: ../IkiWiki/Plugin/inline.pm:224
 msgid "Add a new post titled:"
 msgstr ""
 
-#: ../IkiWiki/Plugin/inline.pm:212
+#: ../IkiWiki/Plugin/inline.pm:240
 #, perl-format
 msgid "nonexistant template %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/inline.pm:245 ../IkiWiki/Render.pm:99
+#: ../IkiWiki/Plugin/inline.pm:273 ../IkiWiki/Render.pm:99
 msgid "Discussion"
 msgstr ""
 
-#: ../IkiWiki/Plugin/inline.pm:463
+#: ../IkiWiki/Plugin/inline.pm:491
 msgid "RPC::XML::Client not found, not pinging"
 msgstr ""
 
@@ -393,6 +393,10 @@ msgstr ""
 msgid "The page %s does not exist."
 msgstr ""
 
+#: ../IkiWiki/Plugin/recentchangesdiff.pm:26
+msgid "(Diff truncated)"
+msgstr ""
+
 #: ../IkiWiki/Plugin/search.pm:34
 #, perl-format
 msgid "Must specify %s when using the search plugin"
@@ -422,7 +426,7 @@ msgstr ""
 msgid "shortcut %s points to <i>%s</i>"
 msgstr ""
 
-#: ../IkiWiki/Plugin/smiley.pm:23
+#: ../IkiWiki/Plugin/smiley.pm:32
 msgid "failed to parse any smileys"
 msgstr ""
 
@@ -512,47 +516,47 @@ msgstr ""
 msgid "getctime not implemented"
 msgstr ""
 
-#: ../IkiWiki/Render.pm:279 ../IkiWiki/Render.pm:300
+#: ../IkiWiki/Render.pm:289 ../IkiWiki/Render.pm:310
 #, perl-format
 msgid "skipping bad filename %s"
 msgstr ""
 
-#: ../IkiWiki/Render.pm:355
+#: ../IkiWiki/Render.pm:365
 #, perl-format
 msgid "removing old page %s"
 msgstr ""
 
-#: ../IkiWiki/Render.pm:396
+#: ../IkiWiki/Render.pm:406
 #, perl-format
 msgid "scanning %s"
 msgstr ""
 
-#: ../IkiWiki/Render.pm:401
+#: ../IkiWiki/Render.pm:411
 #, perl-format
 msgid "rendering %s"
 msgstr ""
 
-#: ../IkiWiki/Render.pm:422
+#: ../IkiWiki/Render.pm:432
 #, perl-format
 msgid "rendering %s, which links to %s"
 msgstr ""
 
-#: ../IkiWiki/Render.pm:443
+#: ../IkiWiki/Render.pm:453
 #, perl-format
 msgid "rendering %s, which depends on %s"
 msgstr ""
 
-#: ../IkiWiki/Render.pm:482
+#: ../IkiWiki/Render.pm:492
 #, perl-format
 msgid "rendering %s, to update its backlinks"
 msgstr ""
 
-#: ../IkiWiki/Render.pm:494
+#: ../IkiWiki/Render.pm:504
 #, perl-format
 msgid "removing %s, no longer rendered by %s"
 msgstr ""
 
-#: ../IkiWiki/Render.pm:520
+#: ../IkiWiki/Render.pm:530
 #, perl-format
 msgid "ikiwiki: cannot render %s"
 msgstr ""
@@ -620,11 +624,11 @@ msgstr ""
 msgid "usage: --set var=value"
 msgstr ""
 
-#: ../IkiWiki.pm:115
+#: ../IkiWiki.pm:117
 msgid "Must specify url to wiki with --url when using --cgi"
 msgstr ""
 
-#: ../IkiWiki.pm:184 ../IkiWiki.pm:185
+#: ../IkiWiki.pm:186 ../IkiWiki.pm:187
 msgid "Error"
 msgstr ""
 
@@ -632,7 +636,7 @@ msgstr ""
 #. translators: preprocessor directive name,
 #. translators: the second a page name, the
 #. translators: third a number.
-#: ../IkiWiki.pm:735
+#: ../IkiWiki.pm:747
 #, perl-format
 msgid "%s preprocessing loop detected on %s at depth %i"
 msgstr ""
-- 
2.39.5