当前位置:  开发笔记 > 开发工具 > 正文

Git:在特定分支上的两个提交之间获取提交

如何解决《Git:在特定分支上的两个提交之间获取提交》经验,为你挑选了2个好方法。

我已经阅读了类似场景的一些答案,但不是这个答案.

我需要在git上的特定分支上的两个提交之间生成一个提交列表.因此,应忽略对其他分支的任何提交.知道怎么做吗?



1> torek..:

"之间"的概念在这里有点模糊,术语"分支"也没有明确定义(一般用git,即).让我看看尽管存在这些问题我是否可以保持这么短(对我来说很难:-)):

我将假设"在"之间,你的意思是git提交图中路径的图论理论.举例来说,假设我们有这样的图形片段(我不能画箭头的节点之间的弧线,而是假装每个-,/\在左侧的箭头头,这样的提交点直左,下,和左,或上下左右,给他们的前任):

              o - o
            /       \
... - A - o - o - o - B   <-- branch-x
            \   /
              o - o - C   <-- branch-y

我已经确定了三个具体commits- A,BC-和提供了两个分支尖端的名称branch-xbranch-y指向提交BC分别.为了git-usefulness-purpose,我们还假设有一个A指向commit 的标记A,这样我们就不必拼出它的SHA-1.

您可以通过三种方式A从提交中获取提交B.一开始B,上升到顶线,下降到中间,然后向左移动A.一开始B,直接离开,最终到达A.最后一个开始B,向后退一步,向下,向左,向上和向左,再向左走一步A.

Git的为您提供了特殊的双点语法A..branch-x(或替代实际SHA-1的节点A,如果你没有一个标签命名A),这对于大多数命令,指示他们应该访问的所有节点上的所有可能路径B返回A,通常包括节点B本身和排除节点A.这几乎是你想要但不完全的,因为你想要排除在其他分支上进行的提交.

这就提出了一个无法回答的(一般性)问题"在哪个分支上做了哪些提交?"

Git试图告诉你这个问题是无效的:你不应该关心; 您应该只关心所有这些提交是否可以从节点访问B.Git实际上通常是对的,但"通常"不是"总是".不幸的是,我没有找到任何好的方法来描述你应该(或做)关心的时间(实际的好例子对我试图写的文本有帮助).

与此同时,让我们继续吧.从上图中可以清楚地看出,下线的提交都是"制作完成branch-y".这里有一个问题,因为它看起来很清楚,但实际上可能并非如此.考虑如果我们重新绘制图形会发生什么:

              o - o
            /       \
... - A - o - o - o - B   <-- branch-x
            \   /
              o
                \
                  o - C   <-- branch-y

这一次似乎branch-y是为了保持两个最低提交而创建的.(如果有另一个分支名称指向单独的第三行提交,则更有可能,因为您的原始问题语句表示要排除所有其他分支 - 不仅仅是分支branch-y- 在这种情况下并不重要.)

无论如何,虽然我不太清楚你的意思是"分支",也不知道你想要给出这个图的哪些提交,让我们来看看git实际提供的选择器.有一个重要的可能正是你的意思.

我之前提到"大多数"git命令使用相同的语法说明符.实际上,大多数git命令要么包含来自git rev-list程序的代码,要么只是运行程序,其作用是选择对象(通常是提交对象)以获取要使用的提交ID列表.它也是您想要用于任何类型脚本的命令.

rev-list命令有许多令人眼花缭乱的选项,其中许多可以帮助进行各种图形遍历.我认为,这里最有趣的两个是--first-parent--not.

运用 --first-parent

我们--first-parent先考虑一下.检查上面的图表(布局:它们可能看起来不同,但拓扑结构,它们是相同的).请注意,它是在合并提交时,如节点B本身和节点左侧的节点B,即路径fork.这是因为它只是具有多个传出弧的合并提交(这实际上是合并提交的定义:它是具有两个或更多父节点的节点).

当git进行合并提交时,它会将各个传出弧编号为多个父节点.第一个弧是特殊的:它是提交时当前分支.也就是说,当你这样做时git merge ,你当时在某个分支上,1和当前提交的SHA-1成为新合并提交的"第一个父".额外的父母(合并的ID,通常只有一个,但git允许更多)是第二个,第三个,依此类推.

使用该--first-parent标志告诉git仅遍历第一父弧.所以git rev-list --first-parent branch-x将从commit开始B,然后找到它的第一个父项(我们无法分辨哪个是上面的图中的第一个),遵循第一个(也是唯一的)父项,依此类推,一直回到root提交.

这可能是你想要的,也可能不是你想要的(尽管它对"之间"的概念没有帮助).

运用 --not

现在让我们来看看--not旗帜.2 通常,git rev-list 生成从给定SHA-1可到达的所有提交的集合(根据需要首先将名称解析为ID).也就是说,它遵循回到所有根的所有路径.结果是一组SHA-1 ID.使用--notmake会rev-list 排除这些ID.就其本身而言,这个否定集是没有用的,但是当与正常(非否定)集合结合时,它有用的.事实上,它首先是如何A..B工作的:rev-list首先生成可以访问的所有提交的集合B,然后减去可以从中访问的所有提交的集合A.

因此,根据您的意思"排除其他分支上的所有提交",可能是您想要的是:

git rev-list branch1 --not branch2 branch3 ... branchN

你只需列出除了branch1之后的每个分支--not.

如果我们最后一次查看我们的图表,让我们看看选择了哪些提交branch-x --not branch-y:

              o - o
            /       \
... - A - o - o - o - B   <-- branch-x
            \   /
              o - o - C   <-- branch-y

C显然可以从提交到达branch-y,就像最下面一行的所有提交一样.右边的提交A也是可以访问的,就像提交A本身和所有早期的提交一样.剩余的提交是从可到达的branch-y,但从可到达的branch-x提交B,因此所得到的图是:

              o - o
            /       \
            - o - o - B   <-- branch-x

注意,rev-list必须--boundary包括"剪切点"(如果我可以称之为); 添加--boundaryA原始图表中的节点放回原位(但A本身仍然被剪断).

(基于你修改过的问题,--not可能就是你想要的了,你只需要获得所有分支的列表,这git for-each-ref --format '%(refname:short)' refs/heads是正确的脚本命令.将你想要的节点分开的一个分支分开,把剩下的分支放在后面--not,并运行git rev-list.)


1即使您在匿名分支上(换句话说,在"分离的HEAD"模式下),这也是有效的.一些git命令会说你不在任何分支上,但你仍然在使用构建分支的相同git内部.在这种情况下,您当前的分支根本没有名称.

2技术上--not只是翻转一点,标记后续的SHA-1或标识符参数被否定.如果它们已经有前缀^符号,它们将成为"正面"引用,否则它们将成为否定引用.因此x ^y z意味着"是x,没有y,是z"而x --not y z意味着"是x,没有y,没有z"并且x --not y ^z意味着"是x,没有y,是z".



2> Sazzad Hissa..:

您可以使用以下命令轻松找到提交列表,

git log branch_name commit_x..commit_y

例如,

git log dev HEAD~20..HEAD~10会告诉你10名单至20 为分支提交dev

您还可以通过的参数过滤所需的任何内容git log

您还可以使用以下命令将该日志存储到文件中 git log dev HEAD~20..HEAD~10 >> logs.txt

推荐阅读
Gbom2402851125
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有