如何判断自上次git拉取以来远程存储库中的哪些文件发生了更改?

如何判断自上次git拉取以来远程存储库中的哪些文件发生了更改?,git,Git,我试图使用$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

我试图使用
$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
我得到了两个repo之间不同的所有文件和更改的列表。但是,我只对在远程存储库和上次在本地框上执行
$git pull origin master
时发生更改的文件列表感兴趣


有什么方法可以做到这一点吗?

git pull
git fetch
后接
git merge
(或
git rebase
)相同

git diff --stat master origin/master
git fetch
显示更新的引用。它将显示如下内容:

a8e5e4e..295bf31  master     -> origin/master
git diff --name-status a8e5e4e..295bf31
这意味着您上次取回master是在a8e5e4e,现在是在295bf31。 您可以通过以下方式查看更改的文件:

a8e5e4e..295bf31  master     -> origin/master
git diff --name-status a8e5e4e..295bf31
但可能更有趣的是,在获取之后,
gitkmaster…origin/master
的输出。通过这种方式,您可以检查您这边的更改和原始端的更改。

是所问问题的正确答案

如果您没有旧的参考,即
a8e5e4e
部分
a8e5e4e..295bf31 master->origin/master
,该怎么办?也许你实际上并不在意:正如他所建议的,查看
master…origin/master
可能会更有趣。1但是,这三点
语法实际上意味着什么

答案在文档中:

另一个特殊符号是
,它对 合并。提交的结果集是对称差异 在两个操作数之间

我怀疑这是混淆了足够多的措辞(实际上,
gitdiff
使用了完全不同的含义)。但事实上,事情并没有那么复杂

考虑到一些提交可以这样绘制:

master  origin/master

   E       G
   |       |
   D       F
     \   /
       C
       |
       B
       |
       A
您在提交
C
时遇到了分歧。当
master
origin/master
都指向
C
时,您开始工作。显然,您提交了
D
E
,以及“他们”(无论他们是谁)提交了
F
G
。顺便说一下,提交
C
,称为合并基

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

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

假设您在
master
分支上(即
HEAD
只是简单地表示“master”),您可以进一步缩短它。要查看自您的分支和它们的分支发生分歧以来它们修改了哪些文件,只需运行:

$ git diff --stat ...origin/master   # or --name-status, etc
省略名称意味着
HEAD
,因此这与
HEAD…origin/master
相同,后者与
master…origin/master
相同

如果您的git足够新,
@{u}
指的是“当前分支的上游分支”(即,从
master
,查找
origin/master
),因此您可以运行:

$ git diff --stat '...@{u}'
(引号用于保护支架不受外壳的影响;在特定外壳中可能需要也可能不需要引号)。即使您在
develope
上以
origin/develope
作为其上游,或
featureX
origin/featureX
作为其上游,这项功能仍然有效


1如果您没有
gitk
,请尝试:

$ git log --graph --boundary ...origin/master
(或如上所述的
“…@{u}”
)。您需要
--boundary
来包含合并提交。您可能还需要添加
--oneline--decoration

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


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

这实际上是将当前提交(
master
)与它们的(
origin/master
)进行比较,我发现--name status我也需要--name只显示文件名,而不显示差异。