From df48e29fb785dd55ae71dd4032786a7c85bec876 Mon Sep 17 00:00:00 2001
From: Marty Oehme <contact@martyoeh.me>
Date: Tue, 11 Mar 2025 10:21:41 +0100
Subject: [PATCH] task: Fix git-backup output to be stable

By default sort the exported output by creation date and modify date.
Also use the jq expanded (prettified) output. Will take a little more
space, but ultimately makes it easier to see task changes since each
value is on a single line.
---
 .../share/task/hooks/on-exit.git-backup       | 24 ++++++++++++++-----
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/office/.local/share/task/hooks/on-exit.git-backup b/office/.local/share/task/hooks/on-exit.git-backup
index eb4d96b..e80cbe2 100755
--- a/office/.local/share/task/hooks/on-exit.git-backup
+++ b/office/.local/share/task/hooks/on-exit.git-backup
@@ -7,7 +7,7 @@
 # The minimum amount of time required between 2 commits in seconds.
 # So only if the last commit is at least x seconds old will a new one
 # be created. Set to 0 to sync each taskwarrior change.
-MINIMUM_WAIT_TIME=600
+MINIMUM_WAIT_TIME=60
 
 # Do not display status information.
 QUIET=true
@@ -16,8 +16,13 @@ QUIET=true
 # task directory clean.
 REMOVE_JSON=false
 
+# Sort with `jq` commandline program if it is found.
+# Also drops extra values 'urgency' and 'id' which are not
+# necessary for backups and automatically calculated by tw.
+STABLE_JSON=true
+
 if [ "${DISABLE_HOOKS}" = "true" ] || ! command -v git >/dev/null 2>&1; then
-    exit 0;
+    exit 0
 fi
 
 if [ "$1" != "api:2" ]; then
@@ -25,7 +30,6 @@ if [ "$1" != "api:2" ]; then
     exit 1
 fi
 
-
 data_dir="$(echo "$5" | cut -f2 -d:)"
 command_run="$(echo "$3" | cut -f2 -d:)"
 
@@ -37,7 +41,7 @@ if [ "$command_run" = "synchronize" ]; then
     git -C "$data_dir" push >/dev/null 2>&1
     push_ret="$?"
     if [ "$pull_ret" -eq 0 ] && [ "$push_ret" -eq 0 ]; then
-    [ $QUIET = "true" ] || echo "Git upstream synchronized."
+        [ $QUIET = "true" ] || echo "Git upstream synchronized."
     fi
 fi
 
@@ -50,7 +54,12 @@ if [ "$(date "+%s")" -lt $((last_commit + MINIMUM_WAIT_TIME)) ]; then
 fi
 
 # echo "EXPORTING TASKS"
-DISABLE_HOOKS=true env task export > "$data_dir/tasks.json"
+if [ "$STABLE_JSON" = true ] && command -v jq >/dev/null 2>&1; then
+    DISABLE_HOOKS=true env task export | jq -S 'map(del(.id, .urgency)) | sort_by(.entry, .modified) | reverse' >"$data_dir/tasks.json"
+else
+    DISABLE_HOOKS=true env task export >"$data_dir/tasks.json"
+fi
+
 # after any command, if there's changes add and commit
 if ! git -C "$data_dir" diff --exit-code >/dev/null 2>&1; then
     # echo "found changes"
@@ -62,4 +71,7 @@ if ! git -C "$data_dir" diff --exit-code >/dev/null 2>&1; then
     git -C "$data_dir" commit "$data_dir/tasks.json" -m "$header" -m "$msg" --no-gpg-sign >/dev/null 2>&1
     [ $QUIET = "true" ] || echo "Backup up to git."
 fi
-[ "$REMOVE_JSON" = true ] && rm "$data_dir/tasks.json" >/dev/null 2>&1
+
+if [ "$REMOVE_JSON" = true ] && [ -f "$data_dir/tasks.json" ]; then
+    rm "$data_dir/tasks.json" >/dev/null 2>&1
+fi