My dotfiles. Period.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #!/bin/bash
  2. #
  3. # Slurp - add everything, slurp into a WIP commit and push
  4. #
  5. warn() {
  6. echo "$@" >&2
  7. }
  8. die() {
  9. warn "$@"
  10. exit 2
  11. }
  12. usage() {
  13. die "usage: git slurp [--force-slurp] [--force-push] [pathspec]..."
  14. }
  15. allowed_slurp() {
  16. #
  17. # Is slurp allowed in this repo?
  18. #
  19. test -f "$ok_file"
  20. }
  21. this_branch_upstream() {
  22. #
  23. # Print upstream of current bvranch
  24. #
  25. git branch -vv \
  26. | grep '^\*' \
  27. | cut -d \] -f1 \
  28. | cut -d \[ -f2 \
  29. | cut -d : -f1
  30. }
  31. allowed_push() {
  32. #
  33. # Is push allowed for the remote branch??
  34. #
  35. # If this branch is tracking a remote branch, and the remote
  36. # branch name is listed in .git-slurp-ok after PUSH, we are
  37. # allowed to push
  38. #
  39. # The remote tracking branch is parsed; example output is here:
  40. #
  41. # $ git branch -vv
  42. # main aaf02f0 [main/master: ahead 25] Some other commit
  43. # * master add0a03 [jdsumsion/master] Some commit
  44. #
  45. local tbranch
  46. test -n "$ok_file" || return 1
  47. tbranch=$(this_branch_upstream)
  48. test -n "$tbranch" || return 0
  49. grep -qxE "PUSH ([^ ]+ )?$tbranch" "$ok_file" 2>/dev/null
  50. }
  51. has_flag() {
  52. #
  53. # Has $ok_file have flag $1 for this branch?
  54. #
  55. local flag=$1
  56. local tbranch
  57. test -n "$ok_file" || return 1
  58. tbranch=$(this_branch_upstream)
  59. grep -xE "PUSH [^ ]+ $tbranch" "$ok_file" \
  60. | cut -d' ' -f2 \
  61. | grep -qwe "$flag"
  62. }
  63. git_relative() {
  64. #
  65. # Convert pathspec $1 to git-root-based pathspec
  66. #
  67. # Also try to clean up path a bit; i.e. remove double slashes
  68. # or unnecessary trailing dot.
  69. #
  70. local path="$1"
  71. test -n "$GIT_PREFIX" && path="$GIT_PREFIX/$path"
  72. local full=$(readlink -m "$path")
  73. test "$full" = "$git_root" && echo . && return
  74. printf %s "${full#$git_root/}"
  75. }
  76. slurp1() {
  77. #
  78. # Slurp pathspec $1
  79. #
  80. local rel_pathspec # relative to git root
  81. rel_pathspec=$(git_relative "$1")
  82. git add "$rel_pathspec" || die
  83. git commit -m "WIP slurp, $date: $rel_pathspec" || die
  84. }
  85. go_slurp() {
  86. #
  87. # Do the slurp for pathspecs $@
  88. #
  89. $force_slurp || allowed_slurp || die "you don't want this."
  90. local date=$(date -Isec)
  91. local pathspec
  92. for pathspec in "$@";
  93. do
  94. slurp1 "$pathspec"
  95. done
  96. }
  97. go_push() {
  98. #
  99. # Do the push (if allowed)
  100. #
  101. if $force_push || allowed_push;
  102. then
  103. if has_flag ci; then
  104. git push
  105. else
  106. git push -o ci.skip
  107. fi
  108. fi
  109. }
  110. main() {
  111. local git_root
  112. local ok_file
  113. local force_slurp=false
  114. local force_push=false
  115. local skip_ci=true
  116. while true; do case $1 in
  117. --force-slurp) force_slurp=true; shift ;;
  118. --force-push) force_push=true; shift ;;
  119. --skip-ci) skip_ci=true; shift ;;
  120. --) shift; break ;;
  121. -*) usage ;;
  122. *) break ;;
  123. esac done
  124. test -n "$1" || set -- .
  125. git_root="$(git rev-parse --show-toplevel)" || die
  126. ok_file="$git_root/.git-slurp-ok"
  127. go_slurp "$@"
  128. go_push
  129. }
  130. main "$@"