如何使用GIT-log命令在GIT分支内提取合并文件列表以及其他提交?例如,下面给出了示例命令,
git log--after="11/29/2016"--before="11/20/2016"--漂亮='format:%cd%h'--名称状态--日期=短本地
来自注释:
合并文件是指通过合并(来自其他分支)的提交。
因此,您真正想要的是从合并提交M的第二个到n父级找到可访问的提交,不包括从M第一个父级可访问的所有提交。
普通的合并提交有两个父级M^1
和M^2
(此语法来自gitrevisions)。因此,如果合并提交M
有99个父级,那么它们是M^1
、M^2
、M^3
,依此类推,一直到M^99
。我们使用^
(帽子或插入符号)字符,后跟一个数字N,写在任何提交说明符之后,表示"该提交的第N个父级"。提交说明符通常只是一个原始散列(如git log
输出):face0ff
。
为了排除提交,我们在它们前面加上相同的^
(帽子或插入符号)字符。如果M
有那99个父母,我们就写^M^1 M^2 M^3 M^4 ... M^99
。但目前,我们可以假设有两个父母,而不必一直计算到99。
因此,我们只需要找到M
的哈希ID,而不是--since
和--until
(也称为--after
和--before
)——假设它最终是face0ff
——并运行:
git log [options ...] ^face0ff^1 face0ff^2
(有一种特殊的、更通用的语法,即使适用于Git的"章鱼合并",比如99父合并:我们编写M^@
来选择所有的章鱼合并。然后,为了排除第一个,我们添加^M^1
。排除我们已经包含的一个也没问题:排除最终会覆盖。)
这是如何以及为什么工作的
给定一系列提交(左边是较旧的提交,右边是较新的提交,并显示存储库中的两个分支名称,我给出了特别有趣的提交字母名称或*
标记):
...--o--*--o---------X <-- develop
A--B--C--D--E <-- feature
我们将在分支develop
上进行一个新的合并提交,它引入了分支feature
独有的五个提交:
...--o--*--o---------X--M <-- develop
/
A--B--C--D--E <-- feature
之后,我们可能会也可能不会在develop
上进行更多的提交,甚至可能删除分支namefeature
:
...--o--*--o---------X--M--o--o <-- develop
/
A--B--C--D--E
提交本身——A
到E
——永远保留在图中,由名称develop
保护(并且可访问),因为从develop
向后工作,我们可以找到M
,并且M
有两个父级。
任何合并的第一个父级总是提交,当我们进行合并时,是分支的顶端。在本例中,这是提交X
,位于最上面一行。因此,我们对第一个父对象根本不感兴趣;我们想要第二个父级1
现在,请注意提交*
。这是(显然,从图形的可视化来看)两个子分支分离的点。关于提交*
,特别有趣的是它在两个分支上即使在我们进行合并提交之前也是如此2之后它仍然是真的,但是在我们进行提交之后,合并导致提交A
到E
也在分支develop
上!也就是说,提交*
-和更早的版本在该分支上总是,但提交A-B-C-D-E
在我们进行合并后"联合"。它们现在位于两个分支上,就像合并前提交*
一样。
如果您愿意,您可以将提交(包括合并提交)视为铁路线上的站点,其特点是铁路只运行一种方式:从今天到过去。如果你在develop
的尖端上车,当你到达火车站M
时,你可以选择:"直回"到X
,或者"下返"到E
。如果你去E
,你可以到达D
到A
的火车站,但如果你回到X
,你会跳过这些站。然而,无论你走哪条路,如果你继续前进,你最终会到达*
火车站。
git log
的工作方式是从今天"穿越铁轨"回到过去,向您展示沿途的每一个"铁轨停靠"(commit)。当它到达像M
这样的分叉时,它会占用两条路线(并按3的顺序向您显示这两条路线)。最终,分叉重新加入(在提交*
时),它可以返回到显示一条路线上的站点,而不是两个或多个。
但是,如果您告诉git log
停止向您显示某些提交,它(当然)将停止显示这些提交。这里有一个棘手的部分:它不仅停止了那些提交,还停止了所有早期的提交。所以我们用它。我们说:"一旦您到达M^1
本身或可从M^1
访问的任何提交,请停止进一步遍历历史。">
因此,^M^1
是告诉git log
的一种简单方法:"不要让我提交*
,或更早的任何东西。"使用M^2
,会告诉git log
:"当你去寻找提交给我看时,一定要从提交M^2
开始看。"我们不必自己找到提交*
:我们只需要意识到从M^1
开始的链最终会到达*
。
这个"可达性"概念是理解Git的关键
1如果这是一个章鱼合并——Git称之为任何有三个或更多父母的合并——我们可能也想要更多的父母。
2这是Git的一个奇怪之处。在其他版本控制系统(VCSe)中,当创建分支时,它会获得某种独特性,从那时起,在该分支上进行的新提交只会在该分支中进行。即使在合并之后,在其他VCSE中,这仍然是正确的:只有在某个特定分支上进行的提交才会在该分支上;并且那些提交在该分支上总是。Git中的情况并非如此,因为在Git中,我们可以移动分支名称,甚至完全删除它们。提交本身保持不变,但名称发生了更改!
3你应该立即问:等等,点什么不过,答案必须另辟蹊径。我在这里要说的是,订单由更多选项控制。