在远程仓库上删除本地Git分支后将其删除


162

我希望本地和远程存储库始终在分支方面保持同步。

在GitHub上的请求请求审核后,我合并并删除了那里的分支(远程)。我如何才能在本地存储库中获取此信息,并让Git也删除分支的本地版本?


您要删除远程跟踪分支,本地分支还是两者都删除?实际上,您可以编写一个别名(bash或git),该别名将使用所有已删除的远程分支,并找到要删除的本地副本,所有这些都可以在一个命令中完成。

也许尝试使用以下命令提出一些建议,git ls-remote然后git show-ref

另外,您可能想签出git symbolic-refgit update-ref

感谢您的帮助,我最终在其他地方找到了答案。看到我的回应。
2013年

Answers:


180

快速方法

git branch --merged | grep -v "\*" | xargs -n 1 git branch -d

注意:如果您不在master,则有可能删除分支。继续阅读“更好的方法”。

确保我们保持主人

您可以确保ing master或更多分支不会被删除grep。在这种情况下,您可以:

git branch --merged | grep -v "\*" | grep -v "YOUR_BRANCH_TO_KEEP" | xargs -n 1 git branch -d

因此,如果我们想继续保持masterdevelopstaging举例来说,我们会去:

git branch --merged | grep -v "\*" | grep -Ev "(\*|master|develop|staging)" | xargs -n 1 git branch -d

将此设为别名

由于有点长,您可能要为.zshrc或添加别名.bashrc。我的被​​称为gbpurgegit branches purge):

alias gbpurge='git branch --merged | grep -Ev "(\*|master|develop|staging)" | xargs -n 1 git branch -d'

然后重新加载您.bashrc.zshrc

. ~/.bashrc

要么

. ~/.zshrc

您可以将命令放在别名中并使其成为单个命令。但是,由于branch瓷器而不是管道命令,所以请注意将来的Git版本中可能会破坏它的UI更改。

1
完善!请注意,在Github工作流程之后,本地分支master将被删除。
Rubens Mariuzzo 2014年

不,很确定它会留在那儿(我每天都在使用它,但它似乎没有这样做)。
2014年

4
仅供参考,如果您想保留多个分支,则可以使用一个grep,如下所示: grep -Ev '(\*|master|important-branch)'
Andrew Burns

4
如果您想将其放在自己的位置~/.gitconfig,则将以下内容添加到该[alias]部分:(gbpurge = !"git branch --merged | grep -Ev '\\*|master|develop|staging' | xargs -n 1 git branch -d"无需在grep表达式中使用())。
dskrvk

82

我在GitHub上使用相同的流程,但没有找到令我满意的先前答案,因为git branch --merged列出了合并的分支,但就我而言,并不是每个分支都被远程删除了。因此,这为我工作:

git fetch --all -p; git branch -vv | grep ": gone]" | awk '{ print $1 }' | xargs -n 1 git branch -d

哪里:

  • git fetch --all -p:更新本地分支机构状态
  • git branch -vv:列出本地分支机构的状态
  • grep ": gone]":筛选已删除的
  • awk '{ print $1 }':提取他们的名字
  • xargs -n 1 git branch -d:将名称传递给delete命令

注意:如果愿意,可以使用-D代替-d来强制执行删除。

例如:

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

参考:

http://git-scm.com/book/en/v2/Git-Branching-Remote-Branches


3
我采取了自由行动,以确保我将始终对大师如此,因此: git checkout master; git pull origin master; git fetch --all -p; git branch -vv | grep gone | awk '{ print $1 }' | xargs -n 1 git branch -d
出色的

请注意,它branch -vv显示了分支中的最后提交消息。如果您在该消息中碰巧已经“走了”,那grep gone也将打到该分支。因此,grep ": gone]"使用起来可能更安全一些。
chawkinsuf 2015年

1
这是对该问题的实际答案。谢谢。
Andrei Gladkyi 2015年

1
更好的是:awk '$3 $4 ~ /:gone]$/ { print $1 }'
Jakub Bochenski'8

