首先,git log --graph --oneline --decorate
不是我想做的。
通常我运行git log -p --all -G pattern
,我希望我能看到已进行更改的分支名称。有什么办法可以做到这一点吗?
这可能是一个不恰当的问题,因为据我所知,Git 没有明确记录进行提交的分支的名称,当我们有多个分支时,我们无法唯一地关联,比如说,存储库中的第一个分支与它们。
试试这个。您可以自定义--pretty-format
以设置颜色,交换输出值等。
$ git log -p --all -G pattern --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset%n' --branches
通过此命令,您可以看到commit-hash
、branch-name
、commit-message
、time
、committer-name
和changes of the commits
。
这可能是一个不恰当的问题,因为据我了解,Git 没有明确记录进行提交的分支的名称,当我们有多个分支时,我们不能唯一地关联,比如说,存储库中的第一个分支与它们。
没错。
根本问题是分支名称(如果有的话)可能没有分支名称,例如,如果您处于"分离的 HEAD"模式,则不是提交的一部分。 此外,可以在提交后随时添加、更改和删除分支名称,以便任何给定的提交都可以位于 no、一个或多个分支上,并且包含分支的集合会动态更改。
这与大多数版本控制系统形成鲜明对比。 例如,在 Mercurial 中,进行提交的分支的名称是提交的一部分。 该提交永远位于该分支上,并且永远不会在任何其他分支上。 每个提交都只在一个分支上,很容易将提交 ID 转换为分支名称。 在 Git 中,提交位于零个或多个分支上,当它位于多个分支上时,它会同时在所有分支上。
因此,在 Git 中,分支名称——就此而言,标签名称和所有其他引用,包括HEAD
本身——基本上是无关紧要的,除了一个关键点:引用是我们(和 Git)获得提交图入口的方式。 每个提交(实际上是每个 Git 对象)的身份都是其丑陋的大 SHA-1 哈希。 该唯一 ID 在存储库中定位对象。 引用(主要是分支和标签名称)让我们从图中开始,然后每个提交都有一个对其父级的引用,或者通过其原始 ID 对其多个父级的多个引用。
正如 Schwern 在评论中指出的那样,git branch --contains
将找到可以访问某些 Git 对象的名称。 Git 的log
具有%d
和%D
格式,它们执行--decorate
所做的操作,但它们只会显示哪些引用直接指向正在显示的提交,而-Gregex
只选择添加或删除与给定正则表达式匹配的行的提交。1因此,如果您有这样的图形片段:
...-o--o--*--o <-- branch1
o--o--* <-- branch2
如果标记为*
的两个提交被-G
模式参数选中,branch2
顶端的提交将被修饰(因为refs/heads/branch2
提交的名称),但从branch1
的顶端后退一步的提交不会(因为没有分支直接指向它)。
(如果有一个标签,无论是轻量级的还是带注释的,指向可从branch1
访问的*
提交,%d
将显示该标签的名称。
许多 Git 命令遍历提交图——主要是通过调用git rev-list
或内置git rev-list
(例如,git log
和git rev-list
是从同一个 C 源文件构建的,该文件有两个不同的类似main
函数,根据我们是否只需要哈希值(即rev-list
)或生成人类可读的文本来选择, 即log
)。 图形的入口点通常是HEAD
和/或一些分支和/或标记名称。--all
选项表示"所有引用":所有分支和标记名称、refs/stash
引用、refs/notes
下的所有内容,等等。
1为此,git log
/git rev-list
必须将每个提交与其父提交进行比较。 这对于具有多个父项的合并提交来说是有问题的。 它如何工作的确切细节非常模糊,但值得指出的是,merge 提交会弄乱历史简化代码,您可能希望两个--full-history
都禁用侧分支修剪,-m
拆分合并提交,以便 N 父合并产生N个单独的差异,每个父级一个,这样,如果任何一个这样的差异包含该表达式,则可以选择拆分合并本身。