aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorDavid Bremner <david@tethera.net>2026-01-25 07:56:38 +0900
committerDavid Bremner <david@tethera.net>2026-02-16 07:24:18 +0900
commitc4c0843d8fed39d4d7da6be493248f75d0c0d706 (patch)
treefccc1200f62566d47a358369be153fffc570545d /test
parentcfc4af0e2bdf8f82ad14342baa6578d4dd366cd9 (diff)
cli/git-remote: add export command
Two (sub)features are stubbed out in this initial implementation: deleting messages (as opposed to tags), and missing messages. There are two corresponding tests marked as broken in T860-git-remote.sh. A third test passes with the stub, which is maybe not ideal, but at least it acts as a regression test.
Diffstat (limited to 'test')
-rwxr-xr-xtest/T860-git-remote.sh170
-rw-r--r--test/make-export.py44
2 files changed, 214 insertions, 0 deletions
diff --git a/test/T860-git-remote.sh b/test/T860-git-remote.sh
index a516f05d..3a1c128a 100755
--- a/test/T860-git-remote.sh
+++ b/test/T860-git-remote.sh
@@ -35,6 +35,7 @@ export GIT_COMMITTER_EMAIL="notmuch@example.com"
export GIT_REMOTE_NM_DEBUG="s"
export GIT_REMOTE_NM_LOG=grn-log.txt
EXPECTED=$NOTMUCH_SRCDIR/test/git-remote.expected-output
+MAKE_EXPORT_PY=$NOTMUCH_SRCDIR/test/make-export.py
TAG_FILE="_notmuch_metadata/87/b1/4EFC743A.3060609@april.org/tags"
@@ -119,6 +120,16 @@ test_expect_equal_file EXPECTED repo/$TAG_FILE
restore_state
backup_state
+test_begin_subtest "push empty commit"
+git -C repo pull
+notmuch dump | sort > EXPECTED
+git -C repo pull
+git -C repo push
+notmuch dump | sort > OUTPUT
+test_expect_equal_file EXPECTED OUTPUT
+restore_state
+
+backup_state
test_begin_subtest "pull sees deletion"
notmuch tag -unread -- id:4EFC743A.3060609@april.org
git -C repo pull
@@ -128,4 +139,163 @@ EOF
test_expect_equal_file EXPECTED repo/$TAG_FILE
restore_state
+backup_state
+test_begin_subtest 'export runs'
+run_helper <<EOF | notmuch_sanitize_git > OUTPUT
+export
+blob
+mark :1
+data 10
+tag1
+tag2
+
+commit refs/heads/master
+mark :2
+author Notmuch Test Suite <notmuch@example.com> 1234 +0000
+committer Notmuch Test Suite <notmuch@example.com> 1234 +0000
+data 8
+ignored
+M 100644 :1 $TAG_FILE
+
+done
+
+EOF
+cat <<EOF > EXPECTED
+ok refs/heads/master
+
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+# this test depends on the previous one
+test_begin_subtest 'export modifies database'
+notmuch dump id:4EFC743A.3060609@april.org | tail -n 1 > OUTPUT
+cat <<EOF > EXPECTED
++tag1 +tag2 -- id:4EFC743A.3060609@april.org
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+restore_state
+
+backup_state
+test_begin_subtest 'restore via export'
+notmuch dump > BEFORE
+python3 $MAKE_EXPORT_PY > export.in
+notmuch tag +transient -- id:4EFC743A.3060609@april.org
+run_helper < export.in > OUTPUT
+notmuch dump id:4EFC743A.3060609@april.org | tail -n 1 > OUTPUT
+cat <<EOF > EXPECTED
++inbox +unread -- id:4EFC743A.3060609@april.org
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+restore_state
+
+backup_state
+test_begin_subtest "push updates database"
+cat<<EOF >repo/$TAG_FILE
+tag1
+tag2
+EOF
+git -C repo add $TAG_FILE
+git -C repo commit -m 'testing push'
+git -C repo push origin master
+notmuch dump id:4EFC743A.3060609@april.org | tail -n 1 > OUTPUT
+cat <<EOF > EXPECTED
++tag1 +tag2 -- id:4EFC743A.3060609@april.org
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+restore_state
+
+backup_state
+test_begin_subtest "adding tag via repo"
+cat<<EOF >repo/$TAG_FILE
+tag1
+tag2
+tag3
+EOF
+git -C repo add $TAG_FILE
+git -C repo commit -m 'testing push'
+git -C repo push origin master
+notmuch dump id:4EFC743A.3060609@april.org | tail -n 1 > OUTPUT
+cat <<EOF > EXPECTED
++tag1 +tag2 +tag3 -- id:4EFC743A.3060609@april.org
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+restore_state
+
+backup_state
+test_begin_subtest "non-prefixed file ignored on push"
+cat<<EOF >repo/dummy
+this is outside the notmuch metadata prefix
+EOF
+git -C repo add dummy
+git -C repo commit -m 'testing prefix'
+test_expect_code 0 "git -C repo push origin master"
+restore_state
+
+backup_state
+test_begin_subtest "non-prefixed file ignored on pull"
+cat<<EOF >repo/dummy
+this is outside the notmuch metadata prefix
+EOF
+cp repo/dummy EXPECTED
+git -C repo add dummy
+git -C repo commit -m 'testing prefix'
+git -C repo push origin master
+git -C repo pull origin master
+test_expect_equal_file EXPECTED repo/dummy
+restore_state
+
+backup_state
+test_begin_subtest "push of non-main ref ignored"
+notmuch dump > EXPECTED
+git -C repo switch -c chaos
+git -C repo rm -r _notmuch_metadata
+git -C repo commit -m "delete all the things"
+git -C repo push origin chaos:chaos
+notmuch dump > OUTPUT
+test_expect_equal_file EXPECTED OUTPUT
+restore_state
+
+backup_state
+test_begin_subtest "removing all tags via repo"
+cat<<EOF >repo/$TAG_FILE
+EOF
+git -C repo add $TAG_FILE
+git -C repo commit -m 'testing push'
+git -C repo push origin master
+notmuch dump id:4EFC743A.3060609@april.org | tail -n 1 > OUTPUT
+cat <<EOF > EXPECTED
+ -- id:4EFC743A.3060609@april.org
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+restore_state
+
+backup_state
+test_begin_subtest "removing message via repo"
+test_subtest_known_broken
+parent=$(dirname $TAG_FILE)
+# future proof this for when e.g. properties are stored
+git -C repo rm -r $parent
+git -C repo commit -m 'testing deletion'
+git -C repo push origin master
+notmuch dump id:4EFC743A.3060609@april.org | tail -n 1 > OUTPUT
+cat <<EOF > EXPECTED
+#notmuch-dump batch-tag:3 config,properties,tags
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+restore_state
+
+backup_state
+test_begin_subtest 'by default, missing messages are an error during export'
+test_subtest_known_broken
+sed s/4EFC743A.3060609@april.org/missing-message@example.com/ < export.in > missing.in
+test_expect_code 1 "run_helper < missing.in"
+restore_state
+
+backup_state
+test_begin_subtest 'when configured, missing messages are ignored'
+notmuch config set git.fail_on_missing false
+test_expect_code 0 "run_helper < missing.in"
+notmuch config set git.fail_on_missing true
+restore_state
+
test_done
diff --git a/test/make-export.py b/test/make-export.py
new file mode 100644
index 00000000..0e6a1141
--- /dev/null
+++ b/test/make-export.py
@@ -0,0 +1,44 @@
+# generate a test input for the 'export' subcommand of the
+# git-remote-notmuch helper
+
+from notmuch2 import Database
+from time import time
+from hashlib import sha1
+
+def hexencode(str):
+ output_charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-_@=.,"
+ out = ""
+ for char in str:
+ if not char in output_charset:
+ out+= f"%{ord(char):x}"
+ else:
+ out+= char
+ return out
+
+db = Database(config=Database.CONFIG.SEARCH)
+
+count=1
+print("export")
+mark={}
+
+for msg in db.messages(""):
+ mark[msg.messageid]=count
+ blob=""
+ for tag in msg.tags:
+ blob += f"{tag}\n"
+ print (f"blob\nmark :{count}");
+ print (f"data {len(blob)}\n{blob}")
+ count=count+1
+
+print (f"\ncommit refs/heads/master\nmark :{count+1}")
+ctime = int(time())
+print (f"author Notmuch Test Suite <notmuch@example.com> {ctime} +0000")
+print (f"committer Notmuch Test Suite <notmuch@example.com> {ctime} +0000")
+print (f"data 8\nignored")
+
+for msg in db.messages(""):
+ digest = sha1(msg.messageid.encode('utf8')).hexdigest()
+ filename = hexencode(msg.messageid)
+ print (f"M 100644 :{mark[msg.messageid]} _notmuch_metadata/{digest[0:2]}/{digest[2:4]}/{filename}/tags")
+
+print("\ndone\n")