如何防止Phabricator吞噬我的提交历史记录

35

以下是令我十分烦恼的情况。

Jack在一家名为foobar的软件公司工作,他是一位工作程序员,他热爱编码并频繁提交代码。他的经理Paul告诉他,公司将开始使用一个新的代码审查工具phabricator,Jack遵从了指示,创建了一个本地分支并开始工作。他不断添加功能,并频繁提交到本地分支。最后在一天结束时,他向phabricator发送了一份请求。

arc diff development

杰克的团队成员约翰审查了他的代码并接受了他的更改。 现在,杰克打开终端并移动到他的存储库目录。 杰克键入以下命令来关闭修订版本并将他的代码与开发分支合并。

arc land --onto development
他看到了以下信息。
Landing current branch 'feature-awesome-features'.
Switched to branch development. Updating branch...
The following commit(s) will be landed:

b2ff76e  Added the foo to bar
33f33ba  Added a really important check which can destroy the project or save it
31a4c9a Added that new awesome feature
8cae3bf rewrote that awful code john wrote
bc54afb  bug fixes

Switched to branch feature-awesome-features. Identifying and merging...
Landing revision 'D1067: Added the awesome feature'...
Rebasing feature-awesome-features onto development
Already up-to-date.
Pushing change...

现在杰克打开 Github 查看他的代码,他漂亮的提交记录,但是他看到的是纯粹的恐惧,所有的提交都被单一的提交所替换,基本上说的是这样的:

Summary: Added the awesome feature

Test Plan:  do foo bar testing

Reviewers: John

Reviewed By: John

CC: Paul

Differential Revision: http://phabricator.foobar.com/D1067

现在Jack很难过,因为他想要查看他的所有提交记录,他认为这个提交记录让他看起来像囤货者,但他其实不是这样的人。他想要解决这个问题,所以他去Stack Overflow上提问。

That how may he prevent phabricator from eating his commit history.

如果每个人的合并看起来都是这样,你为什么认为你会被单独挑出来呢?无论如何,解决方法是拥有更多的小分支。特别是,在功能分支上不要提交不相关的更改。 - tripleee
7个回答

20

asherkin的回答解释了这种行为的基础以及为什么这是默认设置。

如果你不认为这个论点有说服力,你可以使用--merge标志执行--no-ff合并而不是--squash合并。这些合并不会破坏本地提交。

如果在你的.arcconfig中将history.immutable设置为true,则arc land默认将使用--no-ff合并。

如果您不喜欢arc land的行为,也可以使用原始的git命令;它只是为方便提供的。

在你的例子中,我们建议创建五个独立的评审 - 实现多个不同的想法,它们不相关且易于分离。请参阅编写可评审代码。将错误修复、样式更改和新功能合并到一个更改中就是hoarding。


4
当我写代码时,通常有一个单一任务需要完成,我会将它分解为更小的任务,以保持代码库的正确性,确保每个任务至少做一件事情,但不必在一个提交中显著地改变功能。我期望提交集的接受是原子性的,但破坏了“一项想法=一个提交”的规则,这不是Git开发者自己使用的方式。对于典型的补丁序列来说,五个单独的审查意味着它们是相互可交换的五个分支,但实际上并非如此。 - alternative

10

你应该直接使用本地的git流程,例如git mergegit push。来自Phabricator Arc文档:

在更改被接受后,通常会将它们推送并关闭 修订。arc具有几种工作流程可以帮助完成这个过程,包括:

* squashing or merging changes from a feature branch into a master branch
* formatting a good commit message with all the information from Differential
* and automatically closing the revision.

您不需要使用任何这些工作流程:您只需要运行git push, hg push或者svn commit,然后从网页手动关闭修订。

arc有意压缩您的提交。


5
因为文档很烦人,对吧?这样一个巨大的失误竟然能进入生产代码中令人深感担忧。有人可能会说,“那我们就坚持使用普通的 Git 风格的 pull 请求好了。”但是,使用 Phabricator 就做不到。虽然有一个模块正在开发中,但它仍处于测试版。Git 的“早提交、经常提交”的格言也就无从谈起了…… - Kafoso

4

history.immutable: 配置arc使用工作流程,从不在工作副本中重写历史记录。默认情况下,arc将在Git的某些工作流程中对未发布的历史记录进行一些重写(修改提交消息,压缩合并)。这些区别在下面详细介绍。

