何时应该在Git中删除分支?

328

假设我们有一个稳定的应用程序。

明天,有人报告了一个大问题,我们决定立即进行热修复。于是我们在“master”分支上创建一个名为“2011_Hotfix”的分支,然后将其推送上去,这样所有开发人员都可以协作修复它。

我们修复了这个bug,并将“2011_Hotfix”合并到“master”以及当前的开发分支中。然后推送“master”。

现在我们该怎么处理“2011_Hotfix”?它应该永远保留作为一个分支,直到世界末日还是现在就删除它,因为它已经完成了它的使命?将分支随意留下来似乎不干净,因为分支列表可能变得很长,而大多数分支甚至已经不再需要。

如果应该删除它,那么它的历史记录会怎样呢?即使实际分支不再可用,它的历史记录是否会被保留?此外,我如何删除远程分支?


40
将分支视为想法通常会有所帮助。一个相当不错的经验法则是,如果您已经完成了与该分支代表的想法相关的工作,包括完成测试并将更改(将它们合并到主分支)纳入其中,那么您就完成了该分支。 - Cascabel
3
我想知道的是:如果远程热修复被移除了,那么所有合作开发人员的本地是否也会被移除?如果不会,应该如何做到?我认为一个人将热修复迁移到主分支,然后应该清理所有合作者的本地代码,以防止他们往该分支添加提交。 - rolandow
1
你不能影响同事电脑上的本地代码库。你要么告诉他在本地删除分支,要么可以通过git钩子/分支安全性在服务器端强制执行此操作,以防止从你想要保留删除的分支进行推送。 - srz2
8个回答

207

你可以使用命令 git branch -d yourbranch 安全地删除一个分支。如果该分支包含未合并的更改(即,删除分支将使您失去提交),Git 将告诉您并且不会删除它。

因此,删除已合并的分支是简单且不会使您失去任何历史记录。

要删除远程分支,请使用 git push origin :mybranch 命令,假设您的远程名称是 origin,要删除的远程分支名为 mybranch。


44
“删除已合并的分支很容易”,但是保留它也同样便宜。如果保留分支,Git使用的时间和空间不会有明显的性能损失。尽管如此,我还是会删除该分支,因为所有提交记录已经在“主”分支的历史记录中了,所以删除分支会使事情更加清晰整洁。 - Tyler
26
我希望你能为我翻译一下:我希望删除分支的原因之一是:我们在分支中进行了很多更改(实际上,所有更改都是在分支中完成的),所以最终使用“git branch”命令时会得到一个很长的列表。为了简化概述,我希望缩短该列表。因此,旧的分支将被删除。真正发布的内容已经被标记,对我来说不需要讨论。 - michel.iamit
10
我同意删除已经合并的分支,但如果你想查看尚未合并到当前分支的分支列表,可以使用以下命令:git branch --no-merged - lsklyut
70
@MatrixFrog 从git的角度来看,保留这些分支很便宜,但是在人力成本方面可能会变得昂贵。我最近加入了一个有大约40个分支的项目,所有分支都有数字名称。我不知道哪个是哪个,几乎每一个分支都已经过期了。搜索这些分支并弄清楚哪个是哪个的开销很大,需要耗费时间和精力。所以,从技术上讲,保留这些分支很便宜,但实际上并不是这样。我喜欢让我的git repo保持整洁有序。如果没有在进行活动性开发,并且已经合并进主干中,就把它删掉。但这只是我的做法,我尊重其他人可能会采取不同的做法。 - dudewad
1
如何将 --no-merged 命令设置为默认值?我尝试了 git config --global --add branch.noMerged true,它被添加了,但没有任何变化。 - Craig Silver
1
@CraigSilver 的一个选项:git config --global alias.unmerged 'branch --no-merged' - user151841

64
你需要做的是为你发布的任何内容打标签。在活跃开发时保留分支。使用以下命令删除旧分支:
git branch -d branch_name

使用以下代码从服务器上删除它们:

git push origin --delete branch_name

或者是旧的语法

git push origin :branch_name

这意味着“将无内容推送到远程的branch_name”。

话虽如此,只要有DAG(有向无环图)可以指向它,提交记录就会保存在历史记录中。

搜索“git-flow”,可能会对发布管理、分支和标记等方面提供更多的见解。


34

由于这个问题有 "github" 标签,我想补充一下:具体来说,在 Github 中,如果您 pull-request 一个分支并且它被合并(无论是通过 UI 还是通过合并 pull request 的分支),即使您删除该分支,也不会丢失 pull request 数据(包括评论)。

这样做的一个结果是:如果你将 pull requests 作为你的工作流程的一部分(与代码审查很好地结合在一起),你可以安全地在它们被合并后立即删除分支。这是如此普遍,以至于最近 Github 添加了一个(美妙的)功能,在合并 pull request 后就会弹出一个 "删除分支" 按钮。

