## # systr_repo_check [=PATH] # # Assert that the local repository path exists and is valid. ## function systr_repo_check { if [ $# -gt 0 ]; then path="$1" fi if [ ! -f "$path/refs/HEAD" ]; then echo "Fatal: $path is not a repository" >&2 exit 1 fi } ## # systr_repo_resolve_reference # # Resolve a revision name to a commit ID. The result is printed to # stdout. ## function systr_repo_resolve_reference { if [ $# -lt 1 ]; then echo "Fatal: too few args to repo_resolve_reference" >&2 exit 1 fi ref="$1" if [[ "$ref" == "BASE" ]]; then cat .systr/BASE elif [[ "$ref" == "TRAC" ]]; then systr_repo_resolve_reference "$TRAC" elif [[ "$ref" == "NULL" ]]; then echo "NULL" else ( cd "$path" if [ -f "refs/$ref" ]; then cat "refs/$ref" elif [ -f "revs/$ref/.commit.systr" ]; then echo "$ref" else echo "$ref is not a revision" >&2 exit 1 fi ) fi } ## # systr_repo_commit_dist # # Determine how many commits have occurred between and . # IE: How far behind is ? If and are (or # reference) the same commit, the result it zero. Result # written to stdout. ## function systr_repo_commit_dist { if [ $# -lt 2 ]; then echo "Fatal: too few args to repo_commit_dist" >&2 exit 1 fi a=$(systr_repo_resolve_reference "$1") b=$(systr_repo_resolve_reference "$2") d=$((0)) while [[ "$b" != "NULL" ]] do if [[ "$b" == "$a" ]]; then echo "$d" exit fi d=$(($d+1)) read b <"$path/revs/$b/.commit.systr" done echo "Inf" } ## # systrunk shortlog [=BASE] # # View commit history. Generate list of commit IDs only, each # one a newline. Written to stdout. ## function systr_short_log { if [ $# -lt 1 ]; then commit="$BASE" else commit=$(systr_repo_resolve_reference "$1") fi while [[ "$commit" != "NULL" ]] do echo "$commit" read commit <"$path/revs/$commit/.commit.systr" done } ## # systr_repo_merge_base # # Find the merge base between and . That is, determine # which other commit is the closest common ancestor of both # and . Result or "NULL" written to stdout. ## function systr_repo_merge_base { if [ $# -lt 2 ]; then echo "Fatal: too few args to repo_merge_base" >&2 exit 1 fi a=$(systr_repo_resolve_reference "$1") b=$(systr_repo_resolve_reference "$2") while [[ "$a" != "NULL" ]] do check=$(systr_short_log "$b" | grep "$a") if [[ "$check" == "$a" ]]; then echo "$a" exit fi read a <"$path/revs/$a/.commit.systr" done } ## # systrunk log [=BASE] # # View commit history. Generate a dump of all commits reachable # from the given commit, or BASE if no argument is given. ## function systr_log { if [ $# -lt 1 ]; then commit="$BASE" else commit=$(systr_repo_resolve_reference "$1") fi while [[ "$commit" != "NULL" ]] do ( cd "$path/revs/$commit/" read date <.date.systr read author <.author.systr read email <.email.systr printf '%s %s\n' "$commit" "$date" printf '%s <%s>\n\n' "$author" "$email" cat .mesg.systr echo "" echo "" ) read commit <"$path/revs/$commit/.commit.systr" done } ## # systrunk init # # Initialize a repository called ".systr" in the current # directory. ## function systr_init { if [ $# -lt 1 ]; then echo "Fatal: too few args to init" >&2 exit 1 fi name="$1" mkdir "$name.systr" cd "$name.systr" mkdir refs revs echo "NULL" >refs/HEAD } ## # systrunk status [-d] # # View current information such as which branch your worktree is # TRACking, which commit it is BASEd on, and how far out-of-date # it is. Additionally, report whether a merge or update operation # is currently in-progress. If '-d' is given, status will be # accompanied by a shortdiff of pending, uncommitted changes. ## function systr_status { if [[ "$MERG" != "NULL" ]]; then mergcommit=$(systr_repo_resolve_reference "$MERG") if [[ "$MERG" == "TRAC" ]]; then echo "Update in progress, to $mergcommit" else echo "Merge in progress, from $MERG ($mergcommit)" fi echo "" fi traccommit=$(systr_repo_resolve_reference "$TRAC") if [[ "$TRAC" == "$traccommit" ]]; then echo "Not tracking any branch" else echo "Tracking $TRAC ($traccommit)" fi if [[ "$BASE" == "NULL" ]]; then echo "BASE unset" else echo "BASE at $BASE {$updated}" fi dist=$(systr_repo_commit_dist "$BASE" "$TRAC") if [[ "$TRAC" != "$traccommit" ]]; then if [[ "$dist" == "0" ]]; then echo "Up-to-date" else echo "Behind $dist commits" fi fi if [[ "$1" == "-d" ]]; then echo "" systrunk shortdiff && echo "No pending changes" fi }