summaryrefslogtreecommitdiffstats
path: root/bin/git-delete-branches.sh
blob: aa0ffd08b7f710b4b21927c1f763340995dd62fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#!/bin/sh

#############################
#    Configure as needed    #
#############################
# Set to 1 to remove merged branches from remotes
REMOVE_FROM_REMOTE=1

# If REMOVE_FROM_REMOTE was set to 1 above, set this to the remote
# where branches shall be removed
MANAGED_REMOTE="origin"

# These branches will never be removed
BRANCHES_TO_KEEP="master head devel experimental testing"

######################################################
#  Nothing below this point should need to be edited #
######################################################

generate() {
    # Take in space delimited string, output | delimited
    echo "$1" | sed 's/\s/|/g'
}

if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
    echo "${PWD} is not a Git tree. Exiting."
    exit 1
fi

CURRENT=$(git rev-parse --abbrev-ref HEAD)
if [ "$CURRENT" != 'master' ]; then
    echo "Switch to the master branch before running this script." >&2
    exit 1
fi

echo "Fetching remote(s)"
git fetch --prune "$MANAGED_REMOTE"

[ $REMOVE_FROM_REMOTE -eq 1 ] && \
   REMOTE_BR=$(git branch -r --merged | grep -v '\->' |\
    grep -vE "^\s+([^/]+)/($(generate "$BRANCHES_TO_KEEP"))$" |\
    grep -E "^\s+$MANAGED_REMOTE/")
LOCAL_BR=$(git branch --merged | grep -Ev "^\s+($(generate "$BRANCHES_TO_KEEP"))$")

if [ -z "$REMOTE_BR" ] && [ -z "$LOCAL_BR" ]; then
    echo "Woohoo! No unmerged branches!" >&2
else
    [ -n "$REMOTE_BR" ] && \
         echo "The following merged remote branches will be removed:" && \
         echo "$REMOTE_BR"

    [ -n "$LOCAL_BR" ] && \
         echo "The following merged local branches will be removed:" && \
         echo "$LOCAL_BR"
    echo -n "Remove branches? (Y/N): "
    read answer
    case $answer in
        y|Y|Yes|yes)
	    REFS=''
            for BRANCH in $REMOTE_BR; do
                echo -n "Remove branch '$BRANCH'? (Y/n): "
                read answer
                case "$answer" in
                    ''|y|Y|Yes|yes)
                        REFS="$REFS $(echo $BRANCH | sed 's/^[^/]\+\/\(.\+\)/:\1/')"
                        ;;
                esac
            done
	    echo "$REFS" | xargs -n30 git push "$MANAGED_REMOTE"
        if [ -n "$LOCAL_BR" ]; then
            git branch --merged | grep -Ev "^\s+($(generate "$BRANCHES_TO_KEEP"))$" | xargs -n30 git branch -d
            fi
            ;;
        *)
            echo "Aborting due to user request." >&2
            exit 0
    esac
fi