3
除了需要之外-D-d这是一个完美的答案!
卡斯(Cas

72

尝试:

git pull --prune

如果删除了其相应的远程分支,则会删除您的本地分支。

更新:

上面的说法并不正确。

事实上,运行git pull --prune只删除远程跟踪分支诸如此类

遥控器/原点/ fff
遥控器/起源/开发
遥控器/原点/主机

然后,您可以运行git branch -r以检查计算机上剩余的远程跟踪分支。假设左分支是:

原始/开发
起源/主人

这意味着该分支将origin/fff被删除。

因此,运行后git pull --prune,只需运行:

git branch --merged | grep -vFf <(git branch -r | cut -d'/' -f2-)

您可以找到所有本地分支机构:

  1. 不再有相应的远程分支;
  2. 可以安全移除。

然后,<the command above> | xargs git branch -d可以删除所有这些。


42
这个答案不太正确。该--prune标志将仅删除远程跟踪分支,而不会删除本地分支。

3
在这里同意@Cupcake,这不能实现我在这里寻找的东西。
sf89

6
不打算投票,但这是我删除本地分支然后从GitHub删除后所需要的,但是它们仍然作为git remote -v命令中的远程对象存在。
Spechal 2014年

8
您也可以这样做git fetch --prune,这是我的选择方式
e_m0ney

1
来自堆栈溢出的建议中的另一个Git错误... git pull --prune导致“您要求从远程'--prune'中拉出,但未指定分支。因为这不是当前分支的默认配置远程,必须在命令行上指定一个分支。”
jww

23

这应该可以避免使用已接受的解决方案删除masterdevelopment分支:

git branch --merged | egrep -v "^\*|master|development" | xargs -n 1 git branch -d

16

对于使用powershell的人,这相当于上面的答案:

git branch -vv | Select-String -Pattern ': gone]' | ForEach-Object{($_ -split "\s+")[1]} | %{ git branch -D $_ }
  1. 筛选所有标记为已消失的分支
  2. 调用git branch -D每个找到的分支


5

非常简单的解决方案:删除本地存储库,然后重新克隆远程存储库。可能看起来不太优雅,但它很简单,您无需阅读手册页即可完全了解自己在做什么:-)。


1
为什么要投票这么多?我的意思是显然效率不高,尤其是在使用更大的回购协议的情况下,但这确实符合OP的要求。还有其他原因不这样做吗?
3ocene

6
因为您将丢失所有本地分支机构,藏匿处,未推动的提交……这就像用炸药捕鱼一样。
sevenseacat '17

1
当您使用的笔记本电脑因某种原因损坏,丢失或被盗时,也会发生同样的情况,因此我倾向于在本地保持任何重要状态。对我来说,最好只是创建一个分支并将其推送(即使是用于小的功能),并在不再有用之后将其删除。

1

我编写了此单行代码,列出了所有没有相应远程分支的本地分支:

diff -u <(git branch|sed 's/..//') <(git branch -r|sed 's/..origin\///')|tail -n +4|sed -n "s/^-//p" -

完成此操作后,使用以下命令即可轻松删除这些本地分支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

master也在列出我,它没有按预期工作;小心
Enrico

1

我只是这样做以删除合并的本地分支:

git branch -d $(git branch --merged)

并且如果您也想删除不存在的跟踪,请执行以下操作:

git pull --prune

1

如果您刚刚将分支推送并合并到master,请在git bash中执行以下操作:

git branch -d branch_name_to_delete

如果您当前在该分支机构中,它将把您推回母版。在这一点上做一个拉

git pull

-2

投票的答案确实有可能删除母版。考虑以下实际示例。

我有两个功能分支hemen_README和hemen_BASEBOX合并到development中,然后将development合并到master中。功能分支hemen_README和hemen_BASEBOX已远程删除,但仍在本地显示。我也不是本地的高手,而是发展中的人。

在这种情况下

    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)

所以如果我运行上面的部分命令

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch --merged | grep -v "\*"
        hemen_BASEBOX
        hemen_README
        master

请注意,它也显示了master,它将最终被删除。

无论如何我都能做到。我正在与您分享我的会话日志,以了解我是如何实现的。

    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

我只是检查了将被修剪的乳清,然后修剪了它。看下面的分支命令,我们已经照顾了遥控器

    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)

现在继续删除本地分支

    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).

现在好了,分支按需要了。

    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)

当然,它有可能删除母版。请仔细阅读问题。就像我在那儿所说的那样,我需要一种方法来清理我本地的东西。这意味着删除远程不再存在的所有分支。如果master不再存在,则它也将在本地计算机上消失。
sf89 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.