|
1 | | -#!/bin/bash |
| 1 | +#!/usr/bin/env bash |
2 | 2 |
|
3 | | -# Fetch all branches and prune remote-tracking branches that no longer exist |
4 | | -git fetch --all --prune |
| 3 | +set -euo pipefail |
| 4 | + |
| 5 | +if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then |
| 6 | + echo "Not inside a git repository." |
| 7 | + exit 1 |
| 8 | +fi |
| 9 | + |
| 10 | +base_branch="$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@')" |
| 11 | +if [[ -z "$base_branch" ]]; then |
| 12 | + if git show-ref --verify --quiet refs/heads/main; then |
| 13 | + base_branch="main" |
| 14 | + elif git show-ref --verify --quiet refs/heads/master; then |
| 15 | + base_branch="master" |
| 16 | + else |
| 17 | + echo "Could not determine default base branch (origin/HEAD, main, or master)." |
| 18 | + exit 1 |
| 19 | + fi |
| 20 | +fi |
5 | 21 |
|
6 | | -# Store the current branch |
7 | | -original_branch=$(git branch --show-current) |
| 22 | +current_branch="$(git branch --show-current)" |
8 | 23 |
|
9 | | -# Get a list of all local branches, excluding 'main' and branches that start with '_' |
10 | | -branches=$(git branch --format="%(refname:short)" | grep -v '^main$' | grep -v '^_') |
| 24 | +echo "Using base branch: $base_branch" |
| 25 | +git fetch --all --prune |
11 | 26 |
|
12 | | -if [ -z "$branches" ]; then |
13 | | - echo "No branches found for cleanup." |
| 27 | +branches="$({ |
| 28 | + git branch --format='%(refname:short)' \ |
| 29 | + | grep -v "^${base_branch}$" \ |
| 30 | + | grep -v '^_' \ |
| 31 | + | grep -v "^${current_branch}$" |
| 32 | +} || true)" |
| 33 | + |
| 34 | +if [[ -z "$branches" ]]; then |
| 35 | + echo "No local branches found for cleanup." |
14 | 36 | exit 0 |
15 | 37 | fi |
16 | 38 |
|
17 | | -# Iterate over each branch and check if it contains any commits not in 'main' |
18 | 39 | for branch in $branches; do |
19 | | - # Check if branch has any unique commits compared to 'main' |
20 | | - unique_commits=$(git rev-list --count $branch ^main) |
| 40 | + unique_commits="$(git rev-list --count "$branch" "^${base_branch}")" |
21 | 41 |
|
22 | | - if [ "$unique_commits" -eq 0 ]; then |
23 | | - # No unique commits, offer to delete |
24 | | - echo "Branch '$branch' is fully included in 'main' and can be deleted." |
25 | | - read -p "Do you want to delete branch '$branch'? (y/n): " choice |
26 | | - if [ "$choice" = "y" ]; then |
27 | | - git branch -d "$branch" |
| 42 | + if [[ "$unique_commits" -eq 0 ]]; then |
| 43 | + echo "Branch '$branch' is fully included in '$base_branch' and can be deleted." |
| 44 | + read -r -p "Delete branch '$branch'? (y/n): " choice |
| 45 | + if [[ "$choice" == "y" ]]; then |
| 46 | + git branch --delete "$branch" |
28 | 47 | echo "Deleted branch '$branch'." |
29 | 48 | else |
30 | 49 | echo "Skipped branch '$branch'." |
31 | 50 | fi |
32 | 51 | else |
33 | | - # Unique commits exist, show the diff as if 'main' was merged into the branch |
34 | | - echo "Branch '$branch' has $unique_commits unique commit(s) not in 'main'." |
35 | | - echo "Showing the diff between 'main' and '$branch' as if 'main' was merged into '$branch':" |
36 | | - |
37 | | - # Switch to the branch |
38 | | - git checkout "$branch" > /dev/null 2>&1 |
39 | | - |
40 | | - # Perform a merge without committing, to simulate the merge |
41 | | - git merge --no-commit --no-ff main |
42 | | - |
43 | | - # Show the colored diff for the merge result |
44 | | - git diff main --color |
45 | | - |
46 | | - # Abort the merge to return to the original branch state |
47 | | - git merge --abort |
48 | | - |
49 | | - # Switch back to the original branch |
50 | | - git checkout "$original_branch" > /dev/null 2>&1 |
51 | | - |
52 | | - # Offer to delete the branch after showing the diff |
53 | | - read -p "Do you want to delete branch '$branch' despite unique commits? (y/n): " choice |
| 52 | + echo "Branch '$branch' has $unique_commits unique commit(s) not in '$base_branch'." |
| 53 | + echo "Showing diff for '${base_branch}...${branch}':" |
| 54 | + git --no-pager diff --color=always "${base_branch}...${branch}" || true |
54 | 55 |
|
55 | | - if [ "$choice" = "y" ]; then |
56 | | - git branch -D "$branch" |
| 56 | + read -r -p "Delete branch '$branch' despite unique commits? (y/n): " choice |
| 57 | + if [[ "$choice" == "y" ]]; then |
| 58 | + git branch --delete --force "$branch" |
57 | 59 | echo "Deleted branch '$branch'." |
58 | 60 | else |
59 | 61 | echo "Skipped branch '$branch'." |
|
0 commit comments