为什么不提交未解决的更改?


15

在传统的VCS中,我可以理解为什么您不提交未解决的文件,因为您可能会破坏构建。但是,我不明白为什么您不应该在DVCS中提交未解析的文件(其中有些实际上会阻止您提交文件)。

相反,我认为你的版本库应该从被锁定,但不承诺。

在合并过程中能够提交有几个优点(如我所见):

  • 实际的合并更改在历史记录中。
  • 如果合并很大,则可以进行定期提交。
  • 如果您犯了一个错误,那么回滚会很容易(不必重做整个合并)。
  • 在将文件标记为已解决之前,可以将其标记为未解决。这将防止推/拉。

您还可能有一变更集充当合并,而不是一个变更集。这样一来,您仍然可以使用的工具git rerere

那么,为什么要对未解决的文件进行提交以防止/阻止呢?除了传统之外,还有其他原因吗?


1
被谁皱眉或被阻止?
pdr 2012年

@pdr与我一起工作的一些开发人员对此不满意。至少在hg 1.6合并后,文件被标记为未解析。 hg不会让你提交,直到你将其标示为已解决(并不一定意味着你确实有解决这些问题,但我认为是的想法)。
爆炸药2012年

1
因此,“未解决的文件”实际上是指“未解决的合并”吗?
pdr 2012年

@pdr否,hg实际上维护已标记或未标记为“已解决”(使用hg resolve)的文件的列表。如果U此列表上有任何文件,它将不允许您提交。
爆炸药2012年

1
hg resolve专用于冲突合并;请参阅selenic.com/mercurial/hg.1.html#resolveNote that Mercurial will not let you commit files with unresolved merge conflicts. You must use hg resolve -m ... before you can commit after a conflicting merge.
Mike Partridge 2012年

Answers:


6

我能看到的最大问题是,它创建了一个提交窗口,在此窗口中,事物被半合并,并且(可能)无法正常工作。当您推送最后一组本地提交时,所有其他中间提交也都会出现。在理想的世界中,我应该能够进行任何提交,并且代码应该可以工作。如果您在合并过程中开始提交,则代码状态不明确。

您可以做的一件事是对合并进行本地提交,然后在推送时将它们捆绑为一个大提交(尽管我不确定任何vcs如何支持)。尽管这可能会产生您提到的某些好处,但我不确定是否值得增加额外的复杂性(我们已经在处理一个相当混乱和复杂的领域)。


5
我不知道我同意拉出任何提交并使之正常工作的能力..在DVCS中进行提交的很多要点是要提交您的进度,因此,在很多时候,东西肯定会被破坏或不完整。
爆炸药2012年

2
总是有工作提交有一些不错的好处。例如,如果您试图跟踪何时引入了错误,则能够遍历历史记录以查看何时发生故障(vcs甚至具有用于对历史记录进行二进制搜索的命令),这很有用。如果没有有效的提交,您将无法有效地跟踪错误。
Oleksi 2012年

1
Git支持捆绑提交。
2012年

3

我对Git最为熟悉,因此我将针对这种观点做出回答。

我看不出您任何好的VCS希望允许提交未合并文件的原因,尤其是在代码的情况下。您需要使存储库保持一致状态,并且您所建议的内容将违反提交原子性。许多VCS会物理上更改文件以显示冲突的位置-Git,SVN和CVS使用>>>> <<<<类型标记。在具有原子存储库级提交和合并的VCS中,您将创建一个节点,该节点除了您之外对任何人都没有意义。在软件开发中,您的项目无法构建。在小组的文档中,没有人知道哪些更改是正确的。

现在,Git提供了一些可以缓解这种情况的工具,这是您建议允许的提交类型。例如,您可以在推送之前将所有合并的提交压缩在一起。最后与典型的合并提交相同。

有关您的福利清单的特殊问题:

  1. 实际的合并更改在历史记录中。为什么需要更多信息?DVCS非常适合将冲突限制在有限区域内。选择要保留的变更集后,将合并提交节点的副本与先前的副本进行比较,即可得到准确的结果。
  2. 如果合并很大,则可以进行定期提交。这是一个令人担忧的问题,但您永远都不应该首先来到这里。分支机构应该不断拉动上游的变更,以免发生这种情况。rebase在某些情况下,类似的工具或一次选择一次完成也可以为您提供帮助。
  3. 如果您犯了一个错误,那么回滚会很容易(不必重做整个合并)。参见上文-您的冲突不应该变得难以处理。

