git是否强迫您将更改提取到提示?你的推送是否包含这些文件?

时间:2012-01-20 23:28:50

标签: git mercurial push dvcs

使用Mercurial,如果您尝试推送并且对主回购进行了提交,则您将被迫进行合并。

问题是,当您提交更改时,您推送的更改集包含您被迫合并的文件。

您没有触摸这些文件,但历史记录显示您正在修改它们。

git有同样的行为吗?或者它是否足够聪明,知道你没有修改这些文件,所以没有必要把它记录下来。

5 个答案:

答案 0 :(得分:2)

  

使用Mercurial,如果您尝试推送并且对主回购进行了提交,则您将被迫进行合并。

Git和Mercurial在这里工作基本相同。当在远程仓库中进行新的提交时,git push将中止:

$ git push
To /home/mg/tmp/git/repo-1
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to '/home/mg/tmp/git/repo-1'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

Mercurial也在这种情况下中止:

$ hg push
pushing to /home/mg/tmp/hg/repo-1
searching for changes
abort: push creates new remote head 436b0ce25d42!
(you should pull and merge or use push -f to force)

到目前为止一切顺利。在Git中,您现在可以运行git pull,在Mercurial中,您可以运行hg fetch。这将检索并合并新的变更集,并在两个系统中的工作方式相同。

  

问题是,当您提交更改时,您推送的更改集包含您被迫合并的文件。

     

您没有触摸这些文件,但历史记录显示您正在修改它们。

我认为你误解了Mercurial向你展示的内容。两个系统都可以处理完整存储库的快照,因此两个系统将强制您将更改推送到合并中未触及的文件。 Git合并提交还将“包含”所有未更改的文件 - 它们通过提交引用的树对象引用。

因为两个系统都使用快照,所以“谁修改了什么?”的问题只比较两个快照时才有意义。对于合并变更集,有两个有趣的比较:针对第一个父级和第二个父级。

Mercurial和Git之间的差异是没有为合并变更集显示补丁:

$ git log -p -1
commit 8cdbbef1b6f0fc8e01997f6842b7f249d066a30c
Merge: b77058e e99e303
Author: Martin Geisler <mg@aragost.com>
Date:   Mon Jan 23 14:09:09 2012 +0100

    Merge branch 'master' of /home/mg/tmp/git/repo-1

而Mercurial总是显示针对第一个父母的补丁:

$ hg log -p -l 1
changeset:   3:94060588f0a5
tag:         tip
parent:      2:06d00ad5063b
parent:      1:436b0ce25d42
user:        Martin Geisler <mg@aragost.com>
date:        Mon Jan 23 14:01:25 2012 +0100
summary:     Automated merge with file:///home/mg/tmp/hg/repo-1

diff --git a/b b/b
new file mode 100644
--- /dev/null
+++ b/b
@@ -0,0 +1,1 @@
+b

这表明文件b不存在于合并的第一个父级中。换句话说:它可能来自第二个父母。使用hg diff -r "p2(3):3"hg diff -r "3^2:3"进行检查。在Git中,您将使用git diff "8cdbbef^2" 8cdbbef与第二个父级进行比较。

请注意,两个系统对git log bhg log b显示相同:合并变更集不在文件的日志中,除非文件实际上已作为合并变更集。通常在合并更改集中修改文件,因为在提交合并之前需要解决冲突。

答案 1 :(得分:1)

如果您没有触摸在遥控器上修改过的文件,那么git不会将它们显示为冲突,您不必将它们合并。所以,如果你没有,那么它就不会显示,就好像你触摸了这些文件一样。

此外,如果您不希望合并提交显示在历史记录中,则可以在从遥控器拉出时使用--rebase选项。(请参阅man git-pull)。

答案 2 :(得分:1)

知道很聪明。您的提交与合并提交是分开的。

答案 3 :(得分:1)

Git不会在补丁视图中显示这些内容。这意味着您必须合并它们,但是您的非合并提交将不会显示这些文件的更改。实际上,除非存在冲突,否则将显示提交和每个修补程序的git log -p将不显示合并。

答案 4 :(得分:1)

在与@LaurensHolst进行详细讨论后,这个答案已经大幅修改。


您可以选择是否包含合并提交。 git的默认值是包含合并提交。您还可以设置pull来使用rebase,这将创建一个没有合并提交的线性历史记录。

可以将远程分支设置为rebase而不是merge:

git config branch.<branch-name>.rebase true

git可以使用

自动设置
git config [--global] branch.autosetuprebase always

使用rebase进行合并提交会导致在远程提交后放置本地提交,而不需要额外的提交。这提供了历史的线性版本。 git允许您选择您喜欢的历史记录。

Git pull results in extraneous “Merge branch” messages in commit log可以找到类似的答案和解释。