Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cleaning up old remote git branches

Tags:

git

git-branch

People also ask

Should I delete old git branches?

They're unnecessary. In most cases, branches, especially branches that were related to a pull request that has since been accepted, serve no purpose. They're clutter. They don't add any significant technical overhead, but they make it more difficult for humans to work with lists of branches in the repository.

Does git prune remove remote branches?

git fetch --prune is the best utility for cleaning outdated branches. It will connect to a shared remote repository remote and fetch all remote branch refs. It will then delete remote refs that are no longer in use on the remote repository.

How remove deleted branch from remote?

Steps to delete remote Git branchesIssue the git push origin –delete branch-name command, or use the vendor's online UI to perform a branch deletion. After the remote branch is deleted, then delete the remote tracking branch with the git fetch origin –prune command.

How do I delete unused branches?

Deleting a branch LOCALLY Delete a branch with git branch -d <branch> . The -d option will delete the branch only if it has already been pushed and merged with the remote branch. Use -D instead if you want to force the branch to be deleted, even if it hasn't been pushed or merged yet. The branch is now deleted locally.


First, what is the result of git branch -a on machine B?

Second, you have already deleted heads/devel on origin, so that's why you can't delete it from machine B.

Try

git branch -r -d origin/devel

or

git remote prune origin

or

git fetch origin --prune

and feel free to add --dry-run to the end of your git statement to see the result of running it without actually running it.

Docs for git remote prune and git branch.


Consider to run :

git fetch --prune

On a regular basis in each repo to remove local branches that have been tracking a remote branch that is deleted (no longer exists in remote GIT repo).

This can be further simplified by

git config remote.origin.prune true

this is a per-repo setting that will make any future git fetch or git pull to automatically prune.

To set this up for your user, you may also edit the global .gitconfig and add

[fetch]
    prune = true

However, it's recommended that this is done using the following command:

git config --global fetch.prune true

or to apply it system wide (not just for the user)

git config --system fetch.prune true

Here is bash script that can do it for you. It's modified version of http://snippets.freerobby.com/post/491644841/remove-merged-branches-in-git script. My modification enables it to support different remote locations.

#!/bin/bash

current_branch=$(git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')
if [ "$current_branch" != "master" ]; then
  echo "WARNING: You are on branch $current_branch, NOT master."
fi
echo -e "Fetching merged branches...\n"

git remote update --prune
remote_branches=$(git branch -r --merged | grep -v '/master$' | grep -v "/$current_branch$")
local_branches=$(git branch --merged | grep -v 'master$' | grep -v "$current_branch$")
if [ -z "$remote_branches" ] && [ -z "$local_branches" ]; then
  echo "No existing branches have been merged into $current_branch."
else
  echo "This will remove the following branches:"
  if [ -n "$remote_branches" ]; then
echo "$remote_branches"
  fi
  if [ -n "$local_branches" ]; then
echo "$local_branches"
  fi
  read -p "Continue? (y/n): " -n 1 choice
  echo
  if [ "$choice" == "y" ] || [ "$choice" == "Y" ]; then
    remotes=`echo "$remote_branches" | sed 's/\(.*\)\/\(.*\)/\1/g' | sort -u`
# Remove remote branches
for remote in $remotes
do
        branches=`echo "$remote_branches" | grep "$remote/" | sed 's/\(.*\)\/\(.*\)/:\2 /g' | tr -d '\n'`
        git push $remote $branches 
done

# Remove local branches
git branch -d `git branch --merged | grep -v 'master$' | grep -v "$current_branch$" | sed 's/origin\///g' | tr -d '\n'`
  else
echo "No branches removed."
  fi
fi

This command will "dry run" delete all remote (origin) merged branches, apart from master. You can change that, or, add additional branches after master: grep -v for-example-your-branch-here |

git branch -r --merged | 
  grep origin | 
  grep -v '>' | 
  grep -v master | 
  xargs -L1 | 
  awk '{sub(/origin\//,"");print}'| 
  xargs git push origin --delete --dry-run

If it looks good, remove the --dry-run. Additionally, you may like to test this on a fork first.


I'll have to add an answer here, because the other answers are either not covering my case or are needlessly complicated. I use github with other developers and I just want all the local branches whose remotes were (possibly merged and) deleted from a github PR to be deleted in one go from my machine. No, things like git branch -r --merged don't cover the branches that were not merged locally, or the ones that were not merged at all (abandoned) etc, so a different solution is needed.

Anyway, the first step I got it from other answers:

git fetch --prune

A dry run of git remote prune origin seemed like it would do the same thing in my case, so I went with the shortest version to keep it simple.

Now, a git branch -v should mark the branches whose remotes are deleted as [gone]. Therefore, all I need to do is:

git branch -v|grep \\[gone\\]|awk '{print $1}'|xargs -I{} git branch -D {}

As simple as that, it deletes everything I want for the above scenario.

The less common xargs syntax is so that it also works on Mac & BSD in addition to Linux. Careful, this command is not a dry run so it will force-delete all the branches marked as [gone]. Obviously, this being git nothing is gone forever, if you see branches deleted that you remember you wanted kept you can always undelete them (the above command will have listed their hash on deletion, so a simple git checkout -b <branch> <hash>.

Edit: Just add this alias to your .bashrc/.bash_profile, the two commands made into one and I updated the second to work on all shells:

alias old_branch_delete='git fetch -p && git branch -vv | awk "/: gone]/{print \$1}" | xargs git branch -D'

If git branch -r shows a lot of remote-tracking branches that you're not interested in and you want to remove them only from local, use the following command:

git branch -r | grep -Ev 'HEAD|master|develop'  | xargs -r git branch -rd

A safer version would be to only remove the merged ones:

git branch -r --merged | grep -Ev 'HEAD|master|develop'  | xargs -r git branch -rd

This might be useful for large projects, where you don't need the feature branches of other teammates but there're lots of remote-tracking branches fetched upon the initial clone.

However, this step alone is not sufficient, because those deleted remote-tracking branches would come back upon next git fetch.

To stop fetching those remote-tracking branches you need to explicitly specify the refs to fetch in .git/config:

[remote "origin"]
  # fetch = +refs/heads/*:refs/remotes/origin/*    ### don't fetch everything
  fetch = +refs/heads/master:refs/remotes/origin/master
  fetch = +refs/heads/develop:refs/remotes/origin/develop
  fetch = +refs/heads/release/*:refs/remotes/origin/release/*

In the above example we only fetch master, develop and release branches, feel free to adapt as you need.