git 删除不在远程的分支

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16590160/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 08:32:20  来源:igfitidea点击:

remove branches not on remote

gitgit-branch

提问by Dozer

==> git branch -a
* master
  test
  remotes/origin/master
  remotes/origin/test

when someone delete the remotes/origin/test,I still can see it on my computer.

当有人删除它时remotes/origin/test,我仍然可以在我的电脑上看到它。

I know I can do this and remove the test

我知道我可以做到这一点并删除 test

==> git remote prune
==> git branch -d test
==> git branch -a
* master
  remotes/origin/master

But if I have more local branch, and they are not on remote, so how can I remove them quickly?

但是如果我有更多的本地分支,而且它们不在远程,那么我该如何快速删除它们呢?

回答by eck

This is how I remove local branches that are not longer relevant:

这就是我删除不再相关的本地分支的方式:

git branch --merged origin/master | xargs git branch -d

You may need to tweak it according to your specific configuration (e.g. see comments below to exclude particular branches), but the first command here before the pipe should give you a list of all your local branches that have been merged into your master branch.

您可能需要根据您的特定配置对其进行调整(例如,请参阅下面的注释以排除特定分支),但是管道之前的第一个命令应该为您提供已合并到主分支的所有本地分支的列表。

回答by twalberg

According to the git-fetchmanual page, git fetch -pwill "After fetching, remove any remote-tracking branches which no longer exist on the remote.` If you have local branches tracking those remote branches, you may need to prune those manually.

