diff options
| author | David Bremner <david@tethera.net> | 2026-01-25 07:56:37 +0900 |
|---|---|---|
| committer | David Bremner <david@tethera.net> | 2026-02-16 07:24:18 +0900 |
| commit | cfc4af0e2bdf8f82ad14342baa6578d4dd366cd9 (patch) | |
| tree | b0bf98718b8ab5663d811bc0df6e3347b1db910f /git-remote-notmuch.c | |
| parent | fcc41c82c4596aef1598eb9ea52c4b0cb4bb3c53 (diff) | |
cli/git-remote: add import command
The output in default.import is based on a modified version
of Felipe's git-remote-nm with Blake2 hashing replaced by SHA1
(for portability). This enable fetch/pull/clone, so test that as well.
Diffstat (limited to 'git-remote-notmuch.c')
| -rw-r--r-- | git-remote-notmuch.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/git-remote-notmuch.c b/git-remote-notmuch.c index fb5cfd55..bfd045a8 100644 --- a/git-remote-notmuch.c +++ b/git-remote-notmuch.c @@ -157,6 +157,30 @@ read_lastmod (const char *dir, char **uuid_out, unsigned long *counter_out) } static void +store_lastmod (notmuch_database_t *notmuch, const char *dir) +{ + char *filename = NULL; + FILE *out; + unsigned long lastmod; + const char *uuid; + + ASSERT (filename = talloc_asprintf (notmuch, "%s/lastmod", dir)); + + out = fopen (filename, "w"); + ensure (out, "error opening %s for writing: %s", filename, strerror (errno)); + + lastmod = notmuch_database_get_revision (notmuch, &uuid); + ASSERT (fprintf (out, "%s\t%zu\n", uuid, lastmod) > 0); +} + +static void +write_data (const char *data) +{ + printf ("data %zu\n", strlen (data)); + fputs (data, stdout); +} + +static void cmd_capabilities () { fputs ("import\nexport\nrefspec refs/heads/*:refs/notmuch/*\n\n", stdout); @@ -175,6 +199,91 @@ cmd_list (notmuch_database_t *db, const char *uuid, unsigned long lastmod) equal_lastmod (uuid, lastmod, db_uuid, db_lastmod) ? " unchanged" : ""); } +static void +cmd_import (notmuch_database_t *notmuch, + const char *nm_dir, + const char *uuid, + unsigned long lastmod) +{ + const char *ident = NULL; + const char *lastmod_str = NULL; + notmuch_messages_t *messages; + notmuch_status_t status; + notmuch_query_t *query; + char *mid_buf = NULL; + size_t mid_buf_len = 0; + + ident = talloc_asprintf (notmuch, "%s <%s> %zu +0000", + notmuch_config_get (notmuch, NOTMUCH_CONFIG_USER_NAME), + notmuch_config_get (notmuch, NOTMUCH_CONFIG_PRIMARY_EMAIL), + time (NULL)); + + + printf ("feature done\ncommit refs/notmuch/master\nmark :1\ncommitter %s\n", ident); + + ASSERT (lastmod_str = talloc_asprintf (notmuch, "lastmod: %zu\n", lastmod)); + write_data (lastmod_str); + if (uuid) + puts ("from refs/notmuch/master^0"); + + /* don't send deleteall here, as there may be other files in the + * repo outside the database prefix */ + + status = notmuch_query_create_with_syntax (notmuch, + "", + NOTMUCH_QUERY_SYNTAX_XAPIAN, + &query); + + if (print_status_database ("git-remote-nm", notmuch, status)) + exit (EXIT_FAILURE); + + if (debug_flags && strchr (debug_flags, 's')) + notmuch_query_set_sort (query, NOTMUCH_SORT_NEWEST_FIRST); + else + notmuch_query_set_sort (query, NOTMUCH_SORT_UNSORTED); + + status = notmuch_query_search_messages (query, &messages); + if (print_status_query ("git-remote-nm", query, status)) + exit (EXIT_FAILURE); + + for (; + notmuch_messages_valid (messages); + notmuch_messages_move_to_next (messages)) { + const char *tag_buf = ""; + const char *mid; + const char *hash; + const char *prefix = notmuch_config_get (notmuch, NOTMUCH_CONFIG_GIT_METADATA_PREFIX); + int ret; + + notmuch_message_t *message = notmuch_messages_get (messages); + mid = notmuch_message_get_message_id (message); + + ret = hex_encode (notmuch, mid, &mid_buf, &mid_buf_len); + ensure (ret == HEX_SUCCESS, "failed to hex-encode message-id %s\n", mid); + + /* we can't use _notmuch_sha1_from_string because we don't want + * to include the null terminator */ + g_autoptr (GChecksum) sha1 = NULL; + sha1 = g_checksum_new (G_CHECKSUM_SHA1); + g_checksum_update (sha1, (const guchar *) mid, strlen (mid)); + hash = g_checksum_get_string (sha1); + printf ("M 644 inline %s/%2.2s/%2.2s/%s/tags\n", prefix, hash, hash + 2, mid_buf); + + for (notmuch_tags_t *tags = notmuch_message_get_tags (message); + notmuch_tags_valid (tags); + notmuch_tags_move_to_next (tags)) { + const char *tag_str = notmuch_tags_get (tags); + ASSERT (tag_buf = talloc_asprintf (message, "%s%s\n", tag_buf, tag_str)); + } + write_data (tag_buf); + notmuch_message_destroy (message); + } + puts (""); + puts ("done"); + fflush (stdout); + store_lastmod (notmuch, nm_dir); +} + /* stubs since we cannot link with notmuch.o */ const notmuch_opt_desc_t notmuch_shared_options[] = { { } @@ -303,6 +412,8 @@ main (int argc, char *argv[]) if (STRNCMP_LITERAL (s, "capabilities") == 0) cmd_capabilities (); + else if (STRNCMP_LITERAL (s, "import") == 0) + cmd_import (db, nm_dir, uuid, lastmod); else if (STRNCMP_LITERAL (s, "list") == 0) cmd_list (db, uuid, lastmod); |
