hledger/bin/hledger-git
2022-04-20 23:23:36 -10:00

99 lines
2.4 KiB
Bash
Executable File

#!/usr/bin/env bash
set -e
# * About
usage() { line80; cat <<EOF # keep synced with Commands below
hledger-git - easyish version control for your hledger journal, using git.
An experimental prototype, currently works for the default journal only.
A git repo in the main file's directory will be autocreated if needed.
Subcommands:
hledger git record [MSG] - record the journal's files (as listed by 'files')
hledger git status - show unrecorded changes (after first record)
hledger git log - list the journal's change history (after record)
hledger git - show this help
Extra arguments are passed to git (git-specific flags should be preceded by --).
You can install these as more convenient top-level commands by creating
hledger-record, hledger-status, hledger-log scripts like:
#!/bin/sh
hledger-git record "\$@"
Examples:
hledger git status
hledger git log -10
hledger git log -- -10 --stat
EOF
}
# * Utils
line80() { cat <<EOF
--------------------------------------------------------------------------------
EOF
}
no_repo_msg() {
echo "Try this again after 'record'."
}
MAINFILE=$LEDGER_FILE
FILES=$(hledger -f "$MAINFILE" files)
DIR=$(dirname "$MAINFILE")
# executable name, just one word
GIT=git
ensure_git() {
if ! hash $GIT 2>/dev/null; then
cat >&2 <<EOF
This command requires '$GIT', but it's not installed in \$PATH.
Please install it (see https://git.org/downloads) and try again.
EOF
exit 1
fi
}
# TODO: also look in parent directories
ensure_git_repo() {
if [[ ! -d "$DIR/.git" ]]; then
$GIT init "$DIR"
echo "Created git repo in $DIR"
fi
}
# * Commands
# keep synced with usage() above
record() {
ensure_git
ensure_git_repo
cd "$DIR"
for F in $FILES; do $GIT add -f "$F"; done
MSG=${1:-$(date +'%Y-%m-%d %H:%M:%S %Z')}; shift
$GIT record -m "$MSG" "$@" -- "$FILES"
}
status() {
ensure_git
$GIT --work-tree "$DIR" status -sb "$@" -- "$FILES"
}
log() {
ensure_git
# ensure_git_repo
# $GIT --work-tree "$DIR" log --format='%C(yellow)%ad %Cred%h%Creset %s%C(bold blue)%d%Creset' --date=short -1000000 "$@"
cd "$DIR"
# TODO: limit to hledger files
$GIT log --format='%ad %h %s' --date=short "$@"
}
# * Main
# NOTE intended to run Commands but will run any function above
if declare -f "$1" > /dev/null; then "$@"; else usage; fi