为什么本地和远程存储库之间的差异与提交的不同?

时间:2017-12-01 08:23:39

标签: git git-diff

我有合并冲突,我想看的第一件事是本地文件和远程版本之间的区别是什么。为此,我执行了以下操作:

git diff origin:path/to/my/file.py path/to/my/file.py

这样我就看到我的本地版本有一些额外的块。

然后我想看看我究竟做了什么。所以我执行了:

git diff --staged path/to/my/file.py

令我惊讶的是,我看到了另一个更改块,它与上一个命令返回的块不同。

我已经在文本编辑器中打开了我的文件并看到了两个块。现在我不知道如何解释它。

看起来本地版本和远程版本之间存在差异,这种差异不是我提交的版本。

2 个答案:

答案 0 :(得分:2)

我不确定你为什么期望这些差异首先是相同的。

请注意,origin:path/to/my/file.py是指从path/to/my/file.py结算的提交中提取的origin版本,通常为origin/HEAD,通常为origin/master 。然后,git diff命令会将从该提交中提取的文件与您当前工作树中的任何内容进行比较,如果您正在解决合并冲突,那么通常会将具有冲突标记的版本与冲突。

除此之外:git diff

请注意,在合并冲突期间运行git diff喜欢尝试显示组合差异。但是运行git diff <commit-specifier>:<path> <path>可以避免这种情况。同时,运行git diff --staged <path>只是说:

$ git diff --staged path/to/file
* Unmerged path path/to/file

(除非您从工作树中git add编辑了path/to/file版本,告诉Git您已经正确合并了该文件,在这种情况下它会比较HEAD版本为您通过git add ing)复制到索引中的版本。

git merge正在做什么

这不是git merge正在关注和合并的内容。 git merge所看到的是两个差异:

  • 一个差异来自您的合并基础,无论哪个提交,都是HEAD
  • 第二个差异是从你的合并基地到你的另一个头,无论哪个提交(可能origin/master,也许不是)。

首先获取合并基础提交哈希,可以获得这两个差异。比方说,为简化起见,您运行了git merge origin/master,现在正在查看path/to/my/file.py上的合并冲突。你的Git首次运行:

git merge-base --all HEAD origin/master

运气好的话,这只产生一个提交哈希ID。 1 你可以将它保存在一个变量中:

base=$(git merge-base --all HEAD origin/master)

然后在两个特定的差异中使用它:

git diff $base HEAD -- path/to/my/file.py           # what git thinks I changed
git diff $base origin/master -- path/to/my/file.py  # what git thinks they changed

如果要直接比较所有三个文件,可以将它们提取到临时文件中。这就是git mergetool所做的事情,例如:它从这三个提交中的每一个提取基础path/to/my/file.py,本地(HEAD)文件和另一个(“远程头”)文件,然后在所有三个文件上运行您选择的合并工具。

如果git merge-base --all生成多个哈希ID,则git merge -s recursive执行所有这些提交的内部合并,将结果作为临时提交提交,并使用 > commit的哈希作为合并基础。

答案 1 :(得分:0)

您的某些更改已上演,其他更改尚未完成。这两个都是由第一个命令显示的。第二个只显示那些已经上演的变化。

请执行:

git add path/to/my/file.py

然后git diff --staged将显示与第一个命令相同的输出。