但值得注意的是,每个团队都应该采用最适合自己的工作流程(可能会导致不需要删除这些分支)。例如,我的当前工作团队会在他们的 pull requests 被合并后立即修剪除主分支或 deployment 相关的所有分支(如生产、暂存等),我们仍然可以完整地跟踪相关提交是如何形成每个产品的增量改进的。

当然,没有任何历史管理(包括 pull requests 等)可以替代版本的适当标记(最好使用与部署/打包版本相同的工具/脚本自动化标记),以便您可以快速切换到用户当前使用的任何版本。标记也是解决您原始问题的关键:如果您确定任何合并到 "work" 分支的分支都可以和应该被删除,并且任何合并到版本标记、"production" 等的分支都不应该被删除,那么你将始终拥有这些热修复内容直到它们被集成到未来版本中。


2
感谢您解释为什么Github向我展示了一个“删除分支”按钮。 - Todd Owen
我们正在使用 Sourcetree,它提供了保持本地 hotfix 分支和远程 hotfix 分支开放的选项。我曾经认为关闭 hotfix 分支意味着删除该分支并且无法重复使用。例如:我们需要在接下来的5天每天推出 hotfix。然后我们关闭它。但是,假设第6天我们需要另一个 hotfix,那么我们需要创建新的 hotfix 分支吗? - Danger14
这是人们通常做的事情。如果单独为它们命名不可行,您可以根据日期或管理它们的票务系统的参考命名它们。当然,Git 工作流应该基于“最适合您的团队”的原则进行应用,因此如果您决定采用不同的工作方式,请不要担心。 - chesterbr

9
我要补充的是,删除分支的缺点在于您将打破 GitHub 上指向这些分支的任何超链接(这个问题标记为 github)。 那些链接会出现“404 Not Found”错误。 这就是我在删除 GitHub 上的分支后更改我的链接指向提交或标记的原因。
由于有些链接无法更改(例如电子邮件),所以我现在完全避免链接到 GitHub 分支,并从一开始就链接到提交或标记。
我喜欢在合并后删除分支。 这可以防止仓库中出现长列表分支的视觉混乱。 这些分支也会传播到所有存储库的 fork 中。
首先,我会删除本地分支,这样可以防止之后误推送。
git branch -d branchName

然后我删除了远程跟踪分支

git branch -dr remoteName\branchName

然后我在GitHub上删除了分支,我使用web界面,但相应的命令如下。

git push remoteName :branchName

即使分支永远不会合并,通常我仍然希望保留提交记录以备将来查看。但是我仍然想删除该分支。为了散布这些提交记录并防止它们被垃圾回收器清除,我会创建一个注释标签,指向与已删除分支相同的提交记录。
git tag -a tagName commitOrBranchName

然后我将标签推送到GitHub。
git push remoteName tagName

垃圾回收器何时吞噬分支的提交?在删除分支之前,您需要打标签并推送标签吗? - Jared Thirsk

4

看起来你想删除 2011_Hotfix 分支,但不想丢失其历史记录。我将先讨论删除,再讨论历史记录。

通常的 git 分支删除方法已经在上面描述过了,并且它们按预期工作。 git 没有一个一两个单词的命令,可以表示“嘿 git,同时删除本地和远程分支。” 但是可以通过 shell 脚本来模仿这种行为。例如,参考 Zach Holman 的 shell 脚本 'git-nuke'。它非常简单:

#!/bin/sh
git branch -D $1
git push origin :$1

将此内容放入可执行文件中(例如git-nuke),并将其放置在其中一个$PATH目录中。如果您不在2011_Hotfix分支上,则仅运行git-nuke 2011_Hotfix将删除本地和远程分支。这比标准的git命令更快速,更简单-尽管可能更危险。
您对保留历史记录的关注是好事。在这种情况下,您不必担心。一旦将2011_Hotfix合并到master上,来自2011_Hotfix的所有提交都将添加到master的提交历史记录中。简而言之,您不会因为简单合并而失去历史记录。
我还有一个词要补充,可能超出了你的问题范围,但仍然相关。假设在2011_Hotfix上有20个微小的“工作中”提交,但是你只想将一个完整的提交添加到master的历史记录中。如何将这20个小提交合并为一个大提交?幸运的是,git允许您通过使用git-rebase将多个提交合并为一个提交。我不会在这里解释它的工作原理;但是,如果您感兴趣,关于git-rebase的文档非常好。请注意,git rebase会重写历史记录,因此应谨慎使用,特别是如果您是新手。最后,你的2011_Hotfix场景涉及开发团队,而不是单独的开发人员。如果项目团队成员使用git rebase,则明确指导团队在使用git rebase时应该具有明确的准则,以避免团队中的某个牛仔开发人员无意中损坏项目的git历史记录。

3
如果分支已经成功合并并可能已被标记,则我认为它已经无用了。所以您可以安全地执行git branch -d 分支名称

2
如果你想要修剪已经从远端删除的本地分支,可以在使用git fetch时进行修剪。
git fetch --prune

0

您可以在所有主要的Web UI(如Github、BitBucket)中删除分支。在线删除分支后,您可以使用以下命令删除本地分支:

git remote prune origin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接