如何知道 "git push" 将推动哪些差异?

How to know what differences that "git push" is going to push?

在我 git 添加并 git 提交之后,我的工作区、缓存的索引和本地存储库变得相同。那我怎么知道"push"这个补丁集有什么区别呢?

您可以尝试 git diff origin/remote-branch-name..local-branch-namegit log -p origin/branch-name..local-branch-name

如果你想比较你所在的当前分支,那么你可以省略本地分支名称,即 git diff origin/remote-branch-name..git log -p origin/branch-name...

结合git-diff

git diff origin/master [ <local-branch-name> ]

您可能正在寻找

git push --dry-run --verbose

这将模拟一次推送并在途中打印您需要的所有信息。来自 git man page:

git-push:
-v
--verbose

    Run verbosely.

-n
--dry-run

    Do everything except actually send the updates.

是正确的(并且被赞成)但是这里有一个关键点被掩盖了:当你 运行 git push 时,你不会发送 补丁 ,您发送完成提交

这是一个简单的例子:

$ cd /tmp
$ git clone upstream.git downstream
Cloning into 'downstream'...
done.
$ cd downstream
$ echo 'add stuff to the readme file' >> README
$ git add README
$ git commit -m 'make a mistake'
[master 20caf72] make a mistake
 1 file changed, 1 insertion(+)

现在我们有一个不想要的提交,所以我们取消所做的更改(我可以简单地 git revert HEAD 但我想以更复杂的方式进行)。

$ ed README
48
$d
w
19
q

(这将删除文件 README 的最后一行)

$ git add README
$ git commit -m 'un-make the mistake'
[master b0ebc79] un-make the mistake
 1 file changed, 1 deletion(-)

(我们现在准备推送)

$ git push origin master
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 440 bytes | 0 bytes/s, done.
Total 4 (delta 0), reused 0 (delta 0)
To [path]/upstream.git
   49c7832..b0ebc79  master -> master
$ 

即使根本没有实际更改,我仍然只是推送了两次提交。让我们转到上游(裸)存储库并查看:

$ cd ../upstream.git
$ git log --oneline
b0ebc79 un-make the mistake
20caf72 make a mistake
49c7832 initial

的确如此。

因此,正确的问题不是“我将发送什么补丁”,而是“我将发送什么提交”。大多数时候这并没有太大的区别,但是如果你不小心提交了一个 4 GB 的视频文件,然后提交删除相同的文件,diff 来自“他们拥有的” “您最新的提交”可能很小,而您将发送的提交包括一个非常大的提交。

还有一点有点模糊,那就是你的 origin/master(或者 origin/branch,如果你正在处理 branch)是基于 你的 Git 关于其他上游 Git 分支的最新知识。上游可能发生了其他变化。如果是这样,你想看到它,还是想忽略它?如果您确实想要看到它,您将不得不选择如何看到它——在某些时候您可能停止忽略它。

要更新您自己的 Git 对另一方 Git 的看法,您可以 运行 git fetch origin,这会带来新的东西 他们有你没有的,然后更新你的origin/masterorigin/branch,等等。如果他们没有任何新东西,git fetch 什么也不会带来,什么也不会更新。所有 origin/* 名称的存在只是为了让您的 Git 可以告诉您“这是我在另一个 Git 中发现的,我上次与它交谈时。”

当你 运行:

git log -p origin/master..master

您正在指示您的 Git 查看 master 上不在 origin/master 上的提交。那是 你的 origin/master——所以它只和你最近的 git fetch.

一样新

要点

  1. Git 发送和接收 提交 ,而不是补丁。 Git 可以为您制作补丁,以便您可以通过电子邮件发送它们,但是 fetchpush 会处理提交。

  2. 使用 git log 查看提交。添加 -p 以将普通(非合并)提交视为补丁:Git 将为您当场制作它们,以便您可以看到它们。添加 --oneline 以仅查看提交 subject 行。

    log 命令显示您从您指定的位置开始提交,如果您没有指定任何内容,则从您的 HEAD 开始提交。它会一直运行,直到 运行 没有提交,或者在遇到您告诉它停止的提交时停止。这就是 origin/master..master 的意义所在。它告诉 git log:“从我的 master 开始,到达我的 origin/master 时停止。”这里需要两个点。

  3. 使用git diff比较两个提交:例如git diff origin/master master。如果愿意,您可以将其拼写为 git diff origin/master..master——但要注意,因为 git diff 只是比较 端点 ,跳过中间的所有提交。如果您不小心提交了一个大电影文件,然后将其删除,git diff 将跳过它(但 git log 不会!)。

  4. 使用 origin/master 和其他 origin/* 的名字来查看你的 Git 从上次从其他 Git 那里得到这些名字时的记忆。

  5. 运行 git fetch(或git fetch origin)让你的Git再次与另一个Git交谈并接听有什么新事吗。如果另一个 Git 非常活跃,您可能需要经常这样做。如果它非常安静,或者是您自己的个人 GitHub 存储库,您可能 永远不会 需要这样做(因为您的 Git 也会更新您自己的 origin/master之类的就成功了git push).