随着git remote prune origin
我可以删除本地分支机构不在遥控器上的任何更多。
但是我还想删除从那些远程分支创建的本地分支(检查它们是否未合并将是不错的选择)。
我怎样才能做到这一点?
npx git-removed-branches
干运转)或npx git-removed-branches --prune
(真实)。您需要已经有node.js的安装。有关详细信息,请参见下面的答案 。
随着git remote prune origin
我可以删除本地分支机构不在遥控器上的任何更多。
但是我还想删除从那些远程分支创建的本地分支(检查它们是否未合并将是不错的选择)。
我怎样才能做到这一点?
npx git-removed-branches
干运转)或npx git-removed-branches --prune
(真实)。您需要已经有node.js的安装。有关详细信息,请参见下面的答案 。
Answers:
修剪后,您可以使用获取远程分支的列表git branch -r
。可以使用检索带有远程跟踪分支的分支列表git branch -vv
。因此,使用这两个列表,您可以找到不在远程列表中的远程跟踪分支。
这行应该可以解决问题(需要bash
或zsh
,不适用于标准的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
该字符串获取远程分支的列表,并将其传递到egrep
标准输入中。并过滤具有远程跟踪分支的分支(使用git branch -vv
和过滤具有的分支origin
),然后获取该输出的第一列,即分支名称。最后,将所有分支名称传递给delete分支命令。
由于使用了该-d
选项,因此它不会删除尚未合并到运行该命令时所在的分支的分支。
还记得你需要运行的git fetch --prune
第一,否则git branch -r
仍然会看到远程分支。
git fetch -p
并不总是足够?
sh.exe": cannot make pipe for process substitution: Function not implemented sh.exe": egrep -v -f /dev/fd/0: No such file or directory fatal: branch name required
有任何想法吗?
alias git-remove-untracked='git fetch --prune && git branch -r | awk "{print \$1}" | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk "{print \$1}" | xargs git branch -d'
git branch -D
在命令末尾使用,对我们来说效果更好,因为我们倾向于压缩合并时的提交,因此The branch x is not fully merged
在运行时会出错-d
。
如果要删除已经合并到master中的所有本地分支,可以使用以下命令:
git branch --merged master | grep -v '^[ *]*master$' | xargs git branch -d
更多信息。
git branch --merged master --no-color | grep -v '^* master$' | xargs -n1 -r git branch -d
git branch --merged master
列出了合并到master中的分支,然后中间的grep部分排除了master本身(我们不想删除master!),最后一个xargs部分git branch -d
在每一个上执行(删除分支)结果。或者,您也可以阅读答案中提供的“更多信息”链接;)
git branch --merged master | egrep -v '^\s*\*?\s*master$' | xargs git branch -d
。检出master时,git v2.10.1的输出将显示“ * master”。无论有没有星号,我都会摆脱掌握。
在中提供的信息中git help fetch
,有一个小项目:
-p, --prune
After fetching, remove any remote-tracking branches which no longer exist on the remote.
那么,也许git fetch -p
是您要找的东西?
编辑:好的,对于那些在事实发生三年后仍在争论这个答案的人,这里有更多关于我为什么提出这个答案的信息。
首先,OP表示他们希望“也删除从那些远程分支[不再在远程]上创建的本地分支”。在中,这并非不可能git
。这是一个例子。
假设我在中央服务器上有一个存储库,它有两个分支,分别称为A
和B
。如果我将该存储库克隆到本地系统,则我的克隆将具有称为origin/A
和的本地引用(尚未有实际分支)origin/B
。现在,让我说以下:
git checkout -b A origin/A
git checkout -b Z origin/B
git checkout -b C <some hash>
这里的相关事实是,由于某种原因,我选择了在本地存储库中创建一个名称与原始名称不同的分支,并且我也有一个本地分支(尚未)存在于原始存储库中。
现在,假设我同时删除了远程仓库中的A
和B
分支,并更新了本地仓库(git fetch
某种形式),这会导致本地引用origin/A
并origin/B
消失。现在,我的本地回购有三大分支的是,A
,Z
,和C
。这些都没有在远程仓库上有相应的分支。其中两个是“从...远程分支创建的”,但是即使我知道曾经有一个B
起源调用过的分支,我也无法知道它Z
是从...创建的B
,因为在此过程中将其重命名,可能有充分的理由。因此,实际上,如果没有任何外部过程来记录分支原始元数据,或者没有一个知道历史的人员,就无法确定OP的目标是删除三个分支中的哪个(如果有)。如果没有一些git
不会自动为您维护的外部信息,这些信息将git fetch -p
尽可能地接近您,并且任何自动尝试OP请求的自动方法都可能会删除过多的分支,或者会丢失OP否则会丢失的分支要删除。
同样,还有其他场景,例如,如果我创建了三个单独的分支origin/A
来测试三种不同的方法,然后origin/A
消失了。现在,我有三个分支,显然不能全部按名称匹配,但是它们是从创建的origin/A
,因此要对OPs问题进行字面解释,则需要删除所有三个分支。但是,如果您甚至可以找到一种可靠的方式来匹配它们,那可能就不那么理想了……
这将删除已修剪了远程跟踪分支的本地分支。(确保您在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.
git branch -vv | awk '/: gone]/{print $1}' | xargs git branch -d
git branch -d
比较分支与HEAD
。
prunelocal = !sh -c \"git checkout -q master && git fetch -q --prune && git branch -vv | git grep ': gone]' | cut -d' ' -f3 | xargs git branch -d\"
有一个简洁的NPM软件包可以为您完成(它应该跨平台工作)。
通过以下方式安装: npm install -g git-removed-branches
然后git removed-branches
将向您显示所有过时的本地分支,并git removed-branches --prune
实际将其删除。
npx git-removed-branches
像梦一样工作。
对于Microsoft Windows Powershell:
git checkout master; git remote update origin --prune; git branch -vv | Select-String -Pattern ": gone]" | % { $_.toString().Trim().Split(" ")[0]} | % {git branch -d $_}
git checkout master
切换到主分支
git remote update origin --prune
修剪偏远的分支机构
git branch -vv
获取所有分支的详细输出(git reference)
Select-String -Pattern ": gone]"
仅获取已从远程删除它们的记录。
% { $_.toString().Split(" ")[0]}
获取分支名称
% {git branch -d $_}
删除分支
git remote prune origin
,select-string似乎与最新版本的git不匹配。考虑使用ConvertFrom-String -TemplateContent
git checkout master; git pull; git remote prune origin; git branch --merged | select-string -notmatch "master" | % { $_.toString().Trim().Split(" ")[0]} | % {git branch -d $_}
它将列出其远程跟踪分支已从远程删除的本地分支
$ git remote prune origin --dry-run
如果要取消引用未跟踪的本地分支
$ git remote prune origin
正如@tzacks所提到的...有一个npm软件包很方便。做就是了:
npx git-removed-branches --prune
(我会发表评论,但声誉不足)
如果使用Windows和Powershell,则可以使用以下命令删除已合并到当前检出的分支中的所有本地分支:
git branch --merged | ? {$_[0] -ne '*'} | % {$_.trim()} | % {git branch -d $_}
说明
git
为其余的每个分支名称清除输出中的任何前导或尾随空格值得git branch --merged
首先单独运行,以确保它只会删除您期望的内容。
更短更安全的单线:
git branch -d $(git branch --merged | cut -c 3- | grep -v master)
在运行它之前,请确保签出到尚未合并的分支。因为您无法删除当前已签入的分支。
git branch -d $(git branch --merged | cut -c 3- | grep -v master)
我想要一种能够清除所有正在跟踪远程分支的本地分支的方法,该分支位于origin
已删除(gone
)的远程分支上。我不想删除从未设置为跟踪远程分支的本地分支(即:我的本地dev分支)。另外,我想要一个简单的单行代码,仅使用git
或其他简单的CLI工具,而不是编写自定义脚本。我最终使用了grep
和awk
来制作这个简单的命令,然后将其作为别名添加到~/.gitconfig
。
[alias]
prune-branches = !git remote prune origin && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs -r git branch -D
这是一个git config --global ...
可以轻松将其添加为的命令git prune-branches
:
git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print $1}'"'"' | xargs -r git branch -d'
注意:使用-D
标志git branch
可能非常危险。因此,在上面的config命令中,我使用-d
选项git branch
而不是-D
; 我-D
在实际配置中使用。我-D
之所以使用,是因为我不想听到Git抱怨合并的分支,我只是希望它们消失。您可能还需要此功能。如果是这样,只需在config命令的末尾使用-D
而不是即可-d
。
删除远程分支:
$git remote prune origin
要删除已经合并的本地分支:
$git branch -D $(git branch --merged)
不知道如何一次完成所有操作,但是git git branch -d <branchname>
仅在完全合并后才删除本地分支。注意小写字母d。
git branch -D <branchname>
(请注意,大写字母D)将删除本地分支机构,无论其合并状态如何。
您可以使用以下命令:
git branch --merged master | grep -v "\* master" | xargs -n 1 git branch -d
Git Clean:删除已合并的分支,包括分解命令
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}'
b。删除分支:
comm -23 <( git branch | grep -v "/" | grep -v "*" | sort ) <( git br -r | awk -F '/' '{print $2}' | sort ) | xargs git branch -D
以下是Windows用户对@wisbucky答案的改编:
for /f "tokens=1" %i in ('git branch -vv ^| findstr ": gone]"') DO git branch %i -d
我使用posh-git,不幸的是PS不喜欢for
裸机,所以我创建了一个简单的'ol命令脚本,名为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”调用未完全合并但仍要删除的任何分支。
:
或:
(带空格)findstr
每次都与所有内容匹配-我几乎删除了master。但是,使用正则表达式效果很好:git branch -vv ^| findstr /R " \[origin/[0-9]+: gone\] "
我已将接受的答案转换为可靠的脚本。您可以在我的git-extensions存储库中找到它。
$ 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>
我到达此页面,寻求“如何删除不再具有上游分支的本地检出分支”的答案
我也不在乎本地分支是否已经合并,因为管道git branch -d
将简单地发出警告,而不是删除未合并的本地分支。
git branch -a | grep origin | tr -s ' ' | cut -d '/' -f3 | egrep -v -f /dev/fd/0 <(git branch -a | grep -v origin) | grep branch_prefix_that_I_care_about | xargs git branch -d
# translation
# git branch -a | grep origin | tr -s ' ' | cut -d '/' -f3
## this finds all remote branch names minus the "remote/origin/" part
#
# <(git branch -a | grep -v origin)
## this finds all local branch names and redirects it into the previous command
#
# egrep -v -f /dev/fd/0 STUFF
## this is doing some weird magic that I'm grokking as "take the set difference from whatever was piped in"
#
#
# overall translation: (STUFF TO CONSIDER) | egrep magic <(STUFF TO REMOVE FROM CONSIDERATION) | do cool things with resulting stuff
在Powershell中:
git branch -D (git branch --merged |% { $_.trim() } )
这是我的解决方案:
git fetch -p
git branch -vv | grep ": gone" | awk '{print $1}' | xargs git branch -d
-p将删除远程上不再存在的任何远程跟踪引用。因此,第一步将删除对远程分支的引用。
-vv用于显示每个头的sha1和commit主题行,以及与上游分支的关系(如果有)。第二步将获取所有本地分支,而grep命令将筛选出已删除的分支。
删除所有与master无关的分支
git co master && git branch | sed s/\*/\ / | xargs git branch -d 2> /dev/null
我很确定那git remote prune origin
是您想要的。
您可以将其运行git remote prune origin --dry-run
以查看它会做什么而无需进行任何更改。
使用GUI?手动操作,但又快速又容易。
$ git gui
选择“分支->删除”。您可以通过按住Ctrl键单击(窗口)选择多个分支并将其全部删除。