比较两个分支产生不同的差异

6
我使用Bitbucket比较了两个分支。当我将我的master分支(作为源)与我的uat分支(作为目标)进行比较并查看差异时,我注意到当我将uat(作为源)与master(作为目标)进行比较时,文件列表完全不同。当我将master作为源进行比较时,有更多的文件不同。而当我将uat作为源进行比较时,只有少数文件不同。为什么比较的顺序会有所不同?为什么比较两个分支时源和目标会有所影响?
此外,我注意到在差异列表中列出的大多数文件具有相同的内容,唯一的区别是提交哈希值。
这里有一些屏幕截图。我正在使用BitBucket UI来比较这两个分支。当我将master作为源时,你可以看到我的截图中包括了设置文件夹,而当我将uat1作为源时,它并不存在。

uat1 as my source


master as my source


当我将uat1作为我的源并将其与master进行比较时,我注意到了正确的更改文件列表。但是当我将master作为我的源并将其与uat1进行比较时,差异中的文件列表约为50个。然后,我比较了那50个列表中来自uat1和master的一些文件,并注意到它们是相同的,唯一的区别是哈希提交。 - Robin
嗯:你是否处于冲突合并的中间?你正在运行哪些命令?你能展示一下这些命令以及至少一点输出吗? - torek
那么,当你说你在Bitbucket中比较了分支时,是指你通过Bitbucket网页界面发出了命令(而不是例如命令行的git diff命令)?如果是这样,你可能应该标记Bitbucket;并且还可以查看一下在本地比较分支时是否会出现类似的“怪异”情况。但这似乎偏离了我对问题的猜测,所以我又回到了“可能需要更多信息”的状态。 - Mark Adelsberger
@torek,我已经解决了所有合并冲突。此外,在比较中不需要任何命令即可查看差异。我的做法是进入Bitbucket,单击存储库上的“比较”按钮。将主分支作为源,uat作为目标进行比较。然后在Bitbucket UI中反转比较,这就是我注意到总文件巨大差异的方法。 - Robin
截图已发布 - Robin
显示剩余6条评论
2个回答

6
您展示的截屏具有“源”和“目标”分支的概念,并且有一个“创建拉取请求”按钮。
我不太熟悉Bitbucket GUI,但所有提供Pull Request机制的git服务(如Github、Gitlab(在Gitlab中称为“合并请求”)、Azure Devops等)都具有类似的视图:
显示的差异是:
- 如果您将“源”合并到“目标”中,则显示的更改列表。 这与以下情况不同:
- “源”和“目标”之间的所有差异。
以下是一张图解:
# say your branches 'master' and 'release/onemsg-uat1' look like this :

       D--E--F <- release/onemsg-uat1  (source)
      /
--*--X--A--B <- master  (destination)
     ^
    fork point, aka "merge base"

为了表示“源分支所带来的更改”,而不是查看BF之间的完整差异,GUI会向您展示从X开始的更改:

a. 如果您打开一个拉取请求,将release/onemsg-uat1(源)合并到master(目标)中:要查看的更改是XF之间的差异,
b. 如果您交换分支,并查看master将带给release/onemsg-uat1的内容:要查看的更改是XB之间的差异。


git术语中,X称为两个分支的“合并基础”,您可以使用git merge-base master release/onemsg-uat1获取其sha1。

首先,从本地仓库查看这些差异的一种方法是:

# changes introduced in release/onemsg-uat1 :
git diff $(git merge-base master release/onemsg-uat1) release/onemsg-uat1

# changes introduced in master :
git diff $(git merge-base master release/onemsg-uat1) master

上述命令有一个快捷方式:三个点符号标记git diff a...b

# changes introduced in release/onemsg-uat1 :
git diff master...release/onemsg-uat1

# changes introduced in master :
git diff release/onemsg-uat1...master

要仅列出受影响的文件,请使用--name-only--name-status

git diff --name-only master...release/onemsg-uat1
git diff --name-status master...release/onemsg-uat1

要在图形化差异查看器中打开此差异,请使用git difftool:
# the following command will open the differing files one at a time :
git difftool master...release/onemsg-uat1

# with the '-d' option, you will view the diff of two complete directories :
git difftool -d master...release/onemsg-uat1

2

编辑:您正在使用的是Bitbucket的比较器,它不是git diff,也许甚至不是Git的一部分。 Bitbucket在这里做了什么并不明显。 它可能会查看合并基础,也可能不会:

base=$(git merge-base $tip1 $tip2)
git diff $base $tip2

然而,我曾经认为这是GitHub在处理拉取请求显示方面所做的事情,但实验表明GitHub并不是这样做的。Bitbucket也可能不是这样做的(或者说,BitBucket基于Web浏览器的UI是否与GitHub的UI直接相关)。由于我不知道Bitbucket实际上正在比较什么——尽管显然不是两个分支末端——所以我无法真正回答这个问题。我会保留原始答案,因为对于那些只是在命令行上运行git diff的人来说,它可能有用。
输入到git diff中的是(至少初步如此)两个提交或两个快照:将此快照与该快照进行比较。
git diff的输出是一组指令。这些指令告诉您如何更改第一个快照,以便获得第二个快照。
这意味着您最初的期望是错误的。Git没有说:“要从旧的快照转到新的快照,请在这里添加这些行并删除那些行。”它说:“要从左侧提交/快照转到右侧提交/快照...”如果交换两侧,则会得到相反的方向:如果将快照A更改为快照G需要添加一行,则将快照G更改为快照A将需要删除相同的行。

我需要澄清一下。我的意思是说,不同文件的列表完全不同。当我以主干作为源时,有许多在合并时提交的文件,但当我以uat作为源时,只有几个文件被提交。 - Robin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接