该建议可行的唯一方法是,如果分支是整个合并是原子的-您可以看到一系列提交,但是它们只是更大的合并提交中的步骤,必须将其视为提交树中的一个节点。 。我认为当前没有任何VCS支持这种类型的工作流,并且我认为这是没有必要的。


冲突可能不应该变得如此难以控制,而冲突却经常(至少以我的经验)。我认为整个合并应该是原子的。这就是我的建议。可能没有必要,我只是想知道为什么还没有完成。您也不必在冲突中选择一个或另一个选项。有时是两种变化的结合。这尤其令人困惑。
爆炸药2012年

“您需要使存储库保持一致状态”。我认为那不是真的。本地存储库是工作空间,而不是神社。如果它有助于在合并过程中进行提交,请恕我直言。如果您因为不了解而这样做,我建议您不要这样做。但是,如果您是一位经验丰富的程序员,则应该做最适合自己的事情。不要拘泥于保持本地存储库的原始状态。
Bryan Oakley

1

我的主要经验是使用Mercurial,尽管我也偶尔使用git。

Mercurial不会禁止您提交未解决的文件,只会阻止您。在拉动您没有的更改之前,先进行推后处理。

在Mercurial中,您需要做的就是,一旦有了要提交的文件的方式:

hg resolve --mark --all
hg commit -m "I'm such a rebel"

--mark将...将文件标记为已解决,而不会使用合并工具提示您。--all将选择所有带有冲突标记的文件。

如果您想不推就推(因此必须合并其他人的更改),请像绝地一样

hg push --force

下一个拉扯的人将获得+1头(无双关语)

我敢肯定,有一种方法可以用Git做同样的事情(尽管它可能更令人费解)。


1

当我在git中合并时,我会立即提交所有更改(包括合并冲突)。然后,在下一个提交中,我将通过文本编辑器解决合并冲突。解决冲突后,如果需要,我再推送。

老实说,我不明白为什么其他人不这样做,或者git不执行它。

  • 现在,“合并提交”完全清除了需要合并的内容的历史记录。
  • 以下提交完全显示了您为解决合并冲突所做的工作。
  • 当您推送时,冲突将得到解决,并且构建在分支的尖端处不会中断。
  • 在任何时候,如果您破坏冲突解决方案,都可以简单地恢复为“合并后”提交之一,然后重试。

解决提交冲突的标准工作流程的一个巨大缺点是,本地副本的更改可能会潜入。添加的内容被大量合并差异隐藏在代码审查中,因此您不会注意到自己不小心提交了API键或其他

我上面描述的工作流程避免了此本地复制问题,并且还允许代码审阅者检查(仅)看起来像标准提交差异的提交差异中合并解析的详细信息。


0

我认为最好在可能的情况下推送小更改并经常推送(当然,并非总是如此),并且不要提交无法构建或完成一半的代码(我们都会犯错,但是不要不是故意这样做的。我也来自git,我认为最好的事情之一就是您可以在桌面上拥有一个可操作的回购副本……然后您可以对其进行修改以适应您的内心需求。完成重大更改后,将其发送出去。

使用git进行大量开放源代码对我来说最大的挫折是将一半完成的代码放入仓库中,并尝试进行构建,但无法完成,因为那家伙做了一半的工作,并说:“我现在很忙,我会在一周内完成”。因此,我最终不得不报废它(这会使这个家伙烦恼),或者花时间完成并完全集成它。

从我的角度来看,我想将半屁股的东西放在本地,将好东西通过电线发送。


0

不要成为工具的奴隶。

VCS的目标是使您能够完成工作。您的工作不是保留原始的本地存储库,而是编写代码。如果尽早提交(通常是本地提交)可以让您更好地工作,那就去做。

但是,您不应损坏的代码推向上游。


0

因为从根本上说,这是一个坏主意-它将导致您进入处于稀疏状态的存储库(并且轻率地假设您会一直推到任何地方,尽管有人会认为您应该至少拥有一个副本)。

我可以看到,在大型/复杂合并的情况下,您可能希望保存进行中的工作并建立参考点,但是您仍将系统置于需要解决的混乱状态。

还有其他选择-您可以选择从头开始合并-这很可能使您能够适应更改,而无需进行史诗般的合并(或至少使用更容易理解的较大合并)。

在这种情况下,我发现git的rebase特别有用(要遵守有关重新定级的一般注意事项),因为您正在以当前状态为基础重放更改,从而可以将冲突更小地解决。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.