Reputation: 20400
Here is the scenario: Someone has a git repository (on github if that matters) which I've forked. In my branch, I've created lots of branches with changes that the upstream has pulled. Or in some cases applied the diff of my branch instead of properly pulling the branch.
What I want to find is a list of all my branches that has been fully merged into upstreams master branch. That way I can then safely delete those branches because git branch
and other tools list 30+ branches and it looks cluttered.
I thought I explained properly why this question is different from the linked one: Or in some cases applied the diff of my branch instead of properly pulling the branch e.g. git branch --merged
is not a full answer, but oh well...
Upvotes: 4
Views: 1476
Reputation: 66299
Depending on how often you wish to do that, you may want to do it manually (explained first) or script it (explained afterwards).
In the below it is assumed there is an "upstream" remote pointing at the repòsitory you forked e.g.:
$ git remote -v
origin [email protected]:you/repo.git (fetch)
origin [email protected]:you/repo.git (push)
upstream git://github.com/original/repo.git (fetch)
upstream git://github.com/original/repo.git (push)
To get a list of branches that have already been merged with the upstream master:
$ git fetch upstream
$ git branch --merged upstream/master
my-feature
my-other-feature
master
You can then delete them:
$ git branch -d my-feature
$ git branch -d my-other-feature
If changes were applied manually, they may not be in the upstream history, and so the local branch with the equivalent code changes may not be listed. Branches where this is the case should be detected manually.
If you have local branches that represent a remote branch which has already been deleted (the branch was for a pull request, and after merging the pull request you deleted the branch via github's gui) there is a standard git command for cleaning up these branch references:
$ git remote prune origin
To get a list of remote branches in your fork which have been merged, is similar to the first command - but use the -r
switch (remote branches):
$ git branch -r --merged upstream/master
origin/my-feature
origin/my-other-feature
upstream/someone-elses-branch
To delete your own remote branches that have been merged:
$ git push origin :my-feature
$ git push --delete origin my-other-feature # equivalent, just different syntax
Be careful using a scripted solution as it's quite easy to accidentally delete a branch you didn't intend to. That said, remember that branches are just references/names - deleting a branch (by accident) doesn't mean the contents are lost they can easily be recovered (just check git reflog
for example).
The below script deletes local and remote branches which begin with "feature" - this is one way to ensure your own up-to-date master branch, for example, doesn't get deleted by accident.
#!/bin/bash
# E.g. save as ~/bin/git-cleanup, make executable and have ~/bin in your path
# call as `git cleanup`
echo -n "Fetching latest ... "
git fetch origin
git fetch upstream
echo "done"
echo "Deleting merged local feature branches ... "
branches=`git branch --no-color --merged upstream/master`
for branch in $branches;
do
if [[ "$branch" =~ ^feature ]]; then
git branch -d $branch;
fi
done
echo "done"
echo "Deleting local refs to remote branches that don't exist ... "
git remote prune origin
git remote prune upstream
echo "done"
echo "Deleting merged remote feature and hotfix branches ... "
branches=`git branch -r --no-color --merged upstream/master`
for branch in $branches;
do
if [[ "$branch" =~ ^(origin)\/(feature.*$) ]]; then
remote=${BASH_REMATCH[1]};
branch=${BASH_REMATCH[2]};
git push $remote :$branch;
fi
done
echo "done"
echo ""
echo "all finished"
Upvotes: 6
Reputation: 1327224
If you have updated your fork with the latest commits from the upstream repo (the one you have forked), you can then follow "How can I delete all git branches which are already merged?".
git branch --merged | grep -v "\*" | xargs -n 1 git branch -d
But that will only list merged branches (through pull requests for instance), not cherry-picking (when only the diff of one branch is applied to another).
For the second category, you might have to diff those local branches and see if they still have differences that aren't part of the main branches yet.
Upvotes: 1