可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I want to have my local and remote repositories always in sync in terms of branches.
After a Pull Request review on GitHub, I merge and remove my branch there (remote).
How could I fetch this information in my local repository and get Git to remove my local version of the branch as well?
回答1:
The quick way
git branch --merged | grep -v "\*" | xargs -n 1 git branch -d
NB: if you're not on master
, this has the potential to delete the branch. Keep reading for the "better way".
Make sure we keep master
You can ensure that master
, or any other branch for that matter, doesn't get removed by grep
ing for more. In that case you would go:
git branch --merged | grep -v "\*" | grep -v "YOUR_BRANCH_TO_KEEP" | xargs -n 1 git branch -d
So if we wanted to keep master
, develop
and staging
for instance, we would go:
git branch --merged | grep -v "\*" | grep -Ev "(\*|master|develop|staging)" | xargs -n 1 git branch -d
Make this an alias
Since it's a bit long, you might want to add an alias to your .zshrc
or .bashrc
. Mine is called gbpurge
(for git branches purge
):
alias gbpurge='git branch --merged | grep -Ev "(\*|master|develop|staging)" | xargs -n 1 git branch -d'
Then reload your .bashrc
or .zshrc
:
. ~/.bashrc
or
. ~/.zshrc
回答2:
I use the same flow with GitHub, and didn't find the previous answers satisfying me, as git branch --merged
lists branches which were merged, but not every of them was removed remotely in my case.
So, this worked for me:
git fetch --all -p; git branch -vv | grep ": gone]" | awk '{ print $1 }' | xargs -n 1 git branch -d
where:
git fetch --all -p
: update local branches status
git branch -vv
: list local branches status
grep ": gone]"
: filter deleted ones
awk '{ print $1 }'
: extract their names
xargs -n 1 git branch -d
: pass the name to the delete command
Note: if you prefer, you could use -D instead of -d, which enforces the delete.
For example:
someUsr@someHost:~/repo$ git branch -a
basic-testing
integration-for-tests
* master
origin
playground-for-tests
test-services
remotes/origin/HEAD -> origin/master
remotes/origin/basic-testing
remotes/origin/master
remotes/origin/test-services
someUsr@someHost:~/repo$ git fetch --all -p; git branch -vv | grep ": gone]" | awk '{ print $1 }' | xargs -n 1 git branch -d
Fetching origin
Deleted branch integration-for-tests (was fbc609a).
Deleted branch playground-for-tests (was 584b900).
someUsr@someHost:~/repo$ git branch -a
basic-testing
* master
origin
test-services
remotes/origin/HEAD -> origin/master
remotes/origin/basic-testing
remotes/origin/master
remotes/origin/test-services
Reference:
http://git-scm.com/book/en/v2/Git-Branching-Remote-Branches
回答3:
try:
git pull --prune
which deletes your local branch, if its corresponding remote branch is deleted.
Updated:
The statement above is not that correct.
In fact, running git pull --prune
will only REMOVE the remote-tracking branches such like
remotes/origin/fff
remotes/origin/dev
remotes/origin/master
Then, you can run git branch -r
to check the remote-tracking branches left on your machine. Suppose the left branches are:
origin/dev
origin/master
which means the branch origin/fff
is deleted.
So, after running git pull --prune
, just run:
git branch --merged | grep -vFf <(git branch -r | cut -d'/' -f2-)
you can find out all the local branches which:
- have no correspoding remote branches any more;
- can be removed safely.
then, <the command above> | xargs git branch -d
can delete all of them.
回答4:
This should work to avoid deleting the master and development branches with the accepted solution:
git branch --merged | egrep -v "^\*|master|development" | xargs -n 1 git branch -d
回答5:
For people using powershell, this is the equivalent to the answer above:
git branch -vv | Select-String -Pattern ': gone]' | ForEach-Object{($_ -split "\s+")[1]} | %{ git branch -D $_ }
- Filter all the branches that are marked as gone
- Call
git branch -D
on each of the found branches
回答6:
None of this was working for me. You can see my other answer here:
https://stackoverflow.com/a/34969726/550454
But essentially, I now have this in my ~/.gitconfig
:
[alias]
prune-branches = !git remote prune origin && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs -r git branch -d
回答7:
Very simple solution: remove your local repo and clone the remote one anew. May not seem very elegant, but it is simple and you'll understand exactly what you're doing without reading man pages :-).
回答8:
I've written this one-liner to list all local branches which do not have corresponding remote branch:
diff -u <(git branch|sed 's/..//') <(git branch -r|sed 's/..origin\///')|tail -n +4|sed -n "s/^-//p" -
After this done, deleting these local branches is easy with xargs
:
diff -u <(git branch|sed 's/..//') <(git branch -r|sed 's/..origin\///')|tail -n +4|sed -n "s/^-//p" -|xargs -r git branch -d
回答9:
I just do that to remove merged local branches:
git branch -d $(git branch --merged)
and in case you want to remove inexistent trackings too:
git pull --prune
回答10:
In the event that you've just pushed and merged your branch to master, then do the following in git bash:
git branch -d branch_name_to_delete
If you're currently in that branch it will push you back to master. At this point do a pull with
git pull
回答11:
The voted answer does have the potential to delete master. Consdier the below practical example.
I had two feature branches hemen_README and hemen_BASEBOX which were merged into develop, and then develop was merged into master. The feature branches hemen_README and hemen_BASEBOX were deleted remotely but were still showing up locally. Also i am not on master locally, but on develop.
In that case
hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -v -a
* develop 671ad6c Merged in hemen_README (pull request #1)
hemen_BASEBOX a535c0f added global exec paths to puppet manifest
hemen_README ba87489 Updated Readme with considerable details
master 8980894 [behind 7] Initial Vagrantfile, works for vagrant up. Also initial .gitignore
remotes/origin/develop 671ad6c Merged in hemen_README (pull request #1)
remotes/origin/hemen_BASEBOX a535c0f added global exec paths to puppet manifest
remotes/origin/hemen_README ba87489 Updated Readme with considerable details
remotes/origin/master 2f093ce Merged in develop (pull request #3)
So if i run the above partial command
hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch --merged | grep -v "\*"
hemen_BASEBOX
hemen_README
master
Notice that it shows master too, which will eventually be deleted.
In any case I was able to do it. I am sharing my session log with you on how I achieved that.
hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git remote prune origin --dry-run
Pruning origin
URL: git@bitbucket.org:hemenkapadiapublic/vagrant-webdev.git
* [would prune] origin/hemen_BASEBOX
* [would prune] origin/hemen_README
hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git remote prune origin
Pruning origin
URL: git@bitbucket.org:hemenkapadiapublic/vagrant-webdev.git
* [pruned] origin/hemen_BASEBOX
* [pruned] origin/hemen_README
I just checked whay will be pruned and then pruned it. looking at branch command below we have taken care of remotes
hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -v -a
* develop 671ad6c Merged in hemen_README (pull request #1)
hemen_BASEBOX a535c0f added global exec paths to puppet manifest
hemen_README ba87489 Updated Readme with considerable details
master 8980894 [behind 7] Initial Vagrantfile, works for vagrant up. Also initial .gitignore
remotes/origin/develop 671ad6c Merged in hemen_README (pull request #1)
remotes/origin/master 2f093ce Merged in develop (pull request #3)
Now go ahead and delete local branches
hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -d hemen_BASEBOX
Deleted branch hemen_BASEBOX (was a535c0f).
hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -d hemen_README
Deleted branch hemen_README (was ba87489).
Good now the branches are as desired.
hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -v -a
* develop 671ad6c Merged in hemen_README (pull request #1)
master 8980894 [behind 7] Initial Vagrantfile, works for vagrant up. Also initial .gitignore
remotes/origin/develop 671ad6c Merged in hemen_README (pull request #1)
remotes/origin/master 2f093ce Merged in develop (pull request #3)