GNU/Linux
•
xterm-256color
•
bash
2 views
~/.local/bin/git-close-bubble
#!/usr/bin/env bash
# Close a merge bubble started with a "BEGIN ..." commit.
# Usage: git close-bubble <message> [BEGIN-commit]
# git close-bubble --dry-run [BEGIN-commit]
set -euo pipefail
DRY_RUN=0
if [ "${1:-}" = "--dry-run" ]; then
DRY_RUN=1
shift
fi
if [ "$DRY_RUN" -eq 0 ] && [ $# -lt 1 ]; then
echo "usage: git close-bubble <message> [BEGIN-commit]" >&2
echo " git close-bubble --dry-run [BEGIN-commit]" >&2
exit 1
fi
if [ "$DRY_RUN" -eq 1 ]; then
MSG=""
BEGIN_ARG="${1:-}"
else
MSG="$1"
BEGIN_ARG="${2:-}"
fi
B=$(git branch --show-current)
if [ -n "$BEGIN_ARG" ]; then
S=$(git rev-parse --verify "$BEGIN_ARG")
else
CLOSED=$(git log --merges --format='%P' | awk '{print $1}' | sort -u)
S=""
while IFS= read -r c; do
if ! printf '%s\n' "$CLOSED" | grep -qx "$c"; then
S="$c"; break
fi
done < <(git log --grep='^BEGIN ' --format='%H')
if [ -z "$S" ]; then
echo "error: no unclosed BEGIN commit found" >&2
exit 1
fi
fi
echo "Would close bubble starting at: $(git log -1 --format='%h %s' "$S")"
if [ "$DRY_RUN" -eq 1 ]; then
echo "(dry-run; no changes made)"
exit 0
fi
git checkout "$S"
git merge --no-ff "$B" -m "$MSG"
M=$(git rev-parse HEAD)
git checkout "$B"
git merge "$M"
echo "Done. Branch '$B' now points at $M. Inspect, then 'git push' when satisfied."