123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- #!/bin/bash
-
- #
- # Slurp - add everything, slurp into a WIP commit and push
- #
-
- warn() {
- echo "$@" >&2
- }
-
- die() {
- warn "$@"
- exit 2
- }
-
- usage() {
- die "usage: git slurp [--force-slurp] [--force-push] [pathspec]..."
- }
-
- allowed_slurp() {
- #
- # Is slurp allowed in this repo?
- #
- test -f "$ok_file"
- }
-
- this_branch_upstream() {
- #
- # Print upstream of current bvranch
- #
- git branch -vv \
- | grep '^\*' \
- | cut -d \] -f1 \
- | cut -d \[ -f2 \
- | cut -d : -f1
- }
-
- allowed_push() {
- #
- # Is push allowed for the remote branch??
- #
- # If this branch is tracking a remote branch, and the remote
- # branch name is listed in .git-slurp-ok after PUSH, we are
- # allowed to push
- #
- # The remote tracking branch is parsed; example output is here:
- #
- # $ git branch -vv
- # main aaf02f0 [main/master: ahead 25] Some other commit
- # * master add0a03 [jdsumsion/master] Some commit
- #
- local tbranch
- test -n "$ok_file" || return 1
- tbranch=$(this_branch_upstream)
- test -n "$tbranch" || return 0
- grep -qxE "PUSH ([^ ]+ )?$tbranch" "$ok_file" 2>/dev/null
- }
-
- has_flag() {
- #
- # Has $ok_file have flag $1 for this branch?
- #
- local flag=$1
- local tbranch
- test -n "$ok_file" || return 1
- tbranch=$(this_branch_upstream)
- grep -xE "PUSH [^ ]+ $tbranch" "$ok_file" \
- | cut -d' ' -f2 \
- | grep -qwe "$flag"
- }
-
- git_relative() {
- #
- # Convert pathspec $1 to git-root-based pathspec
- #
- # Also try to clean up path a bit; i.e. remove double slashes
- # or unnecessary trailing dot.
- #
- local path="$1"
- test -n "$GIT_PREFIX" && path="$GIT_PREFIX/$path"
- local full=$(readlink -m "$path")
- test "$full" = "$git_root" && echo . && return
- printf %s "${full#$git_root/}"
- }
-
- slurp1() {
- #
- # Slurp pathspec $1
- #
- local rel_pathspec # relative to git root
- rel_pathspec=$(git_relative "$1")
- git add "$rel_pathspec" || die
- git commit -m "WIP slurp, $date: $rel_pathspec" || die
- }
-
- go_slurp() {
- #
- # Do the slurp for pathspecs $@
- #
- $force_slurp || allowed_slurp || die "you don't want this."
- local date=$(date -Isec)
- local pathspec
- for pathspec in "$@";
- do
- slurp1 "$pathspec"
- done
- }
-
- go_push() {
- #
- # Do the push (if allowed)
- #
- if $force_push || allowed_push;
- then
- if has_flag ci; then
- git push
- else
- git push -o ci.skip
- fi
- fi
- }
-
- main() {
- local git_root
- local ok_file
- local force_slurp=false
- local force_push=false
- local skip_ci=true
- while true; do case $1 in
- --force-slurp) force_slurp=true; shift ;;
- --force-push) force_push=true; shift ;;
- --skip-ci) skip_ci=true; shift ;;
- --) shift; break ;;
- -*) usage ;;
- *) break ;;
- esac done
- test -n "$1" || set -- .
- git_root="$(git rev-parse --show-toplevel)" || die
- ok_file="$git_root/.git-slurp-ok"
- go_slurp "$@"
- go_push
- }
-
- main "$@"
|