如何修剪远程不存在的本地跟踪分支

使用git remote prune origin我可以删除远程没有的本地分支。

但是我也想删除那些从这些远程分支创build的地方分支(检查他们是否没有被分开会很好)。

我该怎么做?

修剪后,你可以用git branch -r得到远程分支的列表。 可以使用git branch -vv检索带有远程跟踪分支的分支列表。 因此,使用这两个列表可以find不在远程列表中的远程跟踪分支。

这一行应该做的伎俩(需要bashzsh ,将不能使用标准的Bourne shell):

git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -d

该string获取远程分支的列表,并通过标准input将其传递给egrep 。 并过滤具有远程跟踪分支的分支(使用git branch -vv和过滤那些有origin git branch -vv ),然后得到该输出的第一列,这将是分支名称。 最后将所有分支名称传入删除分支命令。

由于它使用的是-d选项,因此在运行此命令时,它不会删除尚未合并到您所在分支中的分支。

还要记住,你需要首先运行git fetch --prune ,否则git branch -r仍然会看到远程分支。

如果要删除已经合并到主服务器中的所有本地分支机构,则可以使用以下命令:

 git branch --merged master | grep -v '^[ *]*master$' | xargs git branch -d 

更多信息 。

git help fetch的信息的git help fetch ,有这个小项目:

  -p, --prune After fetching, remove any remote-tracking branches which no longer exist on the remote. 

所以,也许, git fetch -p是你在找什么?

编辑:好吧,对于那些仍然辩论这个答案3年后的事实,这里是更多的信息为什么我提出这个答案…

首先,OP表示他们希望“删除那些从远程分支机构创build的远程分支机构”。 这不是在git明确可能的。 这是一个例子。

比方说,我有一个中央服务器上的回购,它有两个分支,称为AB 如果我克隆到本地系统的回购,我的克隆将有本地裁判(尚未实际的分支机构)称为origin/Aorigin/B 现在让我们说我做以下几点:

 git checkout -b A origin/A git checkout -b Z origin/B git checkout -b C <some hash> 

这里的相关事实是,我出于某种原因select了在本地仓库上创build一个与其起源名称不同的分支,并且我还拥有一个本地分支,但是它还没有存在于原始仓库中。

现在让我们说,我删除远程回购AB分支,并更新我的本地回购(某种forms的git fetch ),这导致我的本地裁判origin/Aorigin/B消失。 现在,我的本地回购有三个分支, AZC 这些都没有在远程回购相应的分支。 其中两个是“从…远程分支创build的”,但即使我知道在原点上曾经有一个叫做B的分支,我也无法知道Z是从B创build的,因为它被重命名为这个过程,可能是有很好的理由的。 所以,实际上,如果没有外部进程logging分支源元数据,或者知道历史logging的人,就不可能知道OP的三个分支中的哪一个(如果有的话)是要删除的。 如果没有一些外部信息, git不会自动为你保留, git fetch -p就像你所能得到的一样近,任何自动的尝试OP所要求的方法都会导致删除太多分支或者丢失一些否则OP将以其他方式删除。

还有其他一些情况,例如,如果我创build了三个独立的分支,从origin/Atesting三种不同的方法,然后origin/A消失。 现在我有三个分支,显然不能全部匹配名称,但是它们是从origin/A创buildorigin/A ,所以OP的问题的字面解释需要删除这三个分支。 但是,如果你甚至可以find一个可靠的方法来匹配它们,那么这可能是不可取的。

这将删除远程追踪分支已被修剪的本地分行。 (确保你在master分支!)

 git checkout master git branch -vv | grep ': gone]' | awk '{print $1}' | xargs git branch -d 

细节:

  • git branch -vv显示远程已被修剪的本地分支。

     mybranch abc1234 [origin/mybranch: gone] commit comments 
  • -d会检查它是否被合并( -D将会删除它)

     error: The branch 'mybranch' is not fully merged. 

你可以configurationGit在提取时自动删除对已删除的远程分支的引用:

 git config --global fetch.prune true 

之后调用git fetchgit pull ,对已删除的远程分支的引用将被自动删除。

它将列出从远程删除远程追踪分支的本地分行

 $ git remote prune origin --dry-run 

如果您想从本地取消引用这些本地分支,那么这些分支是未被跟踪的

 $ git remote prune origin 

如果使用Windows和Powershell,则可以使用以下命令删除已合并到当前检出的分支中的所有本地分支:

 git branch --merged | ? {$_[0] -ne '*'} | % {$_.trim()} | % {git branch -d $_} 

