mirror of
https://github.com/simonmichael/hledger.git
synced 2024-12-26 20:02:27 +03:00
118 lines
3.1 KiB
Bash
Executable File
118 lines
3.1 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 [-h|--help] - show this help
|
|
hledger git record [MSG] - record changes to journal's files (as listed by 'files')
|
|
hledger git status - show unrecorded changes in journal's files (after first record)
|
|
hledger git log - list recorded changes in journal's files (after first record)
|
|
hledger git GITARGS - run another git command in this repo, on all files
|
|
|
|
The shorter r, s, l command aliases may be used instead.
|
|
Extra/unrecognised arguments are passed to git. Git-specific flags should be preceded by --.
|
|
|
|
You can install this as more convenient top-level commands by creating
|
|
hledger-record, hledger-status, hledger-log scripts like:
|
|
|
|
#!/bin/sh
|
|
hledger-git record "\$@"
|
|
|
|
Examples:
|
|
|
|
$ hledger git s # briefly show status of journal's files
|
|
$ hledger git l -10 # briefly list last 10 commits to journal's files
|
|
$ hledger git l -- --stat # list commits to journal's files, with summaries
|
|
$ hledger git r 'txns' -- -n # commit changes, ignoring any pre-commit hooks
|
|
|
|
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"; done || echo "(ignored)" >&2
|
|
MSG=${1:-$(date +'%Y-%m-%d %H:%M:%S %Z')}
|
|
if [ $# -ge 1 ]; then
|
|
shift
|
|
fi
|
|
$GIT commit -m "$MSG" "$@" || (echo "error: commit failed" >&2; $GIT reset -q)
|
|
}
|
|
r() { record "$@"; }
|
|
|
|
status() {
|
|
ensure_git
|
|
# short status
|
|
$GIT --work-tree "$DIR" status -sb "$@" -- $FILES
|
|
echo
|
|
# diff
|
|
$GIT --work-tree "$DIR" diff "$@" -- $FILES
|
|
}
|
|
s() { status "$@"; }
|
|
|
|
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 "$@"
|
|
}
|
|
l() { log "$@"; }
|
|
|
|
# * Main
|
|
|
|
# NOTE intended to run Commands but will run any function above
|
|
if [[ "$1" == "-h" || "$1" == "--help" || $# == 0 ]]; then usage
|
|
elif declare -f "$1" > /dev/null; then "$@"
|
|
else
|
|
ensure_git
|
|
$GIT "$@"
|
|
fi
|