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

明天,有人报告了一个大漏洞,我们决定立即进行热修复。因此,我们为“master”创建了一个修复分支,我们将其命名为“2011_Hotfix”,并将其推高,以便所有开发人员可以协作修复它。

我们修复了这个错误,并将“2011_Hotfix”合并到“master”以及当前的开发分支中。然后按“主键”。

我们现在对“2011_Hotfix”做什么?它是应该永远作为一个分支存在,直到时间的尽头,还是我们现在应该删除它,因为它已经达到了它的目的?让分支到处乱放似乎是不干净的,因为分支列表可能会变得很长,其中大多数甚至不再需要了。

如果它被删除,它的历史会发生什么?即使实际的分支不再可用,它也会得到维护吗?另外,如何删除远程分支?


你可以使用git branch -d yourbranch安全地删除一个分支。如果它包含未合并的更改(例如,删除分支会丢失提交),git会告诉你,不会删除它。

因此,删除一个合并的分支成本很低,而且不会丢失任何历史记录。

要删除一个远程分支,使用git push origin:mybranch,假设你的远程名称是origin,你要删除的远程分支名为mybranch。

如果它被成功地合并回来,甚至可能被标记,那么我会说它已经没有任何用处了。你可以安全地执行git branch -d branchname。

你需要做的是标记你释放的任何东西。在你积极开发的时候保留分支。

删除旧的分支

git branch -d branch_name

将它们从服务器中删除

git push origin --delete branch_name

或者旧的语法

git push origin :branch_name

它读起来是“在原点上将任何东西推入branch_name”。

也就是说,只要DAG(有向无环图)可以指向它,提交就会在历史记录中出现。

谷歌的“git-flow”,这可能会提供更多关于发布管理、分支和标签的见解。

由于问题有“github”标签,我还会添加这个:特别是在github中,如果你拉请求一个分支,它被合并(无论是通过UI还是合并拉请求的分支),你不会失去拉请求数据(包括评论),即使你删除了分支。

这样做的结果是:如果您将拉取请求作为工作流的一部分(它与代码审查巧妙地混合在一起),那么只要合并分支,您就可以安全地删除它们。这是如此普遍,最近Github增加了一个(甜蜜的)功能,弹出一个“删除分支”按钮后,你合并一个拉请求。

但是值得注意的是,每个组都应该采用最适合自己的工作流(它可能导致也可能不会导致删除这些分支)。例如,我目前的工作团队,只要他们的pull请求被合并,就会删除所有与主节点或部署无关的分支(例如,生产、staging等),并且我们仍然可以完全跟踪相关的提交如何形成每个产品的每次增量改进。

Of course no history management (pull requests or otherwise) replaces proper tagging of versions (which you preferably automate with the same tool/script that deploys/packages a version), so you can always fast-switch to whatever your users happen to be on at a given moment. Tagging is also the key to solve your original problem: if you establish that any branch merged to the "work" branches can and should be deleted, and that any one that is merged to a version tag, "production", etc. should not, you'll always have the hotfixes alive until they are integrated in a future version.

我想补充的是,删除分支的缺点是你会破坏到GitHub上那些分支的任何超链接(这个问题被标记为GitHub)。对于这些链接,您将看到404 Not Found错误。这就是为什么我在GitHub上删除一个分支后,将我的链接改为指向一个提交或标记。

因为有些链接是无法更改的,比如在电子邮件中,我现在完全避免超链接到GitHub分支,而是从第一天开始链接到提交或标记。

我更喜欢在合并分支之后删除它们。这可以防止在存储库中出现一长串分支的视觉混乱。这些分支还会传播到存储库的所有分支。

首先我删除我的本地分支。这可以防止以后被意外地推。

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

似乎您希望在不丢失其历史记录的情况下删除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的提交历史中。简而言之,简单的合并不会丢失历史记录。

I have one more word to add that is perhaps beyond the scope of your question, but is relevant nonetheless. Let's imagine that there are 20 tiny, "work-in-progress" commits on 2011_Hotfix; however, you want only one complete commit for 2011_Hotfix to be added to master's history. How do you combine all 20 small commits into one big commit? Fortunately, git allows you to consolidate multiple commits into one commit by using git-rebase. I won't explain here how that works; though, if you're interested, the documentation for git-rebase is excellent. Do note that git rebase rewrites history, so it should be used judiciously, especially if you are new to it. Finally, your 2011_Hotfix scenario is about a dev team, not a solo dev. If project team members use git rebase, it is wise for the team to have explicit guidelines on the use of git rebase in order that some cowboy dev on the team doesn't unwittingly damage a project's git's history.

你可以删除分支在所有主要的web ui,如github, BitBucket。在线删除分支后,可以使用

git remote prune origin

如果你想修剪已经从原点删除的本地分支,你也可以使用git fetch进行修剪

git fetch --prune