From 6af6c89df314cf2f9c9e053c04aa2bd492072ab1 Mon Sep 17 00:00:00 2001
From: Joey Hess <joey@gnu.kitenet.net>
Date: Wed, 30 Dec 2009 15:41:17 -0500
Subject: [PATCH] comments: Add a checksum to the name of comment pages, to
 avoid merge conflicts when comments are posted to two branches of a site.

---
 IkiWiki/Plugin/comments.pm                 | 32 ++++++++++++++++------
 debian/changelog                           |  3 ++
 doc/todo/conflict_free_comment_merges.mdwn |  9 ++++++
 3 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/IkiWiki/Plugin/comments.pm b/IkiWiki/Plugin/comments.pm
index 517e16f9f..6340fc2cb 100644
--- a/IkiWiki/Plugin/comments.pm
+++ b/IkiWiki/Plugin/comments.pm
@@ -377,8 +377,6 @@ sub editcomment ($$) {
 	IkiWiki::check_canedit($page, $cgi, $session);
 	$postcomment=0;
 
-	my $location=unique_comment_location($page, $config{srcdir});
-
 	my $content = "[[!comment format=$type\n";
 
 	# FIXME: handling of double quotes probably wrong?
@@ -410,8 +408,11 @@ sub editcomment ($$) {
 	my $subject = $form->field('subject');
 	if (defined $subject && length $subject) {
 		$subject =~ s/"/&quot;/g;
-		$content .= " subject=\"$subject\"\n";
 	}
+	else {
+		$subject = "comment ".(num_comments($page, $config{srcdir}) + 1);
+	}
+	$content .= " subject=\"$subject\"\n";
 
 	$content .= " date=\"" . decode_utf8(strftime('%Y-%m-%dT%H:%M:%SZ', gmtime)) . "\"\n";
 
@@ -421,6 +422,8 @@ sub editcomment ($$) {
 	$editcontent =~ s/"/\\"/g;
 	$content .= " content=\"\"\"\n$editcontent\n\"\"\"]]\n";
 
+	my $location=unique_comment_location($page, $content, $config{srcdir});
+
 	# This is essentially a simplified version of editpage:
 	# - the user does not control the page that's created, only the parent
 	# - it's always a create operation, never an edit
@@ -458,7 +461,7 @@ sub editcomment ($$) {
 
 		if (! $ok) {
 			my $penddir=$config{wikistatedir}."/comments_pending";
-			$location=unique_comment_location($page, $penddir);
+			$location=unique_comment_location($page, $content, $penddir);
 			writefile("$location._comment", $penddir, $content);
 			IkiWiki::printheader($session);
 			print IkiWiki::misctemplate(gettext(gettext("comment stored for moderation")),
@@ -554,7 +557,7 @@ sub commentmoderation ($$) {
 				if ($action eq 'Accept') {
 					my $content=eval { readfile($file) };
 					next if $@; # file vanished since form was displayed
-					my $dest=unique_comment_location($page, $config{srcdir})."._comment";
+					my $dest=unique_comment_location($page, $content, $config{srcdir})."._comment";
 					writefile($dest, $config{srcdir}, $content);
 					if ($config{rcs} and $config{comments_commit}) {
 						IkiWiki::rcs_add($dest);
@@ -813,15 +816,28 @@ sub pagetemplate (@) {
 	}
 }
 
-sub unique_comment_location ($) {
+sub num_comments ($$) {
 	my $page=shift;
 	my $dir=shift;
 
+	my @comments=glob("$dir/$page/$config{comments_pagename}*._comment");
+	return @comments;
+}
+
+sub unique_comment_location ($$$) {
+	my $page=shift;
+
+	eval q{use Digest::MD5 'md5_hex'};
+	error($@) if $@;
+	my $content_md5=md5_hex(shift);
+
+	my $dir=shift;
+
 	my $location;
-	my $i = 0;
+	my $i = num_comments($page, $dir);
 	do {
 		$i++;
-		$location = "$page/$config{comments_pagename}$i";
+		$location = "$page/$config{comments_pagename}${i}_${content_md5}";
 	} while (-e "$dir/$location._comment");
 
 	return $location;
diff --git a/debian/changelog b/debian/changelog
index ee6f9adfb..984351415 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -8,6 +8,9 @@ ikiwiki (3.20091219) UNRELEASED; urgency=low
     can be generated at any time using ikiwiki --dumpsetup so I do
     not see a reason to ship it. Closes: #562183
   * Use env hack in python scripts.
+  * comments: Add a checksum to the name of comment pages, to
+    avoid merge conflicts when comments are posted to two branches of a
+    site.
 
  -- Joey Hess <joeyh@debian.org>  Fri, 25 Dec 2009 14:31:22 -0500
 
diff --git a/doc/todo/conflict_free_comment_merges.mdwn b/doc/todo/conflict_free_comment_merges.mdwn
index e0e8acb34..2cef0ee8c 100644
--- a/doc/todo/conflict_free_comment_merges.mdwn
+++ b/doc/todo/conflict_free_comment_merges.mdwn
@@ -12,3 +12,12 @@ title is specified, to retain the current behavior of the default title
 being "comment N".
 
 What do you think [[smcv]]? --[[Joey]] 
+
+> I had to use md5sums, as sha1sum perl module may not be available and I
+> didn't want to drag it in. But I think that's ok; this doesn't need to be
+> cryptographically secure and even the chances of being able to
+> purposefully cause a md5 collision and thus an undesired merge conflict
+> are quite low since it modifies the input text and adds a date stamp to
+> it.
+>
+> Anyway, I think it's good, [[[done]] --[[Joey]] 
-- 
2.39.5