mercurial和git,它们如何在修改文件时处理签入

时间:2011-11-30 22:02:15

标签: git mercurial

想象一下,用户#1修改了file1,用户#2也修改了file1。这些更改不需要任何手动合并。

用户#1已经检查了他的更改并将其推送到中央存储库。现在用户#2想要推进他们的变化。

据我所知,Mercurial将强制您在推送更改之前更新本地副本。因此,你推送的变更集看起来好像你修改了用户#1的文件,而事实上你并没有。

这是对的吗?

Git会这样做吗?

3 个答案:

答案 0 :(得分:3)

在Mercurial中使用主存储库时,您有两种选择。

典型的工作流程是合并。这意味着您在本地提交更改,然后将第二个人的更改提取到克隆中,然后将所有更改合并到合并更改集中。然后,您可以将两个提交都推送到主存储库。

根据马丁编辑:

另一个工作流程是变基。这里有三个选项:

  1. 实际上没有提交你的工作。只需将其他用户的更改拉入您的树,更新(必要时将合并),然后提交并推送。显然,这只有在你一次提交一个提交时才有效。
  2. Mercurial队列。这相当于暂时取消应用您的补丁,将最新的工作拉入您的克隆,然后重新应用您的补丁并提交。但是,修补程序不会智能应用,您可能会遇到合并冲突。
  3. Rebase扩展。这是更新的,因此更聪明。对于单个变更集,它类似于合并提交,但随后它会删除您的原始提交,将变更集留给其他用户的更改作为其父变更。 rebase扩展甚至可以为您修改Mercurial队列。

答案 1 :(得分:2)

我不能代表Mercurial,但在Git中,合并会自动处理,除非两个人修改同一文件中的同一位置。

如果发生这种情况,第二个签到的人必须合并更改。该文件看起来像这样:

<<<<<<<<<<
void SomeMethod()
{
    // do something
}
==========
void SomeMethod()
{
    // do something else
}
>>>>>>>>>>

基本思想是,作为理解代码的人,您要弄清楚如何将更改放在两个部分中,然后删除标记字符。如果合适的话,我可以将两者结合起来:

void SomeMethod()
{
    // do something
    // do something else
}

或者我可以使用一个,如果它取代另一个:

void SomeMethod()
{
    // do something else
}

然后我添加合并文件并完成提交。或者,如果我不确定更改是否有意义,我可以在完成提交之前进行尽可能多的测试。

除合并外,您还可以 rebase 。这改变了历史的本质,因此,不是你和另一个人同时做出改变,你的历史就是在他的历史之后。但是,虽然改变改变了历史看起来的方式,但它并没有改变这样一个事实,即如果你们两个改变了文件的同一部分,你就必须将这些改变合并在一起。 Rebase(以及任何其他可能的合并操作,如应用/弹出存储或挑选提交)将以与上述相同的方式呈现冲突。

答案 2 :(得分:0)

git的答案取决于git pull的设置。

当用户#2进入推送时,推送将失败,因为共享仓库已更改。在推送之前,用户#2将被要求拉动。

默认情况下,git pullgit fetchgit merge的组合。但是,git pull也可以配置为git fetch,后跟git rebase

git fetch更新远程仓库的本地表示。 Git会自动为您维护这个区域。

在默认模式下,使用git merge,git会将远程仓库中的更改合并到本地仓库。这使得用户#1的更改在用户#2的更改后出现。这也可能会创建一个所谓的合并提交。

在rebase模式下,保存对分支的任何本地更改,从远程表示更新分支,然后在分支顶部重播本地更改。通过这种方式,用户#1的更改发生在之前对用户#2的更改。

来自@Kyralessa的所有信息都与合并冲突有关。合并或使用rebase可能会发生合并冲突。

编辑

我们希望将git rebasegit pull一起使用。这更正确地代表了远程仓库的历史。在此示例中,用户#1在用户#2之前将更改推送到远程,并且历史记录应该反映出来。带有rebase的git pull也避免了合并提交的不幸副作用。