何时删除git的功能分支是合适的?

100

我不想留下82个特性分支,所以我想知道简单合并到主分支后直接删除特性分支可能会有什么潜在的缺点。

工作流程:

git co -b feat-xyz
hack hack
git ci
hack some more
git ci
git co master
git merge feat-xyz
smoke test
git br -d feat-xyz

这里有任何问题吗?


1
我认为没有问题,因为如果你真的需要它们,你总是可以稍后恢复已删除的分支。 - slebetman
据我所知,已删除的分支无法恢复。 但是,如果在删除之前将该分支完全合并到主分支中,则不再需要该分支。 - Simeon
1
@Simeon 是的,你可以这样做。Git 永远不会删除提交记录,所以当你删除分支时,只是删除了它的名称。要恢复已删除的分支,你只需要记住最后一次提交到该分支的内容,然后可以在 git reflog 中搜索它。然后检出哈希值即可。 - slebetman
@slebetman 只有在分支最终合并后才会成立。如果提交被留下,它们最终将变得无法访问,并在一定时间后受到垃圾回收的影响。即使是 reflog 中的条目也最终会被清除,默认情况下大约有 90 天的时间。 - goldenratio
@黄金比例:有任何参考资料吗? - slebetman
@slebetman 请看这里:https://git-scm.com/docs/git-gc 配置部分的第一段注明了reflog条目在(默认情况下)90天后过期,当然可以进行配置。还要注意描述部分中提到git将修剪任何不可达的提交,但不早于2周。如果您创建一个分支,进行一些提交,然后删除该分支并且从未合并或执行其他任何操作,则这些提交将是不可达的,并最终被垃圾回收。 - goldenratio
5个回答

107

我在合并后删除分支,但我总是使用 git merge --no-ff 命令以避免快进,以便在图表上显示分支历史。我喜欢了解功能分支从开发分支中分离和再次合并的历史记录:

Merging with or without fast-forwards

这段内容摘自Vincent Driessen的《成功的Git分支模型》,这是一种非常好的Git工作流程,我在大多数项目中都会应用它。


这是另一种很好的保存历史记录的方法,因为您可以选择从功能可达但从主分支不可达的提交:rev ^ 1..rev ^ 2。缺点是它会破坏您可能想要从主分支进行的任何重新定位(例如,如果您想保持主分支重新定位到上游远程,则这是非常常见的情况)。 - masonk
1
我没有那个问题。我们的团队通过Github进行同步,我通常不需要进行rebase,但我认为这里没有什么不好的。即使您要对develop和feature分支进行rebase,分支仍然在图表上可见,重要的是feature分支相对于开发而言包含了什么,而不是您创建该分支时最初离开的提交。 - lkraider
@Ikraider,感谢你的提醒。我在刚开始学习git时就看过那篇文章,现在对我来说更有意义了。我会rebase我的特性分支,但是像你所说的,我会使用merge --no-ff回到主分支上,因为这样可以看到历史记录。 - bstpierre

69
一般情况下,在合并后删除分支是常规操作。这就是为什么 git branch -d yourbranchname 会检查分支是否完全合并后才会进行删除。
我能想到保留分支的几个原因:一是在它进入生产环境后可能会出现错误,所以你可能想将其保留;二是你可能需要一个历史记录。
无论哪种情况,您都可以选择在删除分支之前标记该分支的 head。标记与分支类似,它是指向提交的指针,但有一些小差异:
  1. porcelain 通常不会在 git show-branch 或 tab-auto 命令等探索性命令中显示标记。
  2. 检出标记会使你处于 detached HEAD 状态。
  3. 你可以留下 "tagging message",这会导致标记被保存为对象存储库中的一个对象,就像提交一样。
这样你就保留了历史记录,如果您需要进行修复,我建议从主分支上创建新的分支来进行修复。

1
检出标签会设置HEAD,但不会自动创建分支。在没有分支的提交上的HEAD是使其分离的。 - Binarian
1
你说得对,它将HEAD设置为提交ID而不是引用。我原帖中的这部分是不正确的。我应该更新它。 - masonk

12
典型的工作流程将是:
 // Create new branch
 $ git checkout -b myfeature
 // and then do some changes and commit them

 // Switch to master branch
 $ git checkout master

 // Merge myfeature to master. --no-ff will always keep branch information.
 $ git merge --no-ff myfeature

 // Delete myfeature branch
 $ git branch -d myfeature

 // Push the changes
 $ git push origin master

7

我能想到两个原因,你可能会想要保留一个功能分支一段时间:

  • 存在一种可能性,上游会将其退回给你以进行更多的工作。
  • 其他开发人员可能希望使用该功能,而不需要主分支中的其他所有内容。

实际上,大多数情况下,在合并后删除分支就可以了。


1

我认为这是典型的工作流程(合并后删除)

编辑 因此,至少对于短期分支,我认为更好的做法是将它们变基到主分支上。然后你就会得到一个线性的变更历史记录,并且整个分支都成为主干的一部分。在这种情况下,你已经拥有了所有的更改,所以显然不需要复制。


那么保留这个分支真的没有意义,对吧? - bstpierre
1
我强烈建议避免“变基(rebase)”。 变基通常是有害的,只有在某些情况下才有用。 - Dietrich Epp
9
对于本地的私有分支,变基是一个非常合理的工作流程。例如,通过变基来与上游工作保持同步是非常常见的(“向下”变基)。向上*变基则很少见,通常也是有害的。第二个答案并不是很合理,因为无论您是在变基还是合并上游更改,您仍然必须以某种方式将这些内容“推”到上游。即使在您的本地分支上,您最终也必须将功能合并到主分支上。保持对特性分支的变基的优点在于,这种合并变得快进了。 - masonk
1
在使用变基分支时需要注意一些问题,最近我就被这个问题困扰了。现在看来很明显,但是我在一个长期存在的分支上进行了数月的变基操作,每次都将整个分支与主分支进行变基。最终形成了大约600个不错的、细粒度的提交,但是主分支已经被大幅重构并多次完全更改。每次进行变基操作时,我都会将其旧提交从与它们相关的主分支提交中切断。现在,我更喜欢在需要时合并主分支。只有在分支历史记录绝对不会受到影响时,我才会进行变基操作。 - Gary Fixler

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