Last active
April 14, 2025 08:13
-
-
Save vaishnavmhetre/dad7246f2dfceffe2c2f1d8c5ff68e6c to your computer and use it in GitHub Desktop.
Git Branches cleanup
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ------------------------------------------------------------------------------ | |
# git_list_untracked | |
# | |
# Lists local Git branches that are tracking a remote branch which no longer | |
# exists (i.e., the remote was deleted or the branch was removed from the remote). | |
# | |
# - First runs `git fetch --prune` to clean up stale remote references. | |
# - Then checks all local branches with an upstream and verifies if the remote | |
# branch still exists. | |
# - Filters out "main" and "master" from the results to avoid accidental deletion. | |
# | |
# Usage: | |
# git_list_untracked | |
# ------------------------------------------------------------------------------ | |
git_list_untracked() { | |
git fetch --prune | |
git for-each-ref --format='%(refname:short) %(upstream:short)' refs/heads/ | | |
while read -r local_branch upstream; do | |
if [[ -n "$upstream" ]] && ! git show-ref --verify --quiet "refs/remotes/$upstream"; then | |
echo "$local_branch" | |
fi | |
done | grep -vE '^(main|master)$' | |
} | |
# ------------------------------------------------------------------------------ | |
# git_remove_untracked [--dry-run] | |
# | |
# Deletes local branches that no longer track a valid remote branch. | |
# | |
# - By default, deletes branches listed by `git_list_untracked`. | |
# - Use `--dry-run` to only list the branches that *would* be deleted, | |
# without actually deleting them. | |
# | |
# Skips deletion if no such branches are found. | |
# | |
# Usage: | |
# git_remove_untracked # actually deletes untracked branches | |
# git_remove_untracked --dry-run # previews deletions only | |
# ------------------------------------------------------------------------------ | |
git_remove_untracked() { | |
local dry_run=false | |
if [[ "$1" == "--dry-run" ]]; then | |
dry_run=true | |
fi | |
local branches | |
branches=$(git_list_untracked) | |
if [[ -z "$branches" ]]; then | |
echo "β No untracked local branches to delete." | |
return 0 | |
fi | |
echo "π§Ή Untracked branches:" | |
echo "$branches" | |
if $dry_run; then | |
echo "π‘ Dry run mode. No branches will be deleted." | |
else | |
echo "$branches" | xargs -r git branch -D | |
echo "β Deleted untracked branches." | |
fi | |
} | |
# ------------------------------------------------------------------------------ | |
# git_hard_sync [repo_path] | |
# | |
# Safely hard-resets the current branch in the given Git repository (or current | |
# directory) to match its upstream (remote-tracking) branch. | |
# | |
# - Checks if the given path is a Git repository. | |
# - Detects the current branch and its upstream. | |
# - Asks for confirmation before discarding local changes via `git reset --hard`. | |
# | |
# Useful for syncing a feature branch after someone rebased and force-pushed it. | |
# | |
# Usage: | |
# git_hard_sync # operates in current directory | |
# git_hard_sync /path/to/repo # operates in the specified repo | |
# ------------------------------------------------------------------------------ | |
git_hard_sync() { | |
local repo_path="${1:-.}" | |
if [ ! -d "$repo_path/.git" ]; then | |
echo "β '$repo_path' is not a valid Git repository." | |
return 1 | |
fi | |
( | |
cd "$repo_path" || exit 1 | |
local branch | |
branch=$(git rev-parse --abbrev-ref HEAD) | |
local upstream | |
upstream=$(git rev-parse --abbrev-ref @{u} 2>/dev/null) | |
if [ -z "$upstream" ]; then | |
echo "β No upstream branch set for '$branch'." | |
return 1 | |
fi | |
echo "π In repo: $repo_path" | |
echo "π You're on branch '$branch'." | |
echo "β οΈ This will HARD RESET to match '$upstream'." | |
read -p "Are you sure? This will discard local changes. (y/N): " confirm | |
if [[ "$confirm" =~ ^[Yy]$ ]]; then | |
git fetch && git reset --hard "$upstream" | |
echo "β Branch '$branch' has been reset to '$upstream'." | |
else | |
echo "π« Aborted." | |
fi | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment