Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
GitHub PR使用什么git命令来显示差异_Git_Github - Fatal编程技术网

GitHub PR使用什么git命令来显示差异

GitHub PR使用什么git命令来显示差异,git,github,Git,Github,我想使用命令行生成GitHub提供的相同差异。“帮助”页面将其描述为“头部分支尖端与头部上次与基本分支同步的提交之间的比较”() 如果PR要将分支a拉入分支b,那么git diff命令行是什么 我特别想知道为什么当a和b都是在分支m之外创建的,并且我将分支m上的后续更改合并到a和b时,更改会出现在PR中 示例:提交分支m、a和b的图(从下到上读取) 拟合并的分行行长: git rev-parse a 5 合并的基础: git merge-base b a 3 git命令显示提交2中引入的差异

我想使用命令行生成GitHub提供的相同差异。“帮助”页面将其描述为“头部分支尖端与头部上次与基本分支同步的提交之间的比较”()

如果PR要将分支a拉入分支b,那么git diff命令行是什么

我特别想知道为什么当a和b都是在分支m之外创建的,并且我将分支m上的后续更改合并到a和b时,更改会出现在PR中

示例:提交分支m、a和b的图(从下到上读取)

拟合并的分行行长:

git rev-parse a
5
合并的基础:

git merge-base b a
3
git命令显示提交2中引入的差异:

git diff b...a

但是GitHub PR显示了在提交2和提交3中引入的差异,差异在目标分支和源分支之间:

git diff <destination> <source>
git-diff

这将包括源上而不是目标上的所有更改,反之亦然。如果你得到这个,你的功能分支已经过时了。您可以将目标合并到您的分支中,也可以将您的分支重新设置到目标分支上(取决于您的工作流程和个人偏好)。

编辑:我已经使用本地命令和GitHub的实际输出对此进行了扩充,现在我根本无法解释在它们的拉请求比较中显示了什么。这完全是胡说八道,就像他们在网页上展示的许多其他东西一样。GitHub的显示显示了目标分支中已经存在的提交,就好像合并将进行它实际上不会进行的更改一样。也就是说,对于“将分支“a”合并到b”中,将添加的唯一提交是那些尚未包含在“b”中的提交,但GitHub的显示显示显示了已包含在“b”中的两个提交


TL;博士 通常(但请看详细答案):

其中,
$base
$head
来自下面的长答案编辑:嗯,这就是他们应该展示的内容。事实证明这不是他们真正展示的

使用示例存储库 您在
https://github.com/kenocrates/ex1
,我克隆了它:

$ git clone https://github.com/kenocrates/ex1
...
$ cd ex1
要从中获取
refs/pull
引用,您需要修改配置,使其部分内容如下:

[remote "origin"]
        url = https://github.com/kenocrates/ex1
        fetch = +refs/heads/*:refs/remotes/origin/*
        fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
我也这么做了。然后:

$ git fetch origin
From https://github.com/kenocrates/ex1
 * [new ref]         refs/pull/1/head -> origin/pr/1
我现在使用的用于查找正确合并基的命令是:

$ git merge-base --all refs/remotes/origin/pr/1 refs/remotes/origin/b
587593749ee46806ed2c9fd06cf8b904bbce255a
因为我的提交全名是
refs/remotes/origin/pr/1
,而我的提交全名是
refs/remotes/origin/b
,GitHub称之为“基本分支”。请注意,我们还可以使用原始哈希ID或更短的名称:

$ git rev-parse origin/pr/1
1cef243f9efe6e94c9926f7992efb6c093188b8c
$ git rev-parse origin/b
48728bc19480e0c1cc9e3a399634a5f389881c47
(省略
refs/remotes/
,如中所述,这将由Git通常用于解析名称的六步流程中的第五步承担)

因此,可通过以下方式获得正确的差异(完整,而不是一次提交):

$ git diff 587593749ee46806ed2c9fd06cf8b904bbce255a origin/b
或较短者:

$ git diff origin/pr/1...origin/b
其中一种输出:

diff --git a/file b/file
index 4fc2681..186222c 100644
--- a/file
+++ b/file
@@ -1,6 +1,7 @@
 Section A

 Section B
+line 1

 Section C
 line 1
这是GitHub应该显示的内容,因为如果我们接受pull请求,它将被合并,并产生效果。它们实际显示的内容不同。Per,我们看到的是四个提交,其中两个已经包含在目标分支中:

1cef243f9efe6e94c9926f7992efb6c093188b8c
587593749ee46806ed2c9fd06cf8b904bbce255a
23c2ff68c02207a2f172090566d7b2c75b6f1c16
b21d3c4067261aa295319f177ad1629b5ae12818
下面是GitHub上存储库中的实际内容,包括pull请求(虽然不是它的合并),以及通常的名称更改,这是由于我们使用存储库的副本,而我们没有将我们的副本设置为纯镜像。(制作一个纯镜像将使我们自己的本地存储库无法在中执行任何工作。)

这个图表非常复杂,很难阅读,但是,如果我们真的要进行这个提议的合并,这些是我们将通过另一个分支添加的提交,它们还没有在
origin/a

$ git log --decorate --oneline --graph $(git merge-base origin/pr/1 origin/b)..origin/b
* 48728bc (origin/b) Merge branch 'm' into b
* f365142 added line to section B
这就是为什么我们在本地差异中看到了我们所看到的。出于某种原因,GitHub所选择的基础是不正确的

让我们再做一个实验,让我们抓取GitHub所做的实际合并提交,看看它在
git log--all--decoration--graph--oneline中的外观:

$ git config --add remote.origin.fetch '+refs/pull/*/merge:refs/remotes/origin/pr-merge/*'
$ git fetch
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/kenocrates/ex1
 * [new ref]         refs/pull/1/merge -> origin/pr-merge/1

$ git log --all --decorate --graph --oneline
*   f53dc81 (origin/pr-merge/1) Merge 1cef243f9efe6e94c9926f7992efb6c093188b8c into 48728bc19480e0c1cc9e3a399634a5f389881c47
|\  
| *   1cef243 (HEAD -> a, origin/pr/1, origin/a, origin/HEAD) Merge branch 'm' into a
| |\  
| * | b21d3c4 added line to section A
* | |   48728bc (origin/b) Merge branch 'm' into b
|\ \ \  
| | |/  
| |/|   
| * |   5875937 (origin/m) Merge branch 'p' into m
| |\ \  
| | |/  
| |/|   
| | * 23c2ff6 added line to section C
| |/  
* | f365142 added line to section B
|/  
* 1ff1a3c added file
这正是我们应该期望的:一个合并提交,其第一个父级
origin/pr merge/1^1
48728bc19480e0c1cc9e3a399634a5f389881c47
aka
origin/b
,其第二个父级
origin/pr merge/1^2
1cef243f9efe6e94c9926f7992efb6c093188b8c
aka
HEAD
origin/pr/1
origin/a
origin/HEAD

长的 答案[编辑:除非它不是GitHub实际使用的答案]嵌入在短语中:

“头分支尖端与头上次与基分支同步的提交之间的比较”

为了理解(和再现)这一点,我们必须定义每个术语

分支(名称)的尖端只是分支名称解析到的提交。例如,要查找分支
master
尖端的散列ID,可以运行:

git rev-parse master
一般来说,对于大多数命令,使用分支名称与使用此分支提示哈希ID具有相同的效果,因此我们甚至不必在这里处理
git rev parse
。(Git中有一些例外:有时名称不仅仅意味着原始散列ID。)

接下来,我们有总部分支和基地分支。在这里,定义这些术语的是GitHub,而不是Git。本例中的head分支是您执行pull请求的分支,base是您说的“into”的分支:请将feature-X拉入master表示head=feature-X,base=master;所以

如果PR将分支a拉入分支b

然后“head”是
a
,而“base”是
b
,因此您可以执行
head=a
base=b
并使用
$head
$base
be
$ git log --all --decorate --oneline --graph
*   48728bc (origin/b) Merge branch 'm' into b
|\  
* | f365142 added line to section B
| | *   1cef243 (HEAD -> a, origin/pr/1, origin/a, origin/HEAD) Merge branch 'm' into a
| | |\  
| | |/  
| |/|   
| * |   5875937 (origin/m) Merge branch 'p' into m
| |\ \  
|/ / /  
| * | 23c2ff6 added line to section C
|/ /  
| * b21d3c4 added line to section A
|/  
* 1ff1a3c added file
$ git log --decorate --oneline --graph $(git merge-base origin/pr/1 origin/b)..origin/b
* 48728bc (origin/b) Merge branch 'm' into b
* f365142 added line to section B
$ git config --add remote.origin.fetch '+refs/pull/*/merge:refs/remotes/origin/pr-merge/*'
$ git fetch
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/kenocrates/ex1
 * [new ref]         refs/pull/1/merge -> origin/pr-merge/1

$ git log --all --decorate --graph --oneline
*   f53dc81 (origin/pr-merge/1) Merge 1cef243f9efe6e94c9926f7992efb6c093188b8c into 48728bc19480e0c1cc9e3a399634a5f389881c47
|\  
| *   1cef243 (HEAD -> a, origin/pr/1, origin/a, origin/HEAD) Merge branch 'm' into a
| |\  
| * | b21d3c4 added line to section A
* | |   48728bc (origin/b) Merge branch 'm' into b
|\ \ \  
| | |/  
| |/|   
| * |   5875937 (origin/m) Merge branch 'p' into m
| |\ \  
| | |/  
| |/|   
| | * 23c2ff6 added line to section C
| |/  
* | f365142 added line to section B
|/  
* 1ff1a3c added file
git rev-parse master
git merge-base --all refs/pull/$N/head refs/heads/$base
git merge-base --all $head $base
hash=$(git merge-base $head $base)  # slightly sloppy
... check that $hash is just one hash ...
git diff $hash $head