如何在从远程分支合并之前检查真正的git diff?

abh*_*kar 55 git diff

我想检查远程分支和本地分支之间的真正差异.我怎样才能做到这一点?

发出以下命令部分有效,但它也显示了我本地分支的新变化的差异.

git diff remote/branch
Run Code Online (Sandbox Code Playgroud)

rho*_*mes 132

由于这个话题频繁出现,如果没有一点关于git如何工作的背景可能会令人困惑,我想我会尝试解释最简单的案例,但是如果有足够的深度,那么新手就会有足够的处理来做它额外的研究.

如果您通过普通的'clone'设置git存储库并具有默认的refspecs,这意味着您的遥控器名为'origin'并且您从分支'master'中提取/获取,您有时可能需要查看遥控器中的内容存储库在拉下来之前.

由于"git pull"执行自动合并(除非存在冲突),因此可以很高兴看到下一步的"传入".如果你不熟悉git是如何工作的,特别是如何管理refspecs,这可能有点不直观.

假设某人在远程存储库中进行了更改(为了便于说明,通过提交更改并将其推送到远程存储库中添加一行),然后键入:

$ git diff origin/master
Run Code Online (Sandbox Code Playgroud)

你可能不会看到任何变化; 但是,如果您执行以下操作:

$ git fetch; git diff ..origin/master 
Run Code Online (Sandbox Code Playgroud)

您将看到已提交到本地git存储库的内容与远程存储库中的内容之间的区别.您将看不到本地文件系统中的任何更改或在索引中暂存的更改.

好的,我们为什么要这样做?origin/master是refspec(参见手册页).简而言之,这就是我们所提到的,以便比较,拉取或取出,以及推送到.以下所有内容在功能上都是等效的:

origin/master
remotes/origin/master
refs/remotes/origin/master
Run Code Online (Sandbox Code Playgroud)

要开始解开这个问题,只需看一下存储库的.git目录结构.典型布局如下所示:

.git/refs
.git/refs/heads
.git/refs/heads/master
.git/refs/remotes
.git/refs/remotes/origin
.git/refs/remotes/origin/HEAD
.git/refs/remotes/origin/master
.git/refs/tags
Run Code Online (Sandbox Code Playgroud)

看看.git/refs/remotes/origin/HEAD; 在默认情况下,它将指向您用来拉出和推送的分支.在我的情况下,因为我在掌握,这个文本文件的内容如下所示:

ref: refs/remotes/origin/master
Run Code Online (Sandbox Code Playgroud)

这告诉我,我的遥控器的HEAD由refspec'refs/remotes/origin/master'识别(恰好有上面提到的别名).

这并没有告诉我们多少; 什么是远程存储库的状态?查看远程主服务器的状态:

$ cat .git/refs/heads/master     
6d0fb0adfdfa5af861931bb06d34100b349f1d63
Run Code Online (Sandbox Code Playgroud)

好吧,这是一个SHA1哈希; 可能是一个提交.它是如何被放入这个文件的?好吧,无论何时执行pull或fetch,此文件都会使用拉取或获取的远程最新提交进行更新.这解释了为什么我们必须git fetch在执行差异之前.请记住,git fetch只需更新远程分支的本地副本,但不要将其与工作副本合并.这是完全安全的.A git fetch; git merge相当于a git pull.

执行获取后,git将能够在获取时查看远程存储库中的最新提交.

你可以使用各种说明符组合来git来根据需要查看你的差异(下面的例子使用本地工作副本作为隐式的第一次提交):

$ git diff remote/origin   
This shows the incoming remote additions as deletions; any additions in your local 
repository are shown as additions.

$ git diff ...remote/origin
Shows incoming remote additions as additions; the triple-dot excludes changes
committed to your local repository.

$ git diff ..remote/origin
Shows incoming remote additions as additions; the double-dot includes changes
committed to your local repository as deletions (since they are not yet pushed).
Run Code Online (Sandbox Code Playgroud)

有关".."与"..."的信息,请参阅git-scm修订版选择git help diff的优秀文档:提交范围 简而言之,对于上面的示例,双点语法显示了从origin/master可以访问的所有提交但不是你的工作副本.同样,三点语法显示从提交(隐式工作副本,远程/原点)可以访问的所有提交,但不能同时从两者提交.

我正在逐步完成这一步,因为我对git很新,而这正是令我困惑的事情......我确信git专家可以找到有关细节的缺陷......我只是希望这个答案弥补了一些人发现所有各种帖子有点简洁的差距.

  • 双点和三点,是吗?那有点可怕.但是感谢你的回答 - 它解释了为什么git diff对我来说从未显示过多少. (6认同)
  • 这应该是公认的答案; 更多初学者友好并解释了围绕差异的重要概念(如果你不熟悉所有术语,那么man-page是一个很难理解的痛苦). (5认同)

Evg*_*nov 15

从文档:

git diff [--options] <commit>...<commit> [--] [<path>…]
Run Code Online (Sandbox Code Playgroud)

此表单用于查看包含和最多为第二个的分支上的更改<commit>,从两者的共同祖先开始<commit>."git diff A ... B"相当于"git diff $(git-merge-base AB)B".您可以省略任何一个<commit>,这与使用HEAD具有相同的效果.

你试过这个吗?


Ant*_*sse 7

你想做的是,正如Evgen Bodunov建议的那样:

git diff ...remote/branch
Run Code Online (Sandbox Code Playgroud)

这将改变远程/分支的变化,并忽略当前HEAD的变化.