Skip to content

Commit eb906ee

Browse files
fix(git): git pu more resilient
Rather than push all matching refs, only push refs matching a standard stack pattern `hjdivad/{task}/{stackPrId}`. This avoids pushing an unrelated stack in the same repo.
1 parent a660040 commit eb906ee

3 files changed

Lines changed: 74 additions & 4 deletions

File tree

bin/git-pu

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
# === Configuration ===
5+
# Change this to your username/prefix for forked usage
6+
BRANCH_PREFIX="hjdivad"
7+
8+
# === Parse arguments ===
9+
DRY_RUN=false
10+
while [[ $# -gt 0 ]]; do
11+
case "$1" in
12+
-n|--dry-run)
13+
DRY_RUN=true
14+
shift
15+
;;
16+
-h|--help)
17+
echo "Usage: git pu [-n|--dry-run]"
18+
echo ""
19+
echo "Push all branches matching '${BRANCH_PREFIX}/{name}/*' with --force-with-lease"
20+
echo ""
21+
echo "Options:"
22+
echo " -n, --dry-run Print the git push command without executing it"
23+
echo " -h, --help Show this help message"
24+
exit 0
25+
;;
26+
*)
27+
echo "Error: Unknown option '$1'" >&2
28+
echo "Usage: git pu [-n|--dry-run]" >&2
29+
exit 1
30+
;;
31+
esac
32+
done
33+
34+
# Get current branch
35+
current_branch=$(git branch --show-current)
36+
37+
if [[ -z "$current_branch" ]]; then
38+
echo "Error: Not on a branch (detached HEAD state)" >&2
39+
exit 1
40+
fi
41+
42+
# Check if branch matches {prefix}/{name}/*
43+
# Pattern: PREFIX/SOMETHING/SOMETHING_ELSE
44+
if [[ ! "$current_branch" =~ ^${BRANCH_PREFIX}/([^/]+)/.+ ]]; then
45+
echo "Error: Current branch '$current_branch' does not match pattern '${BRANCH_PREFIX}/{name}/*'" >&2
46+
echo "Expected format: ${BRANCH_PREFIX}/<name>/<feature>" >&2
47+
exit 1
48+
fi
49+
50+
# Extract the {name} portion
51+
name="${BASH_REMATCH[1]}"
52+
53+
# Find all local branches matching {prefix}/{name}/*
54+
branches=()
55+
while IFS= read -r branch; do
56+
branches+=("$branch")
57+
done < <(git for-each-ref --format='%(refname:short)' "refs/heads/${BRANCH_PREFIX}/${name}/*")
58+
59+
if [[ ${#branches[@]} -eq 0 ]]; then
60+
echo "Error: No branches found matching '${BRANCH_PREFIX}/${name}/*'" >&2
61+
exit 1
62+
fi
63+
64+
echo "Pushing ${#branches[@]} branch(es) matching '${BRANCH_PREFIX}/${name}/*':"
65+
printf ' - %s\n' "${branches[@]}"
66+
67+
if [[ "$DRY_RUN" == true ]]; then
68+
echo ""
69+
echo "[dry-run] Would execute:"
70+
echo " git push --force-with-lease origin ${branches[*]}"
71+
else
72+
git push --force-with-lease origin "${branches[@]}"
73+
fi

packages/git/config

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,6 @@
4646
# amend leave message alone
4747
cmm = commit --amend -CHEAD
4848

49-
# push all matching refs to origin, with-lease.
50-
# work on a branch with commits stacked to PRs, rebase with --update-refs and
51-
# then `git pu` to push the whole stack.
52-
pu = push --force-with-lease origin :
5349
# push one origin
5450
pf = push --force-with-lease origin @
5551

packages/zsh/path.zsh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ __ensure_first_path "$HOME/src/github/malleatus/shared_binutils/global/target/de
3939
__ensure_first_path "$HOME/src/github/hjdivad/dotfiles/packages/binutils/crates/global/target/debug"
4040
# org global added in $HOME/.zshrc.local
4141
__ensure_first_path "$HOME/.local/bin"
42+
__ensure_first_path "$HOME/src/github/hjdivad/dotfiles/bin"
4243

4344

4445
# this is not using the `# CMD:` system because it captures `$PATH` at the time

0 commit comments

Comments
 (0)