git-commit: make the actions more fine-grained
authorDenis Ovsienko <denis@ovsienko.info>
Thu, 3 Jan 2019 17:46:49 +0000 (17:46 +0000)
committerDenis Ovsienko <denis@ovsienko.info>
Thu, 3 Jan 2019 17:46:49 +0000 (17:46 +0000)
Introduce an optional -o ("only") option to request only a specific
step of the pull-commit-push workflow. This is useful for updating many
files in a batch -- any changes will still end up one commit per file,
but the workflow will be pull-commit-commit-...-commit-commit-push, which
will not multiply the delay accessing a slow git remote before and after
every attempted file.

Without the option the script will work same as before this change.

[skip ci]

gateways/git-commit

index dcb095b..7c4d7ba 100755 (executable)
@@ -11,6 +11,7 @@
 # (
 #   'u' => 'racktables_pseudo_user',
 #   'r' => '/path/to/repository',
+#   'o' => 'pull', # or 'commit' or 'push' or unset
 #   'f' => 'path/to/file/within/the/repository/file.txt',
 #   'm' => 'commit message text',
 #   'a' => 'Some Author <user@example.org>',
@@ -28,7 +29,11 @@ THISFILE=`basename "$0"`
 usage_and_exit()
 {
        cat >&2 <<ENDOFMESSAGE
-Usage: $THISFILE -u <u> -r <r> -f <f> [-m <m> -a <a>]
+Usage: $THISFILE -u <u> -r <r> -o pull
+   or: $THISFILE -u <u> -r <r> -o commit -f <f> [-m <m> -a <a>]
+   or: $THISFILE -u <u> -r <r> -o push
+   or: $THISFILE -u <u> -r <r> [-o full] -f <f> [-m <m> -a <a>]
+
   -u <username>    A pseudo-user to work as (this script will try to sudo
                      itself if the current user is not the same). The user
                      must be able to write to the repository filesystem and to
@@ -36,6 +41,13 @@ Usage: $THISFILE -u <u> -r <r> -f <f> [-m <m> -a <a>]
                      user interaction (i.e. the git remote must be on a local
                      filesystem or be configured to use SSH keys).
   -r <repodir>     An absolute path to an existing git repository.
+  -o pull          Only run git-pull(1).
+  -o commit        Only replace the file contents with stdin and run
+                     git-commit(1) if the contents has changed.
+  -o push          Only run git-push(1).
+  -o full          This is the default and is the same as running the three
+                     actions above one after another, except the push will be
+                     skipped if the commit was skipped.
   -f <filepath>    A relative path to a file within the repository (if the
                      file or the path do not exist, the missing component(s)
                      will be created automatically).
@@ -94,7 +106,7 @@ git_commit_or_exit()
        if ! git cat-file -e HEAD:"$FILEPATH" 2>/dev/null || ! git diff --quiet -- "$FILEPATH"; then
                git add -- "$FILEPATH"
                git commit --quiet --message="$COMMITMSG" ${AUTHOR:+--author="$AUTHOR"} -- "$FILEPATH"
-               git_push_or_exit
+               [ "$1" = "and_push" ] && git_push_or_exit
        fi
 }
 
@@ -110,7 +122,8 @@ git_commit_or_exit()
 # processing, but that would not look consistent. Hence this script uses
 # getopts and short options for all arguments.
 
-while getopts u:r:f:m:a: opt; do
+ONLYRUN=full
+while getopts u:r:o:f:m:a: opt; do
        case "$opt" in
        u)
                SUDOUSER="$OPTARG"
@@ -118,6 +131,9 @@ while getopts u:r:f:m:a: opt; do
        r)
                REPODIR="$OPTARG"
                ;;
+       o)
+               ONLYRUN="$OPTARG"
+               ;;
        f)
                FILEPATH="$OPTARG"
                ;;
@@ -141,9 +157,27 @@ assert_nonempty_option -u "$SUDOUSER"
 }
 
 assert_nonempty_option -r "$REPODIR"
-assert_nonempty_option -f "$FILEPATH"
 cd "$REPODIR"
-git_pull_or_exit
-git_commit_or_exit
+
+case "$ONLYRUN" in
+pull)
+       git_pull_or_exit
+       ;;
+commit)
+       assert_nonempty_option -f "$FILEPATH"
+       git_commit_or_exit
+       ;;
+push)
+       git_push_or_exit
+       ;;
+full)
+       assert_nonempty_option -f "$FILEPATH"
+       git_pull_or_exit
+       git_commit_or_exit and_push
+       ;;
+*)
+       usage_and_exit
+       ;;
+esac
 
 exit 0