在 Git 存储库中,如何有效地删除已删除远程分支的本地跟踪分支?

时间:2021-05-05 11:39:46

标签: git

在 Git 存储库中,如何有效地删除已删除远程分支的本地跟踪分支?

如果我创建一个 Github 存储库,然后在 master 之外创建一个功能分支,那么 Git cli 会显示这一点

user@workstation C:\Home\Development\Workspaces\Scratch\GitTest1      
$ git branch -vv                                                            
* feature1 e1f5c4e [origin/feature1] Stuff added on branch feature1         
  master   d7a1ee8 [origin/master] Initial commit                           
                                                                            
user@workstation C:\Home\Development\Workspaces\Scratch\GitTest1      
$ git branch -a                                                             
* feature1                                                                  
  master                                                                    
  remotes/origin/feature1                                                   
  remotes/origin/master                                                     

我可以看到我的本地分支机构正在跟踪哪些远程分支机构,一切都很好。

如果我从 Github 和 fetch --prune 中删除功能分支。

user@workstation C:\Home\Development\Workspaces\Scratch\GitTest1      
$ git fetch --prune                                                         
From https://github.com/Neutrino-Sunset/git-test                            
 - [deleted]         (none)     -> origin/feature1                          

但现在 git branch -vv 仍然显示已删除的远程分支,即使 git branch -a 不再列出它。

user@workstation C:\Home\Development\Workspaces\Scratch\GitTest1      
$ git branch -vv                                                            
* feature1 e1f5c4e [origin/feature1: gone] Stuff added on branch feature1   
  master   d7a1ee8 [origin/master] Initial commit                           
                                                                            
user@workstation C:\Home\Development\Workspaces\Scratch\GitTest1      
$ git branch -a                                                             
* feature1                                                                  
  master                                                                    
  remotes/origin/master          

因此,我必须使本地存储库与远程存储库保持同步的唯一方法是在一个控制台中运行 git branch -vv,在另一个控制台中运行 git branch -a。然后手动比较我的哪些本地分支说他们正在跟踪远程分支实际上正在跟踪一个甚至不存在的分支,然后在第三个控制台中手动删除无关的分支。

对于大型存储库来说,这非常麻烦,而且很容易出错。

Git 真的没有提供更智能的方法来做到这一点吗?

1 个答案:

答案 0 :(得分:1)

我同意 torek's comment 并想详细说明为什么

从概念上讲,让我们从一个更笼统的问题开始:

<块引用>

在 Git 存储库中,如何有效地删除我不知道的本地分支 不再需要?

因为每个人的工作流程可能不同,所以没有一个很好的包罗万象的方法来确定您不再需要哪些分支。 Git 支持的标准答案是:

  1. 如果一个分支完全合并到另一个分支(通常是永久共享分支,例如 mainmasterdevelop),则您不再需要它。这是因为该分支上没有尚未存储在其他地方的信息(除了分支名称)。如果您决定再次需要它,您可以在以后重新创建分支。

当我说 Git 支持删除完全合并的分支时,我的意思是当您删除一个分支时,您可以指定 -d 来执行删除,如果该分支完全合并(到您当前签出的分支或其他指定分支),或者您可以使用 -D 删除分支。

您可能不再需要分支的其他原因不符合 #1 中的条件,其中一些可能是:

  1. 用于测试或玩耍的废弃树枝。
  2. 被拒绝且永远不会使用的潜在代码。 (例如,如果您在不同的分支名称上尝试了 3 种不同的方式,并继续使用最佳实现。如果您确定自己的选择,那么现在可以删除其他 2 个分支,并且可以删除“好”分支一次它已完全合并。)
  3. 具有 代码 的分支完全合并,但由于变基或修改而具有不同的提交 ID。如果您的 PR 工具有一个名为“半线性合并”(Azure DevOps)或“Rebase、merge”(Bitbucket)的选项,这可能会发生这种情况,这可能会在 PR 完成时动态更改提交 ID,这意味着您的本地分支将具有不同的身份证。另一种可能发生的情况是,如果其他人在您的分支上重新定位或修改了提交,也许是在完成您的 PR 之前进行小幅调整。 (当我的同事要求我 PR 他们的东西并将 PR 设置为自动完成时,我经常这样做。如果我看到一些小问题,我可能会在 PR 中对其进行评论,但随后只需为他们修复它,强制推送出来然后批准它。现在他们在删除他们的分支时肯定需要使用 -D 而不是 -d。)

现在回答您的具体问题(转述):

<块引用>

在 Git 存储库中,如何有效地删除已删除远程分支的本地分支?

一种明显的方法是使用您建议的方法,但旁边带有“gone”一词。这应该会捕获您可以在 #1 和 #4 中删除的大多数分支,但它仍然不完美。它没有捕捉到您向本地分支添加提交并在 PR 完成之前忘记将其推送的情况!如果您不担心这种可能性,那么您的方法应该有效,并且可能可以自动化。 (有关一些想法,请参阅 VonC's answer。)

如果您不想冒险删除从未推送的分支上的额外提交,那么 Git 支持的一件事就是您确定是安全的一件事,即删除完全合并的分支。因此,考虑到这一点,您可以安全地遍历每个本地分支,对永久分支(例如 -ddevelop)使用 main 参数,并在晚上睡个好觉。这样做的问题是您可能仍然有更多的分支可以删除。

如果你有一个即时变基的工作流程,那么你也可以使用这个算法:

  1. 选择要比较的分支(您的大部分 PR 会去哪里,例如 main
  2. 对于每个本地分支 X
  3. T 创建临时分支 X
  4. T 变基到 main
  5. 差异 Tmain。如果它们相同,您可以删除分支 X

现在对于其余的分支,您只需手动查看它们。我建议每天列出几次您当地的分支机构,并一直清除它们,因为您会知道最近完成了哪些 PR。如果等待时间太长,它会变得混乱。 (有点像电子邮件收件箱,或者更类似的是电子邮件草稿文件夹。我想我有 50 多个草稿,可能有 1 或 2 个我出于某种原因不想删除,因此它们全部会留下来,直到我花时间清除它们。)