gpt4 book ai didi

git - 从master merge 后,如何找出分支上的变化?

转载 作者:行者123 更新时间:2023-12-03 17:36:50 26 4
gpt4 key购买 nike

我分了master个分支。有时,我将master合并到我的分支中以进行更新。

       /--B--D--G--H--J--L--M--> dev (HEAD)
/ / /
-----A--C--E--F--I--K---> master


如何只显示分支中的更改,而不包括合并中的更改?
即仅在提交 BDHLM时显示差异。

git diff A不起作用,因为它包含来自 master的合并更改。

顺便说一句,如果有人知道快速查找 A而无需继续向下滚动日志的方法,我将不胜感激。

最佳答案

我不清楚您正在寻找什么。但请注意:

提交存储快照。这意味着提交K具有完整的源树,该树独立于提交ABC等中的内容。同样,提交J具有完整的快照,与AK或任何其他提交中的内容无关。
(这里的“独立”一词意味着,如果您要求Git检索提交J,则在创建K之后是否设法以某种方式更改提交J并不重要。实际上,不可能更改任何提交,曾经; git commit --amend似乎更改了提交,但实际上并没有。)

在两个特定的提交上使用git diff,Git提取两个快照中的每个快照,并进行比较。


简单差异
因此,git diff K M将向您显示master的当前提示(提交K)和dev的当前提示(提交M)之间的区别。
您也可以仅拼写此git diff master dev
那可能就是您想要看到的内容(再次,对我来说还不是很清楚)。因此,答案1:git diff master dev
多个独立差异
另一方面,也许您想要显示的是对提交B的一个差异,对提交D的一个差异,对提交H的一个差异,对提交L的一个差异和对commit <的一个差异。 cc>。也就是说,您希望一次查看每个非合并的提交,与其(单个)父提交相比。
您可以Mgit diff A B,依此类推。但是您也可以只git diff B Dgit show B,依此类推。这会将提交显示为更改,而不是快照。
您可能想知道,如果提交存储快照而不是更改快照,怎么可能呢? (因为大多数其他版本控制系统实际上都存储更改,所以这使很多人感到不安。)对此明显矛盾的答案是git show D查找所绘制的相同图形。
再次查看提交git show。之前有什么提交?也就是说,哪个提交在它的左边,向左跟随?提交B的可能祖先只有一个,即提交B的单亲。所以A

提取提交git show B的快照,然后
提取提交A的快照,然后
对比这两个快照。

同样,提交B只有一个直接祖先(父),即提交M。所以L

提取git show M的快照,然后
提取L的快照,然后
对比这两个快照。

如果这是您想要的,那么有趣的问题就变成了:如何以MBDHL顺序找到每个提交的ID?答案很复杂,但是关键命令是M,它基本上与git rev-list相同。这些命令(git loggit log两者)的作用是遍历提交图。也就是说,您选择一些起点(在本例中为git rev-list的提示,为M的提示),并告诉Git向后浏览所有提交,并查看每个提交的父母。
问题在于,当您遇到合并提交(例如提交dev)时,Git会返回其所有父级。您希望限制Git在进行合并提交时仅查找作为分支J尖端的父级。 Git对此有一个标记,拼写为dev。这告诉--first-parent仅跟随每个合并提交的第一个父项。
我们还希望跳过合并,因此我们可以添加git rev-list(这不会影响后退过程,它只限制打印的修订版ID以排除合并)。
这将导致答案2a:--no-merges(稍后将进入“ not A”部分)。
现在,实际上将它与git rev-list --first-parent --no-merges ^A dev一起使用有点麻烦,因为现在我们必须获取每个提交ID,然后在其上运行git rev-list。但是,有一种更简单的方法,因为git showgit rev-list本质上是相同的命令,并且git log将每个提交显示为补丁,其作用与git log -p相同。
这导致答案2b:git show。我们在这里也不一定需要git log -p --first-parent --no-merges ^A dev。见下文。
合并提交和合并的差异
--no-merges做的一件特别事情,而git show没有,是处理显示合并提交的情况,例如提交git diff。提交J有两个父级,即提交JH(顺便说一句,这意味着您在进行提交K之前先进行了提交K :))。如果运行J,则Git将提取git diff H JH的快照并进行比较。如果运行J,则Git将提取git diff K JK的快照并进行比较。但是,如果您运行J,Git将:

提取git show J的快照,然后
提取H的快照,然后
提取K的快照(合并),最后
产生Git所谓的组合差异。

来自步骤4的组合差异试图以紧凑的方式显示从JHK的变化。在压缩更改时,Git会丢弃任何JH中的版本与K中的版本相匹配的文件。
也就是说,假设文件JREADME.txt更改为H。但是,假设JREADME.txtK中相同。换句话说,当您执行J时,您正在从git merge进行更改以生成K,并且在合并的另一端对J进行了更改。这意味着README.txt与一个“传入侧”完全匹配,因此组合的diff会完全忽略该文件。
这意味着合并的差异通常根本不显示任何内容,即使合并在新快照中产生了一些变化。要查看这些更改,您必须进行两个比较,而不仅仅是一个。您必须使一个从README.txtH的差异,另一个从JK的差异,而不是依靠组合的差异。
使用J时,还可以通过将git log -p-c添加到选项中来查看合并的合并差异。但是,如果您不要求这样做,那么Git所做的实际上是可笑的简单:它根本不用理会差异。
因此,这将导致答案2c:--cc。我们所做的只是删除git log -p --first-parent ^A dev:现在,我们将看到每个合并的日志消息,但没有差异。
--no-merges这是什么?
这也与您的其他问题有关:

顺便说一句,如果有人知道一种快速查找A而又不用继续滚动日志的方法,我将不胜感激。

答案是为commit ^A创建一个符号名称。一次找到其ID,然后选择一个名称,例如Adev(但由于正在使用中,请勿使用任何一个!)。
这就是masterdev的全部:它们只是提交的符号名,外加额外的属性,作为分支名称,您可以master符号名并在分支上“结束”。您也可以给git checkout一个分支名称。您将需要确保不对该分支进行A并对其进行提交,因为如果这样做,您将成长一个新的分支,而不是仅仅将分支名称保留为指向提交git checkout
或者,您可以使标记名称指向提交A。这几乎与分支名称完全相同。两者的区别是:

这是一个标签名称:您不能将其作为分支签出,因此不能意外更改它。
这是一个标签名称:如果您A您将其作为标签发送到上游,那么其他所有人也将拥有它。

在这种情况下,第1点对您有利,而第2点可能对您不利,因此,由优势(不能无意更改它)是否值得风险(可能无意间发布)取决于您。
如果您的ID为git push --tags,则可以:

$ git tag A <id-of-commit-A>

现在您的名字是 A。 (您以后可以 A删除它,尽管如果您不小心发布了它,则可能会继续从上游取回它。)
回到 git tag -d A命令中的 ^A字符串问题,所有 git log所做的就是告诉 ^A(因此是 git rev-list)在到达提交 git log时停止遍历提交图。提交也未显示(对于 A,未打印;对于 git rev-list,未显示在日志输出中)。前缀 git log符号是“ not”的缩写,即“让我可以从 ^访问所有提交,但不能从 dev访问所有提交”。添加 A使Git仅遍历每次合并的第一个父对象,这样我们就不会进入从 --first-parent合并的提交。
master语法也可以拼写为 ^A dev。请注意,这对 A..devgit log均适用,但是对于 git rev-list而言则有很大不同。)

关于git - 从master merge 后,如何找出分支上的变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39837542/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com