说明

  • 列出当前分支和已经合并到其中的分支
  • 过滤掉当前分支
  • 清除每个剩余分支名称的git输出的任何前导或尾随空格
  • 删除合并的本地分支

这是值得运行的git branch --merged自己首先git branch --merged ,以确保它只会去除你所期望的。

(从http://railsware.com/blog/2014/08/11/git-housekeeping-tutorial-clean-up-outdated-branches-in-local-and-remote-repositories/移植/自动化。);

不知道如何做到一次,但git git branch -d <branchname>将只删除一个本地分支,如果它完全合并。 注意小写字母d。

git branch -D <branchname> (注意大写git branch -D <branchname> D)会删除一个本地分支,不pipe它的合并状态如何。

更短,更安全的单线:

 git branch -d $(git branch --merged | cut -c 3-) 

在运行之前,请务必检查尚未合并的分支。 因为您不能删除当前签入的分支。

在@ wisbucky的答案上使用变体,我添加了以下作为我的~/.gitconfig文件的别名:

 pruneitgood = "!f() { \ git remote prune origin; \ git branch -vv | perl -nae 'system(qw(git branch -d), $F[0]) if $F[3] eq q{gone]}'; \ }; f" 

有了这个,一个简单的git pruneitgood将清理合并后不再需要的本地和远程分支。

有一个整洁的NPM包,它为你做(它应该跨平台)。

安装它: npm install -g git-removed-branches

然后git removed-branches将显示所有陈旧的本地分支和git removed-branches --prune实际上删除它们。

更多信息在这里。

基于上面的答案,我来到这一行解决scheme:

 git remote prune origin; git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -d 

Schleis的变体不适合我(Ubuntu 12.04),所以让我来提出我的(清晰而有光泽的:)变体:

变种1(我更喜欢这个选项):

 git for-each-ref --format='%(refname:short) %(upstream)' refs/heads/ | awk '$2 !~/^refs\/remotes/' | xargs git branch -D 

变体2:

一个。 干运行:

 comm -23 <( git branch | grep -v "/" | grep -v "*" | sort ) <( git br -r | awk -F '/' '{print $2}' | sort ) | awk '{print "git branch -D " $1}' 

湾 删除分支:

 comm -23 <( git branch | grep -v "/" | grep -v "*" | sort ) <( git br -r | awk -F '/' '{print $2}' | sort ) | xargs git branch -D 

我已经把接受的答案变成一个强大的脚本。 你会在我的git扩展库中find它。

 $ git-prune --help Remove old local branches that do not exist in <remote> any more. With --test, only print which local branches would be deleted. Usage: git-prune [-t|--test|-f|--force] <remote> 

以下是Windows用户对@ wisbucky的解答:

for /f "tokens=1" %i in ('git branch -vv ^| findstr ": gone]"') DO git branch %i -d

我使用posh-git,不幸的是PS不喜欢裸体,所以我创build了一个普通的命令脚本PruneOrphanBranches.cmd:

 @ECHO OFF for /f "tokens=1" %%i in ('git branch -vv ^| findstr ": gone]"') DO CALL :ProcessBranch %%i %1 GOTO :EOF :ProcessBranch IF /I "%2%"=="-d" ( git branch %1 %2 ) ELSE ( CALL :OutputMessage %1 ) GOTO :EOF :OutputMessage ECHO Will delete branch [%1] GOTO :EOF :EOF 

调用它没有参数看到一个列表,然后用“-d”调用它来执行实际的删除或“-D”为任何没有完全合并,但是你想要删除的分支。

在git bash中试试这个,获取和删除对被删除分支的引用,然后修剪跟踪被删除分支的本地分支:

 git fetch -p && git branch -d `git branch -vv | grep ': gone]' | awk '{print $1}' | xargs` 

记得首先签出一个不会被删除的分支,这样就不会阻止删除分支。

删除任何不熟悉master的分支

 git co master && git branch | sed s/\*/\ / | xargs git branch -d 2> /dev/null 

如果你从本地计算机中删除,这是我的直接方式:

只需进入: C:\Repo\your-project\.git\refs\heads

每个分支是在这个文件夹下创build的文件,只是删除与您的分支名称匹配的文件

在Windows上很难find方法,我正在使用sourcetree,我不想一一删除。 我只是弄明白了这一点,它确实救了我的Windows。

我敢肯定, git remote prune origin是你想要的。

你可以运行它作为git remote prune origin --dry-run ,看看做什么,而不作任何改变。

使用GUI? 手动程序,但快速和容易。

 $ git gui 

select“分支 – >删除”。 你可以用ctrl-click(windows)来select多个分支并删除所有分支。