Streamline Your Git Workflow with a Cleanup Script

Will AshworthWill Ashworth
5 min read

In the fast-paced world of software development, efficiency and organization are key. That's why I'm excited to share a tool I've developed that promises to streamline one of the more tedious aspects of managing a git repository: branch cleanup. Designed with simplicity and effectiveness in mind, this Zsh script is a game-changer for developers looking to maintain a clean and efficient repository.

Introducing the Git Cleanup Script

Crafted for the Zsh shell, this script automates the process of removing local and remote branches that have been merged into your mainline branch, be it master or main. By doing so, it ensures your repository remains uncluttered, making it easier for you and your team to navigate and manage your projects.

Key Features:

  • Automated Cleanup: The script identifies and removes branches fully merged into master or main, plus any specified production branch, streamlining your repository maintenance.

  • Safe to Use: It safeguards against the deletion of critical branches such as main, master, and other protected branches, ensuring only the intended branches are pruned.

  • User Confirmation: Before executing deletions, it seeks your confirmation, providing a layer of security and control over the cleanup process.

Installation Guide

To integrate this script into your workflow, simply add it to your Zsh custom directory. Here's how:

  1. Download the Script: First, ensure you have the script saved on your system. You can copy it directly from this article or from the repository where it's hosted.

  2. Move to Custom Directory: Navigate to your Zsh custom directory, typically found at ~/.oh-my-zsh/custom (if you're using Oh My Zsh) or your preferred custom scripts directory.

  3. Create a New File: Create a new file for the script, naming it something memorable like git-cleanup-repo.zsh.

  4. Paste the Script: Open the newly created file in your favorite text editor, paste the script, and save your changes.

  5. Make It Executable: Ensure the script is executable by running chmod +x git-cleanup-repo.zsh in your terminal.

  6. Source Your .zshrc File: For the changes to take effect, source your .zshrc file by executing source ~/.zshrc in your terminal.

By following these steps, you'll have the Git Cleanup Script seamlessly integrated into your Zsh environment, ready to optimize your git workflow with a simple command.

The Script

# Git Cleanup Script
#
# This script is designed to clean up local and remote branches that have already been
# merged into either the 'master' or 'main' branch (whichever is currently active).
# It helps maintain a clean repository by removing branches that are no longer needed.
#
# Usage:
#   1. Make sure you are on the 'master' or 'main' branch before running this script.
#   2. Run the script using the following command:
#      $ git-cleanup-repo [production_branch]
#   3. The script will identify branches that have been fully merged and offer to
#      delete them both locally and remotely (if applicable), except for protected branches.
#
# Note:
#   - This script is intended to run on either the 'master' or 'main' branch, or a specified production branch.
#     If you attempt to run it on any other branch, it will exit with an error message.
#   - The script will never delete the following branches:
#     - main, master, production, prod, staging, stage, dev, development
#
# Author: Will Ashworth
# Created:   February 1, 2024
# Updated:   April 9, 2024
#
function git-cleanup-repo() {
    # Determine the active branch (master or main)
    active_branch=$(git symbolic-ref --short HEAD)

    # Determine the production branch
    production_branch="${1:-$active_branch}"

    # Check if the provided branch is one of the approved branches
    if [ "$production_branch" != "master" ] && [ "$production_branch" != "main" ] && [ "$production_branch" != "$active_branch" ]; then
        echo "This script is only intended to run on the 'master' or 'main' branch, or a specified production branch."
        return 1
    fi

    # Make sure we're working with the most up-to-date version of the production branch.
    git fetch origin "$production_branch:$production_branch" &>/dev/null

    # Prune obsolete remote tracking branches. These are branches that we
    # once tracked, but have since been deleted on the remote.
    git remote prune origin

    # List all the branches that have been merged fully into the production branch,
    # and then delete them, excluding protected branches.
    local_merged=$(git branch --merged "origin/$production_branch" | grep -Ev "$production_branch|main|master|production|prod|staging|stage|dev|development$")

    if [ -n "$local_merged" ]; then
        echo "The following local branches are fully merged and will be removed:"
        echo "$local_merged"

        # Ask permission (just to be safe)
        echo -n "Continue with local branch deletion (y/N)?"
        read REPLY

        # Delete the local branches that match our rules
        if [[ $REPLY =~ ^[Yy]$ ]]; then
            echo "$local_merged" | xargs git branch -d
            echo "Done!"
        fi
    else
        echo "No local branches to delete."
    fi

    # Now the same, but including remote branches.
    remote_merged=$(git branch -r --merged "origin/$production_branch" | sed 's/ *origin\///' | grep -Ev "$production_branch|main|master|production|prod|staging|stage|dev|development$")

    if [ -n "$remote_merged" ]; then
        echo "The following remote branches are fully merged and will be removed from the remote:"
        echo "$remote_merged"

        # Ask permission (just to be safe)
        echo -n "Continue with remote branch deletion (y/N)?"
        read REPLY

        # Delete the remote branches that match our rules
        if [[ $REPLY =~ ^[Yy]$ ]]; then
            git branch -r --merged "origin/$production_branch" | sed 's/ *origin\///' |
                grep -Ev "$production_branch|main|master|production|prod|staging|stage|dev|development$" | xargs -I% git push origin :% 2>&1 |
                grep --color=never 'deleted'
            echo "Done!"
        fi
    else
        echo "No remote branches to delete."
    fi
}

How To Use It

  • If you're in main or master, you can use git-cleanup-repo

  • If your source branch is something like production, then you can use git-cleanup-repo production instead. In this example, simply swap out production for something else.

  • Ensure you're on the source branch when running the script. Although, the script has detection to check for this and alert you if you aren't.

Wrapping Up

The Git Cleanup Script is more than just a utility; it's a step towards a more streamlined, efficient development process. By automating the cleanup of merged branches, it not only saves time but also keeps your repository tidy and manageable. Whether you're working on a small personal project or a large-scale professional endeavor, incorporating this script into your workflow is a move towards enhanced productivity and organization.

Try it out, and witness firsthand the difference it makes in your development routine.

0
Subscribe to my newsletter

Read articles from Will Ashworth directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Will Ashworth
Will Ashworth