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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13064613/
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-10 14:49:23  来源:igfitidea点击:

How to prune local tracking branches that do not exist on remote anymore

git

提问by Alex

With git remote prune originI can remove the local branches that are not on the remote any more.

随着git remote prune origin我可以删除不在远程的本地分支。

But I also want to remove local branches that were created from those remote branches (a check if they are unmerged would be nice).

但我也想删除从这些远程分支创建的本地分支(检查它们是否未合并会很好)。

How can I do this?

我怎样才能做到这一点?

回答by Schleis

After pruning, you can get the list of remote branches with git branch -r. The list of branches with their remote tracking branch can be retrieved with git branch -vv. So using these two lists you can find the remote tracking branches that are not in the list of remotes.

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

This line should do the trick (requires bashor zsh, won't work with standard Bourne shell):

这一行应该可以解决问题(需要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

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

This string gets the list of remote branches and passes it into egrepthrough the standard input. And filters the branches that have a remote tracking branch (using git branch -vvand filtering for those that have origin) then getting the first column of that output which will be the branch name. Finally passing all the branch names into the delete branch command.

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

Since it is using the -doption, it will not delete branches that have not been merged into the branch that you are on when you run this command.

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

Also remember that you'll need to run git fetch --prunefirst, otherwise git branch -rwill still see the remote branches.

还记得你需要运行的git fetch --prune第一,否则git branch -r仍然会看到远程分支。

回答by Hymanocnr

If you want to delete all local branches that are already merged into master, you can use the following command:

如果要删除所有已经合并到master的本地分支,可以使用以下命令:

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

More info.

更多信息

回答by twalberg

Amidst the information presented by git help fetch, there is this little item:

在 提供的信息中git help fetch,有一个小项目:

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

So, perhaps, git fetch -pis what you are looking for?

那么,也许,git fetch -p这就是你要找的吗?

EDIT: Ok, for those still debating this answer 3 years after the fact, here's a little more information on why I presented this answer...

编辑:好的,对于那些在事实发生 3 年后仍在争论这个答案的人,这里有更多关于我为什么提出这个答案的信息......

First, the OP says they want to "remove also those local branches that were created from those remote branches [that are not any more on the remote]". This is not unambiguously possible in git. Here's an example.

首先,OP 表示他们希望“还删除那些从远程分支创建的本地分支[不再在远程分支上]”。这在git. 这是一个例子。

Let's say I have a repo on a central server, and it has two branches, called Aand B. If I clone that repo to my local system, my clone will have local refs (not actual branches yet) called origin/Aand origin/B. Now let's say I do the following:

假设我在中央服务器上有一个 repo,它有两个分支,称为AB。如果我将该 repo 克隆到我的本地系统,我的克隆将具有名为origin/Aand 的本地引用(尚未实际分支)origin/B。现在假设我执行以下操作:

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

The pertinent facts here are that I for some reason chose to create a branch on my local repo that has a different name than its origin, and I also have a local branch that does not (yet) exist on the origin repo.

这里的相关事实是,我出于某种原因选择在我的本地存储库上创建一个名称与其来源不同的分支,并且我还有一个本地分支(尚未)存在于来源存储库中。

Now let's say I remove both the Aand Bbranches on the remote repo and update my local repo (git fetchof some form), which causes my local refs origin/Aand origin/Bto disappear. Now, my local repo has three branches still, A, Z, and C. None of these have a corresponding branch on the remote repo. Two of them were "created from ... remote branches", but even if I know that there used to be a branch called Bon the origin, I have no way to know that Zwas created from B, because it was renamed in the process, probably for a good reason. So, really, without some external process recording branch origin metadata, or a human who knows the history, it is impossible to tell which of the three branches, if any, the OP is targeting for removal. Without some external information that gitdoes not automatically maintain for you, git fetch -pis about as close as you can get, and any automatic method for literally attempting what the OP asked runs the risk of either deleting too many branches, or missing some that the OP would otherwise want deleted.

现在,让我们说我同时删除AB树枝上的远程回购和更新我的本地回购(git fetch某些形式的),这将导致我的本地裁判origin/Aorigin/B消失。现在,我的本地 repo 仍然有三个分支A,、Z、 和C。这些在远程仓库上都没有相应的分支。其中两个是“从......远程分支创建的”,但即使我知道曾经有一个分支B在原点上调用,我也无法知道它Z是从B,因为它在此过程中被重命名,这可能是有充分理由的。所以,实际上,如果没有一些外部进程记录分支源元数据,或者没有了解历史的人,就不可能知道 OP 的目标是删除三个分支中的哪一个(如果有的话)。如果没有一些git不会自动为您维护的外部信息,则git fetch -p几乎是您所能获得的,并且任何从字面上尝试 OP 所要求内容的自动方法都存在删除太多分支或丢失 OP 可能会丢失的一些分支的风险想删除。

There are other scenarios, as well, such as if I create three separate branches off origin/Ato test three different approaches to something, and then origin/Agoes away. Now I have three branches, which obviously can't all match name-wise, but they were created from origin/A, and so a literal interpretation of the OPs question would require removing all three. However, that may not be desirable, if you could even find a reliable way to match them...

还有其他场景,例如,如果我创建三个独立的分支origin/A来测试对某事的三种不同方法,然后origin/A就消失了。现在我有三个分支,它们显然不能全部匹配名称,但它们是从 中创建的origin/A,因此对 OPs 问题的字面解释需要删除所有三个。但是,如果您甚至可以找到一种可靠的方法来匹配它们,那可能并不理想……

回答by wisbucky

This will delete the local branches for which the remote tracking branches have been pruned. (Make sure you are on masterbranch!)

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

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


Details:

细节:

  • git branch -vvdisplays "gone" for local branches that the remote has been pruned.

    mybranch abc1234 [origin/mybranch: gone] commit comments
    
  • -dwill check if it has been merged (-Dwill delete it regardless)

    error: The branch 'mybranch' is not fully merged.
    
  • git branch -vv对于远程已被修剪的本地分支,显示“gone”。

    mybranch abc1234 [origin/mybranch: gone] commit comments
    
  • -d将检查它是否已合并(-D无论如何都会删除它)

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

回答by wedesoft

One can configure Git to automatically remove references to deleted remote branches when fetching:

可以将 Git 配置为在获取时自动删除对已删除远程分支的引用:

git config --global fetch.prune true

When calling git fetchor git pullafterwards, references to deleted remote branches get removed automatically.

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

回答by tzachs

There's a neat NPM package that does it for you (and it should work cross platform).

有一个简洁的 NPM 包可以为您完成(并且它应该跨平台工作)。

Install it with: npm install -g git-removed-branches

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

And then git removed-brancheswill show you all the stale local branches, and git removed-branches --pruneto actually delete them.

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

More info here.

更多信息在这里。

回答by chris31389

Windows Solution

视窗解决方案

For Microsoft Windows Powershell:

对于 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 | Select-String -Pattern ": gone]" | % { $_.toString().Trim().Split(" ")[0]} | % {git branch -d $_}

Explaination

说明

git checkout masterswitches to the master branch

git checkout master切换到主分支

git remote update origin --pruneprunes remote branches

git remote update origin --prune修剪远程分支

git branch -vvgets a verbose output of all branches (git reference)

git branch -vv获取所有分支的详细输出(git reference

Select-String -Pattern ": gone]"gets only the records where they have been removed from remote.

Select-String -Pattern ": gone]"仅获取已从远程删除的记录。

% { $_.toString().Split(" ")[0]}get the branch name

% { $_.toString().Split(" ")[0]}获取分支名称

% {git branch -d $_}deletes the branch

% {git branch -d $_}删除分支

回答by 027

It will list the local branches whose remote tracking branch is deleted from remote

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

$ git remote prune origin --dry-run

If you want to de-reference these local branches from local which are un tracked

如果您想从未跟踪的本地取消引用这些本地分支

$ git remote prune origin

回答by johnshew

As @tzacks notes... there is an npm package that is handy for this. Just do:

正如@tzacks 指出的那样......有一个 npm 包可以方便地做到这一点。做就是了:

npx git-removed-branches --prune

(I would have commented but not enough reputation)

(我会评论但没有足够的声誉)

回答by Gnat

If using Windows and Powershell, you can use the following to delete all local branches that have been merged into the branch currently checked out:

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

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

Explanation

解释

  • Lists the current branch and the branches that have been merged into it
  • Filters out the current branch
  • Cleans up any leading or trailing spaces from the gitoutput for each remaining branch name
  • Deletes the merged local branches
  • 列出当前分支和已经合并到其中的分支
  • 过滤掉当前分支
  • git为每个剩余的分支名称清除输出中的任何前导或尾随空格
  • 删除合并的本地分支

It's worth running git branch --mergedby itself first just to make sure it's only going to remove what you expect it to.

值得git branch --merged先单独运行,以确保它只会删除您期望的内容。

(Ported/automated from http://railsware.com/blog/2014/08/11/git-housekeeping-tutorial-clean-up-outdated-branches-in-local-and-remote-repositories/.)

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