根据git-fetch手册页,git fetch -p将“在获取后,删除远程上不再存在的任何远程跟踪分支。`如果您有本地分支跟踪这些远程分支,则可能需要手动修剪它们。

回答by kcm

A simple prune will not delete the local branch.

简单的修剪不会删除本地分支。

Here is another approach to achieve a real deletion. Be sure to execute "git fetch -p" first to get the latest status of the remote repositories.

这是实现真正删除的另一种方法。请务必先执行“git fetch -p”以获取远程存储库的最新状态。

git branch -vv | grep ': gone]'|  grep -v "\*" | awk '{ print ; }' | xargs -r git branch -d

This will check all local branches and their origin and will delete all local branches whose origin was deleted.

这将检查所有本地分支及其来源,并将删除其来源已被删除的所有本地分支。

In detail:

详细:

git branch -vv

will list your local branches and show information about the remote branch, saying “gone” if it is not present anymore.

将列出您的本地分支并显示有关远程分支的信息,如果它不再存在,则说“消失”。

grep ': gone]'

will fetch the branches that match the “ gone]” phrase.

将获取匹配“goed]”短语的分支。

grep -v "\*"

will fetch only lines that do not contain an asterisk. This will ignore the branch you are currently on and also prevent that the “git branch -d” is executed with a “*” at the end which would result in deleting all your local branches

将只获取不包含星号的行。这将忽略您当前所在的分支,并防止“git branch -d”在末尾使用“*”执行,这将导致删除所有本地分支

awk '{print }'

will fetch the output until the first white space, which will result in the local branch name.

将获取输出直到第一个空格,这将导致本地分支名称。

xargs git branch -d

will use the output (branch name) and append it to the “git branch -d” command to finally delete the branch. If you also want to delete branches that are not fully merged, you can use a capital “D” instead of “d” to force delete.

将使用输出(分支名称)并将其附加到“git branch -d”命令以最终删除分支。如果您还想删除未完全合并的分支,您可以使用大写的“D”代替“d”来强制删除。

回答by trustin

I wrote a simple shell script called git-dangling-branchesfor this purpose. If you specify -Doption, it will delete all local branches which don't have refs/remotes/origin/<branch_name>. Of course, you should be careful when you do that.

为此,我编写了一个简单的 shell 脚本git-dangling-branches。如果您指定-D选项,它将删除所有没有refs/remotes/origin/<branch_name>. 当然,这样做时你应该小心。

#!/bin/bash -e
if [[ "" == '-D' ]]; then
  DELETE=1
else
  DELETE=0
fi

REMOTE_BRANCHES="`mktemp`"
LOCAL_BRANCHES="`mktemp`"
DANGLING_BRANCHES="`mktemp`"
git for-each-ref --format="%(refname)" refs/remotes/origin/ | \
  sed 's#^refs/remotes/origin/##' > "$REMOTE_BRANCHES"
git for-each-ref --format="%(refname)" refs/heads/ | \
  sed 's#^refs/heads/##' > "$LOCAL_BRANCHES"
grep -vxF -f "$REMOTE_BRANCHES" "$LOCAL_BRANCHES" | \
  sort -V > "$DANGLING_BRANCHES"
rm -f "$REMOTE_BRANCHES" "$LOCAL_BRANCHES"

if [[ $DELETE -ne 0 ]]; then
  cat "$DANGLING_BRANCHES" | while read -r B; do
    git branch -D "$B"
  done
else
  cat "$DANGLING_BRANCHES"
fi
rm -f "$DANGLING_BRANCHES"

回答by Karl Wilbur

I ended up with something very similar to kcm's approach. I wanted something that would purge all local branches that were tracking a remote branch, on origin, where the remote branch has been deleted (gone). I did not want to delete local branches that were never set up to track a remote branch (i.e.: my local dev branches). Also I wanted a simple one-liner that just uses git, or other simple CLI tools, rather than writing custom scripts. I ended up using a bit of grepand awkto make this simple command then added it as a alias in my ~/.gitconfig.

我最终得到了与kcm的方法非常相似的东西。我想要一些可以清除所有跟踪远程分支的本地分支的东西origin,在远程分支已被删除 ( gone) 的地方。我不想删除从未设置为跟踪远程分支的本地分支(即:我的本地开发分支)。此外,我想要一个简单的单行程序,它只使用git或其他简单的 CLI 工具,而不是编写自定义脚本。我最终使用了一些grepawk来制作这个简单的命令,然后将它作为别名添加到我的~/.gitconfig.

[alias]
  prune-branches = !git remote prune origin && git branch -vv | grep ': gone]' | awk '{print }' | xargs -r git branch -D

Here is a git config --global ...command for easily adding this as git prune-branches:

这是一个git config --global ...可以轻松将其添加为的命令git prune-branches

git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print }'"'"' | xargs -r git branch -d'

NOTE: As Matteopointed out in his earlier comment on another answer, use of the -Dflag to git branchcan be very dangerous. So, in the config command I use the -doption to git branchrather than -D; I use -Din my actual config. I use -Dbecause I don't want to hear Git complain about unmerged branches, I just want them to go away. You may want this functionality as well. If so, simply use -Dinstead of -dat the end of that config command.

注意:正如Matteo在他之前对另一个答案的评论中指出的那样,使用-D标志 togit branch可能非常危险。因此,在 config 命令中,我使用-d选项 togit branch而不是-D; 我-D在我的实际配置中使用。我使用-D是因为我不想听到 Git 抱怨未合并的分支,我只想让它们消失。您可能也需要此功能。如果是这样,只需在该配置命令的末尾使用-D而不是-d

回答by Laksitha Ranasingha

You can do this by iterating over the refs, I used following command to remove all the local branches which dont have remote branches and it worked. Warning: this operation does a force delete non fully merged branches, use with care.

您可以通过迭代引用来做到这一点,我使用以下命令删除所有没有远程分支的本地分支并且它工作正常。警告:此操作会强制删除未完全合并的分支,请谨慎使用。

git branch -D `git for-each-ref --format="%(fieldName)" refs/heads/<branch-name-pattern>`

%(fieldName) = refname:short)

%(fieldName) = refname:short)

refs/heads/= can be suffixed if you have a common prefix/suffix in branch names ex: refs/heads/*abc*

refs/heads/如果您在分支名称中有一个共同的前缀/后缀,则可以添加后缀,例如: refs/heads/*abc*

Refer this for more information git-for-each-ref(1) Manual Page

有关更多信息,请参阅git-for-each-ref(1) 手册页

回答by Pando85

First, do:

首先,做:

git fetch && git remote prune origin

git fetch && git remote prune origin

And then:

进而:

git branch -a | grep -v ${$(git branch -a | grep remotes | cut -d/" -f3-)/#/-e} | xargs git branch -D

git branch -a | grep -v ${$(git branch -a | grep remotes | cut -d/" -f3-)/#/-e} | xargs git branch -D

  • List all remotes without remote/origin prefix: git branch -a | grep remotes | cut -d'/' -f3-
  • Remove all listed from git: git branch -a | grep v ${<all remotes without prefix>/#/-e}
  • Remove from local needs -Dcause not all have to be marked as merged. For example, squash and merge in Github does not mark them as merged.
  • 列出所有没有 remote/origin 前缀的遥控器: git branch -a | grep remotes | cut -d'/' -f3-
  • 从 git 中删除所有列出的内容: git branch -a | grep v ${<all remotes without prefix>/#/-e}
  • 从本地需求中删除,-D因为并非所有都必须标记为已合并。例如,Github 中的压缩和合并不会将它们标记为已合并。