7

我正在尝试使用推送一些代码,$git push origin master但出现错误

! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/'
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.

当我这样做时$ git fetch origin master$ git diff master origin/master我得到了两个存储库之间不同的所有文件和更改的列表。但是,我只对在远程存储库和上次$ git pull origin master在本地机器上执行操作之间发生更改的文件列表感兴趣。

有没有办法我可以做到这一点?

4

3 回答 3

7

git pullgit fetch后跟git merge(或git rebase)相同。

git fetch显示更新的参考。它将显示如下内容:

a8e5e4e..295bf31  master     -> origin/master

这意味着您上次获取 master 时是在 a8e5e4e,现在是在 295bf31。您可以看到更改后的文件,例如:

git diff --name-status a8e5e4e..295bf31

但也许更有趣的是gitk master...origin/masterfetch 之后的输出。通过这种方式,您可以检查您这边的更改和源端的更改。

于 2013-08-18T08:26:06.413 回答
5

michas 的答案是正确的答案。

如果您没有旧的 ref,即 的a8e5e4e部分a8e5e4e..295bf31 master -> origin/master怎么办?可能您实际上并不关心:正如他所建议的那样,看master...origin/master可能会更有趣。1 但是,这个三点...语法实际上是什么意思

答案在git rev-list文档中:

另一个特殊符号<commit1>...<commit2>对合并很有用。提交的结果集是两个操作数之间的对称差异。...

我怀疑这足以令人困惑的措辞(实际上git diff使用了完全不同的含义)。但实际上,它并没有那么复杂。

给定一些可以像这样绘制的提交:

master  origin/master

   E       G
   |       |
   D       F
     \   /
       C
       |
       B
       |
       A

你所拥有的是 commit 的分歧Cmaster当和origin/master都指向时,您开始工作C。显然,您承诺了Dand E,而“他们”(无论他们是谁)都承诺了Fand G。顺便说一下,提交C被称为合并基础

意思master...origin/master是:找到我C,然后把左右两边的东西都“从那里”给我。也就是说,所有在master origin/master上的提交,不包括在它们第一次相遇点及以下的任何提交。

如果您运行gitk master...origin/master,您将看到:2所做的所有提交,以及他们所做的所有提交。但是,如果您运行,则会将大部分内容抛出。相反,它会找到合并基数3并将其与右侧名称进行比较。git diff flags master...origin/mastergit diffC

假设您在您的master分支上(即,HEAD无论如何都只是意味着“master”),您可以进一步缩短它。要查看自从您和他们的分支分歧后他们修改了哪些文件,只需运行:

$ git diff --stat ...origin/master   # or --name-status, etc

留下名字的意思HEAD,所以这和HEAD...origin/masterwhich是一样的master...origin/master

如果你的 git 足够新,@{u}指的是“当前分支的上游分支”(即 from master, find origin/master),所以你可以运行:

$ git diff --stat '...@{u}'

(引号是为了保护括号免受外壳的影响;在您的特定外壳中可能需要也可能不需要它们)。即使您将developorigin/develop作为其上游或作为其上游等,featureX这也有效。origin/featureX


1如果没有gitk,请尝试:

$ git log --graph --boundary ...origin/master

(或'...@{u}'如上所述)。您需要--boundary包含合并提交。您可能还想添加--oneline --decorate

2实际上gitk也会向您显示合并提交,就像脚注 1 中的命令一样。也就是说,它用于--boundary包含会合点提交(这与合并基础并不完全相同,但足够接近)。

3这假设只有一个合并基础提交。对于这些情况,这应该是正确的。因此,git diff将树CG上游分支头部的树进行比较。您将比较“他们在哪里”和“他们最终在哪里”,而不管他们在任意长的车程中访问的任何中间点。:-) 例如,如果提交F添加了一个文件this/that,然后G再次提交删除它,您将看不到该文件。

于 2013-08-18T15:44:14.800 回答
3
git diff --stat master origin/master
于 2013-08-18T07:20:38.160 回答