Skip to content

Commit c23fb4e

Browse files
committedDec 14, 2016
git-branchkill : add a way to push branch deletion to remote repos (all known) - added some failsafes
1 parent 149a207 commit c23fb4e

File tree

1 file changed

+51
-19
lines changed

1 file changed

+51
-19
lines changed
 

‎git-branchkill

+51-19
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ LOCALKILL=-d
1010
REMOTEKILL=no
1111
REPODIRS=""
1212

13+
BASE_REPO=upstream
14+
BASE_BRANCH=master
15+
1316
# We do parse some outputs, so keep it single-language
1417
LANG=C
1518
LC_ALL=C
@@ -18,17 +21,21 @@ export LANG LC_ALL
1821
while [ $# -gt 0 ]; do
1922
case "$1" in
2023
-h|--help)
21-
echo "Usage: $0 [-n] [-D] [-DD] [-R 'repodir ...'] branchname(s)..."
24+
echo "Usage: $0 [-n] [-D] [-DD|-DDD] [-R 'repodir ...'] branchname(s)..."
2225
echo "Removes local branches and remote references to branches, so as to"
2326
echo "help clean up after a branch has been merged and is no longer used"
2427
echo " -n Read-only mode to see what might be done"
2528
echo " -D Allow destruction of un-merged local branches"
2629
echo " -DD Cause the remote repo(s) to forget named branch(es)"
27-
echo " -R 'dirs...' List one or more local repositories (directories)"
30+
echo " -DDD ONLY cause the remote repo(s) to forget named branch(es)"
31+
echo " (do not remove local branches and/or references)"
32+
echo " -R 'dirs...' List one or more local repositories (directories)"
2833
echo " to act upon; the parameter may be specified more than once,"
2934
echo " and its argument may be a space-separated list of directories"
3035
echo " (e.g. from a shell glob or Midnight Commander substitution);"
3136
echo " if no '-R ...' is specified, script works in current dir"
37+
echo " -BR 'repo' Change the untouchable base repo (default: ${BASE_REPO})"
38+
echo " -BB 'branch' Change the untouchable base branch (default: ${BASE_BRANCH})"
3239
echo " branch(es) List one or more branch name(s) to remove"
3340
return 0
3441
;;
@@ -44,6 +51,13 @@ while [ $# -gt 0 ]; do
4451
echo "Info: Pushing destruction of named branches to remotes!" >&2
4552
shift 1
4653
;;
54+
-DDD) REMOTEKILL=yes
55+
LOCALKILL=""
56+
echo "Info: ONLY pushing destruction of named branches to remotes!" >&2
57+
shift 1
58+
;;
59+
-BR) BASE_REPO="$2"; shift ;;
60+
-BB) BASE_BRANCH="$2"; shift ;;
4761
-R) if [ -n "$2" ] ; then
4862
for D in $2 ; do
4963
if [ -d "$D" ]; then
@@ -75,19 +89,25 @@ branchkill() {
7589
echo "=== `date`: Currently checked out branch is '$CURBRANCH'"
7690

7791
REMOTES="`git remote -v | egrep 'push' | awk '{print $1}'`" || REMOTES=""
78-
echo "=== `date`: Known remote repos are: `echo "$REMOTES" | tr '\n' ' '`"
92+
if [ -n "$REMOTES" ] ; then
93+
echo "=== `date`: Known remote repos are: `echo "$REMOTES" | tr '\n' ' '`"
94+
else
95+
echo "=== `date`: WARNING: No remote repos are known; will only process local branches"
96+
fi
7997

8098
RES=0
99+
[ -n "$LOCALKILL" ] && \
81100
for B in "$@" ; do
82101
echo ""
83102
echo "=== `date`: Processing a branch named '$B'"
84-
if [ "$B" = "$CURBRANCH" -o "$B" = master ] ; then
85-
echo "Error: can not remove master branch, or current branch: '$B'" \
103+
if [ "$B" = "$CURBRANCH" -o "$B" = "${BASE_BRANCH}" ] ; then
104+
echo "Error: can not remove master branch '${BASE_BRANCH}', or current branch: '$B'" \
86105
"(please change into some other)" >&2
87106
RES=2
88107
FAILED="$FAILED
89108
M($RES) `pwd` $B master branch, or current branch"
90109
else
110+
[ -n "$REMOTES" ] && \
91111
for R in $REMOTES ; do
92112
echo "Info: Removing local reference to remote branch: '$R/$B' ..."
93113
_OUT="`$EXEC git branch -dr "$R/$B" 2>&1`"
@@ -118,22 +138,34 @@ L($RES) `pwd` $B `echo ${_OUT} | tr '\n' ' '`"
118138
# Note that you may (try to) remove any branch on a remote server,
119139
# including your current one or a master one (not all git workflows
120140
# even use a "master" or assign a special meaning to it).
141+
[ -n "$REMOTES" ] && \
121142
if [ "$REMOTEKILL" = yes ]; then
122-
for R in $REMOTES ; do
123-
echo "Info: Removing the branch '$B' in remote repo '$R' ..."
124-
_OUT="`$EXEC git push "$R" ":$B" 2>&1`"
125-
_RES=$?
126-
if [ "$_RES" = 0 ] || \
127-
echo "$_OUT" | egrep " does not appear to be a git repository|remote ref does not exist|Please make sure you have the correct access rights" >/dev/null \
128-
; then
129-
echo "OK, now OTHER clones of this remote repo should 'git fetch --all --prune'"
130-
else
131-
RES=$_RES
132-
[ "$_RES" != 0 ] && FAILED="$FAILED
143+
if [ "$B" = "${BASE_BRANCH}" ] ; then
144+
echo "Error: can not remove master branch '${BASE_BRANCH}'" >&2
145+
RES=2
146+
FAILED="$FAILED
147+
P($RES) `pwd` $B master branch"
148+
else
149+
for R in $REMOTES ; do
150+
if [ "$R" = "${BASE_REPO}" ]; then
151+
echo "WARNING: Not removing branches in upstream repo: '$R/$B' ..." >&2
152+
continue
153+
fi
154+
echo "Info: Removing the branch '$B' in remote repo '$R' ..."
155+
_OUT="`$EXEC git push "$R" ":$B" 2>&1`"
156+
_RES=$?
157+
if [ "$_RES" = 0 ] || \
158+
echo "$_OUT" | egrep " does not appear to be a git repository|remote ref does not exist|Please make sure you have the correct access rights" >/dev/null \
159+
; then
160+
echo "OK, now OTHER clones of this remote repo should 'git fetch --all --prune'"
161+
else
162+
RES=$_RES
163+
[ "$_RES" != 0 ] && FAILED="$FAILED
133164
P($RES) `pwd` $B `echo ${_OUT} | tr '\n' ' '`"
134-
fi
135-
echo "$_OUT"
136-
done
165+
fi
166+
echo "$_OUT"
167+
done
168+
fi
137169
fi
138170
done
139171

0 commit comments

Comments
 (0)
Please sign in to comment.