# vim: ft=sh: # Get path to worktree for git branch _gitbworktree() { git worktree list --porcelain | \ awk -v ref="refs/heads/$1" \ '/^worktree / { worktree = $2 }; /^branch / { if ($2 == ref) { print worktree }}' } # Automatic branch merger (merge branch, push it to server and remove branch) # Expects name of the branch as argument # It fails if it's not fast forward merge and if there is fixup! commit. gitbmerge() ( local branch="$1" set -e if ! git rev-parse --quiet --verify "$branch" >/dev/null; then echo "No such branch: $branch" >&2 return 1 fi local upstream upstream="$(git rev-parse "$branch@{u}")" || true if [ -n "$upstream" ] && [ "$upstream" != "$(git rev-parse "$branch")" ]; then echo "First push your changes to the server!" >&2 return 1 fi [ -z "$(git log --grep="^fixup\!" HEAD.."$branch")" ] || { echo "First squash fixups!" >&2 return 1 } [ -z "$(git log --grep="^Apply .* suggestion(s) to " HEAD.."$branch")" ] || { echo "First squash suggestions!" >&2 return 1 } [ "$(git rev-parse HEAD)" != "$(git rev-parse "$branch")" ] || { echo "Nothing to merge! 🤷" >&2 return 1 } local wt wt="$(_gitbworktree "$branch")" if [ -n "$wt" ]; then if [ -d "$wd/.git" ]; then echo "Branch is checked out in root repository!" return 1 fi rm -r "$wt" git worktree prune fi git merge --ff-only "$branch" \ && git push \ && git branch -d "$branch" \ && { if [ -n "$upstream" ]; then git push origin :"$branch"; fi; } ) # Checkout branch to new work tree gitbcheckout() { local nw nw="$(git rev-parse --show-toplevel)-$1" git worktree add "$nw" "$1" cd "$nw" git submodule update --no-fetch --init --recursive } alias gitbco='gitbcheckout' # Create new branch from HEAD gitbnew() { git branch "$1" HEAD gitbcheckout "$1" } # Git that uses SOCKS on my favorite port sgit() { ALL_PROXY=socks5h://localhost:8123 git "$@" }