[notmuch] [PATCH] Handle message renames in mail spool
authorMikhail Gusarov <dottedmag@dottedmag.net>
Thu, 26 Nov 2009 20:23:45 +0000 (02:23 +0600)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:35:44 +0000 (09:35 -0800)
e3/74b7a09e6cdf28720e0db2519c5463e905c9e6 [new file with mode: 0644]

diff --git a/e3/74b7a09e6cdf28720e0db2519c5463e905c9e6 b/e3/74b7a09e6cdf28720e0db2519c5463e905c9e6
new file mode 100644 (file)
index 0000000..6383376
--- /dev/null
@@ -0,0 +1,214 @@
+Return-Path: <dottedmag@dottedmag.net>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+       by olra.theworths.org (Postfix) with ESMTP id 1FEFE431FBC\r
+       for <notmuch@notmuchmail.org>; Thu, 26 Nov 2009 12:23:51 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+       by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+       with ESMTP id yqSzF81pNVVO for <notmuch@notmuchmail.org>;\r
+       Thu, 26 Nov 2009 12:23:50 -0800 (PST)\r
+Received: from dottedmag.net (burger.dottedmag.net [212.75.37.82])\r
+       by olra.theworths.org (Postfix) with ESMTP id 922B7431FAE\r
+       for <notmuch@notmuchmail.org>; Thu, 26 Nov 2009 12:23:49 -0800 (PST)\r
+Received: from vertex.dottedmag (unknown [91.197.127.125])\r
+       by dottedmag.net (Postfix) with ESMTPSA id 2C6788C025\r
+       for <notmuch@notmuchmail.org>; Thu, 26 Nov 2009 21:23:48 +0100 (CET)\r
+Received: from dottedmag by vertex.dottedmag with local (Exim 4.69)\r
+       (envelope-from <dottedmag@dottedmag.net>) id 1NDksT-0007U0-55\r
+       for notmuch@notmuchmail.org; Fri, 27 Nov 2009 02:23:45 +0600\r
+From: Mikhail Gusarov <dottedmag@dottedmag.net>\r
+To: notmuch@notmuchmail.org\r
+Date: Fri, 27 Nov 2009 02:23:45 +0600\r
+Message-Id: <1259267025-28733-1-git-send-email-dottedmag@dottedmag.net>\r
+X-Mailer: git-send-email 1.6.3.3\r
+Subject: [notmuch] [PATCH] Handle message renames in mail spool\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.12\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+       <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Thu, 26 Nov 2009 20:23:51 -0000\r
+\r
+In order to handle message renames the following changes were deemed necessary:\r
+\r
+* Mtime check on individual files was disabled. As files may be moved around\r
+without changing their mtime, it's necessary to parse them even if they appear\r
+old in case old message was moved. mtime check on directories was kept as moving\r
+files changes mtime of directory.\r
+\r
+* If message being parsed is already found in database under different path,\r
+then this message is considered to be moved, path is updated in database and\r
+this file does not undergo further processing.\r
+\r
+Note that after applying this patch notmuch still does not handle copying files\r
+(which is harmless, database will point to the last copy of message found during\r
+'notmuch new') and deleting files (which is more serious, as dangling entries\r
+will show up in searches).\r
+\r
+Signed-off-by: Mikhail Gusarov <dottedmag@dottedmag.net>\r
+---\r
+ lib/database.cc |   32 +++++++++++++------\r
+ notmuch-new.c   |   92 ++++++++++++++++++++++++++----------------------------\r
+ 2 files changed, 66 insertions(+), 58 deletions(-)\r
+\r
+diff --git a/lib/database.cc b/lib/database.cc\r
+index 2c90019..257c0b8 100644\r
+--- a/lib/database.cc\r
++++ b/lib/database.cc\r
+@@ -990,19 +990,31 @@ notmuch_database_add_message (notmuch_database_t *notmuch,\r
+       if (private_status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) {\r
+           _notmuch_message_set_filename (message, filename);\r
+           _notmuch_message_add_term (message, "type", "mail");\r
+-      } else {\r
+-          ret = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID;\r
+-          goto DONE;\r
+-      }\r
\r
+-      ret = _notmuch_database_link_message (notmuch, message, message_file);\r
+-      if (ret)\r
+-          goto DONE;\r
++          ret = _notmuch_database_link_message (notmuch, message, message_file);\r
++          if (ret)\r
++              goto DONE;\r
\r
+-      date = notmuch_message_file_get_header (message_file, "date");\r
+-      _notmuch_message_set_date (message, date);\r
++          date = notmuch_message_file_get_header (message_file, "date");\r
++          _notmuch_message_set_date (message, date);\r
\r
+-      _notmuch_message_index_file (message, filename);\r
++          _notmuch_message_index_file (message, filename);\r
++      } else {\r
++          const char *old_filename = notmuch_message_get_filename (message);\r
++          if (strcmp (old_filename, filename) == 0) {\r
++              /* We have already seen it */\r
++              goto DONE;\r
++          } else {\r
++              if (access (old_filename, R_OK) == 0) {\r
++                  /* old_filename still exists, we've got a duplicate */\r
++                  ret = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID;\r
++                  goto DONE;\r
++              } else {\r
++                  /* Message file has been moved/renamed */\r
++                  _notmuch_message_set_filename (message, filename);\r
++              }\r
++          }\r
++      }\r
\r
+       _notmuch_message_sync (message);\r
+     } catch (const Xapian::Error &error) {\r
+diff --git a/notmuch-new.c b/notmuch-new.c\r
+index 0dd2784..d16679c 100644\r
+--- a/notmuch-new.c\r
++++ b/notmuch-new.c\r
+@@ -174,54 +174,50 @@ add_files_recursive (notmuch_database_t *notmuch,\r
+       }\r
\r
+       if (S_ISREG (st->st_mode)) {\r
+-          /* If the file hasn't been modified since the last\r
+-           * add_files, then we need not look at it. */\r
+-          if (path_dbtime == 0 || st->st_mtime > path_dbtime) {\r
+-              state->processed_files++;\r
+-\r
+-              status = notmuch_database_add_message (notmuch, next, &message);\r
+-              switch (status) {\r
+-                  /* success */\r
+-                  case NOTMUCH_STATUS_SUCCESS:\r
+-                      state->added_messages++;\r
+-                      tag_inbox_and_unread (message);\r
+-                      break;\r
+-                  /* Non-fatal issues (go on to next file) */\r
+-                  case NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID:\r
+-                      /* Stay silent on this one. */\r
+-                      break;\r
+-                  case NOTMUCH_STATUS_FILE_NOT_EMAIL:\r
+-                      fprintf (stderr, "Note: Ignoring non-mail file: %s\n",\r
+-                               next);\r
+-                      break;\r
+-                  /* Fatal issues. Don't process anymore. */\r
+-                  case NOTMUCH_STATUS_READONLY_DATABASE:\r
+-                  case NOTMUCH_STATUS_XAPIAN_EXCEPTION:\r
+-                  case NOTMUCH_STATUS_OUT_OF_MEMORY:\r
+-                      fprintf (stderr, "Error: %s. Halting processing.\n",\r
+-                               notmuch_status_to_string (status));\r
+-                      ret = status;\r
+-                      goto DONE;\r
+-                  default:\r
+-                  case NOTMUCH_STATUS_FILE_ERROR:\r
+-                  case NOTMUCH_STATUS_NULL_POINTER:\r
+-                  case NOTMUCH_STATUS_TAG_TOO_LONG:\r
+-                  case NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW:\r
+-                  case NOTMUCH_STATUS_LAST_STATUS:\r
+-                      INTERNAL_ERROR ("add_message returned unexpected value: %d",  status);\r
+-                      goto DONE;\r
+-              }\r
+-\r
+-              if (message) {\r
+-                  notmuch_message_destroy (message);\r
+-                  message = NULL;\r
+-              }\r
+-\r
+-              if (do_add_files_print_progress) {\r
+-                  do_add_files_print_progress = 0;\r
+-                  add_files_print_progress (state);\r
+-              }\r
+-          }\r
++            state->processed_files++;\r
++\r
++            status = notmuch_database_add_message (notmuch, next, &message);\r
++            switch (status) {\r
++                /* success */\r
++                case NOTMUCH_STATUS_SUCCESS:\r
++                    state->added_messages++;\r
++                    tag_inbox_and_unread (message);\r
++                    break;\r
++              /* Non-fatal issues (go on to next file) */\r
++                case NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID:\r
++                    /* Stay silent on this one. */\r
++                    break;\r
++                case NOTMUCH_STATUS_FILE_NOT_EMAIL:\r
++                    fprintf (stderr, "Note: Ignoring non-mail file: %s\n",\r
++                             next);\r
++                    break;\r
++              /* Fatal issues. Don't process anymore. */\r
++                case NOTMUCH_STATUS_READONLY_DATABASE:\r
++                case NOTMUCH_STATUS_XAPIAN_EXCEPTION:\r
++                case NOTMUCH_STATUS_OUT_OF_MEMORY:\r
++                    fprintf (stderr, "Error: %s. Halting processing.\n",\r
++                             notmuch_status_to_string (status));\r
++                    ret = status;\r
++                    goto DONE;\r
++                default:\r
++                case NOTMUCH_STATUS_FILE_ERROR:\r
++                case NOTMUCH_STATUS_NULL_POINTER:\r
++                case NOTMUCH_STATUS_TAG_TOO_LONG:\r
++                case NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW:\r
++                case NOTMUCH_STATUS_LAST_STATUS:\r
++                    INTERNAL_ERROR ("add_message returned unexpected value: %d",  status);\r
++                    goto DONE;\r
++            }\r
++\r
++            if (message) {\r
++                notmuch_message_destroy (message);\r
++                message = NULL;\r
++            }\r
++\r
++            if (do_add_files_print_progress) {\r
++                do_add_files_print_progress = 0;\r
++                add_files_print_progress (state);\r
++            }\r
+       } else if (S_ISDIR (st->st_mode)) {\r
+           status = add_files_recursive (notmuch, next, st, state);\r
+           if (status && ret == NOTMUCH_STATUS_SUCCESS)\r
+-- \r
+1.6.3.3\r
+\r