因此,只需在您的.arcconfig文件中添加一行即可。

"history.immutable": true

3
一些文档解释了为什么这是arc land的默认设置。
当您的存储库达到临界速度时,将一个想法拆分成一个提交与其他策略相比并没有真正的优势。特别地:
- 几乎所有针对主/远程存储库的操作都是关于想法而不是提交的。当一个想法由多个提交组成时,您需要弄清楚哪些提交代表一个想法(“foo小部件出了问题,我需要回滚哪些提交?”),或者哪个提交最终代表一个想法(“提交af3291029毫无意义,这个更改试图实现什么目标?”)。 - 发布工程变得非常简单。当每个想法对应一个提交时,发布工程师可以轻松选择或删除想法。当一个想法由多个提交组成时,很容易意外地选择或删除半个想法,并最终处于几乎肯定错误的状态。 - 自动化测试变得非常简单。如果每个想法都是一个提交,您可以对每个提交运行自动化测试,测试失败会指示一个严重的问题。如果每个想法由多个提交组成,则大多数提交代表代码库的已知错误状态(例如,具有语法错误的检查点,该错误在下一个检查点中修复,或者半实现的想法)。 - 理解更改变得非常简单。您可以对断点进行二分,并轻松地识别整个想法,而无需在日志中向前和向后搜索以确定想法的范围。并且您可以确信需要回滚哪些内容才能完全删除整个想法。 - 没有清晰的价值可以让检查点提交(其中一些保证是存储库的已知错误版本)持续存在远程。考虑一个理论上的VCS,它会自动为每个击键创建一个检查点提交。这个VCS显然是不可用的。但是,许多检查点提交并没有太大区别,并且在概念上代表了写入较大想法所需的击键序列中相对任意的一点。要么摆脱它们,要么创建一个抽象层(合并提交),允许您在尝试根据想法理解存储库时忽略它们(这几乎总是这样)。
所有这些问题只有在规模上成为问题时才会出现。Facebook每天推出数十个想法,每周推出数千个想法,如果没有选择一个想法是一个提交的存储库策略,就无法做到这一点(至少不需要更多的人员或更多的错误)。
对于git,推荐的解决方案是将功能分支推送到上游,然后合并而不是rebase到主分支 - 如果您同意上述观点但仍希望将检查点提交推送到上游。
如果这仅用于审核期间(如您的问题所述 - 但它听起来像您没有进行任何代码审核或仅进行了后推代码审核),请注意Differential将已显示所有本地提交以供审阅者查看原始提交消息。

arc land 的设计目的是仅用于推送到存储库的“最终”分支(即生产或某个代表等待发布更改的分支)。如果您正在进行提交后审核(即从开发到主分支的合并),则可以直接绕过 arc land 进行操作(在许多情况下,这是被广泛接受的),并直接使用git push 推送您的更改。


5
压缩提交是“每次提交一个想法”的相反,它形成了无法轻易还原、传递或讨论的“巨型提交”。这会严重影响git bisect和git blame。如果您想将多个提交收集到单个合并点,请使用正确的分支。 - Alexander Ljungberg
1
你所说的一切都意味着你把太多东西压缩在一起了。压缩检查点提交绝对不是“每次提交一个想法”的相反面。如果您想要更多上下文,请阅读链接的来源。 - asherkin
1
好的,我现在明白了,链接的文章将“一个想法”定义为我会描述为“许多想法”的方式。我坚持认为:一个提交应该是一个具体、易于描述且目的明确的变更。一系列的提交可以是更大计划的一部分,即“特性”,这就是一个分支。 - Alexander Ljungberg
1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - alternative

1
在最近更新的arcanist中,对于这个问题的现代答案是使用新的strategy语法来防止压缩。 arc land Dxyz --strategy merge 旧的--merge--squash语法已被--strategy替换。
(有关背景信息,请参见:https://secure.phabricator.com/T13547

0

--merge 不起作用,因为它会创建一个合并提交。 我已经修补了我的代码,加入了一个 --rebase 选项,可以做正确的事情,但我不确定 arc 的开发人员是否愿意接受这个修改。


0
这是我的做法。它不能防止提交历史被压缩,但允许你将后续功能重新基于丢失的分支进行变基。 < p > $ arc land --revision <feature1>

< p > $ git branch -u master <feature2>

< p > $ arc cascade

arc cascade 将重新基于 feature1 所有从 feature1 衍生出的特性分支。

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