忽略其他分支,查看两个分支的git日志记录。

3
考虑这个示例git仓库。
#!/bin/bash -e
rm -rf example
git init example
cd example
echo 0 > file.txt
git add file.txt
git commit -am "initial commit"
git branch branch1
echo 1 > file.txt
git commit -am "1 (on master)"
git branch branch2
git checkout branch1
echo 2 > file2.txt
git add file2.txt
git commit -m "2 (on branch1)"
git merge --no-edit master
echo 3 > file2.txt
git commit -am "3 (on branch1)"
git checkout master
echo 4 > file.txt
git commit -am "4 (on master)"
git checkout branch1
git merge --no-edit master
echo 5 > file2.txt
git commit -am "5 (on branch1)"
git checkout branch2
echo 6 > file3.txt
git add file3.txt
git commit -m "6 (on branch2)"
git checkout master
git merge --no-edit branch2
git merge --no-edit branch1

上面的脚本从master分支创建了两个分支(branch1branch2);我们多次将master合并到branch1中,最后将branch1合并回master。同时,在branch1合并回来之前,我们将branch2合并回master
如果我在master上运行git log --graph --oneline,结果看起来很复杂。
*   4f71184 Merge branch 'branch1'
|\
| * d58e9f0 5 (on branch1)
| *   b19c9b4 Merge branch 'master' into branch1
| |\
| * | 212f4d6 3 (on branch1)
| * |   1ac0082 Merge branch 'master' into branch1
| |\ \
| * | | 26cf8e0 2 (on branch1)
* | | |   9aaa8c5 Merge branch 'branch2'
|\ \ \ \
| |_|_|/
|/| | |
| * | | 425aead 6 (on branch2)
| | |/
| |/|
* | | 67a7fed 4 (on master)
|/ /
* | 6a56133 1 (on master)
|/
* 0d4f076 initial commit

在这个例子中,我主要关注masterbranch1之间的合并;我不关心其他分支上合并到master的提交。在这种情况下,只有另一个分支(branch2),它只有一个提交,所以它不会对图表造成太大的影响,但当有很多分支参与时,情况会变得更加复杂,但我只想关注masterbranch1
如果我使用git log --graph --oneline --first-parent master branch1命令,图表看起来几乎正确,只观察masterbranch1的第一个父节点,但是即使它们的第二个父节点出现在日志中,合并提交也没有绘制合并线。
* 4f71184 Merge branch 'branch1'
| * d58e9f0 5 (on branch1)
| * b19c9b4 Merge branch 'master' into branch1
| * 212f4d6 3 (on branch1)
| * 1ac0082 Merge branch 'master' into branch1
| * 26cf8e0 2 (on branch1)
* | 9aaa8c5 Merge branch 'branch2'
* | 67a7fed 4 (on master)
* | 6a56133 1 (on master)
|/
* 0d4f076 initial commit

我认为我想要的东西是这样的,日志中删除branch2提交425aead。(再次说明,虽然不太清晰,但如果有更多像branch2这样的分支,这个值就会更加明显。)

*   4f71184 Merge branch 'branch1'
|\
| * d58e9f0 5 (on branch1)
| *   b19c9b4 Merge branch 'master' into branch1
| |\
| * | 212f4d6 3 (on branch1)
| * |   1ac0082 Merge branch 'master' into branch1
| |\ \
| * | | 26cf8e0 2 (on branch1)
* | | |   9aaa8c5 Merge branch 'branch2'
|  \ \ \
|  _|_|/
|/  | |
|   |/
|  /|
* | | 67a7fed 4 (on master)
|/ /
* | 6a56133 1 (on master)
|/
* 0d4f076 initial commit

有没有办法在这里得到我想要的东西?
2个回答

0

很遗憾,没有。这个问题源于git log将其提交选择过程与其图形绘制过程相结合的方式。如果没有 --first-parent,它会跟踪每个合并提交的所有父级,但是使用 --first-parent,它就会剥离掉其他父级,所以当它到达绘制节点连接的时候,即使它正在绘制的两个提交具有合并链接,该链接也会从内部数据结构中消失

如果您可以在git log中结合使用 --no-walk--graph,那么这样做就可以实现:

git rev-list --first-parent master branch1 |
    git log --no-walk --stdin --decorate --oneline --graph

即,我们将首先收集要显示的节点(使用git rev-list),然后指示git log重新获取这些特定的提交图节点,包括完整的父级信息,并将它们按可绘制的图形形式排序,然后绘制它们。但是你不能:

fatal: cannot combine --no-walk with --graph

这实际上是一个相当困难的问题,尽管似乎有一种折中的解决方案可以实现,如果您决定深入挖掘git log的图形绘制代码。基本上,我们想要将日志记录分成两个部分:一个--first-parent扫描以收集节点,然后进行第二次重新扫描,重新遍历图形,重新填充每个提交的内核数据结构,在第一次扫描期间丢弃与未加载的节点的父链接(而不是丢弃除第一个之外的所有节点)。这给了我们一个修改过的提交图,适合绘制,我们甚至不需要rev-list--stdin


0

git log --graph 无法正确显示,但使用 dot(又名Graphviz)生成正确的图形非常容易。

我使用了this answer中的git-log-dot脚本:

#!/usr/bin/python
import subprocess, sys, re

args = ['git', 'log', '--pretty=format:%x00%H%x01%h%x01%P%x00'] + sys.argv[1:]

rows = subprocess.check_output(args).split('\x00')[1::2]

seen_commits = set([row.split('\x01')[0] for row in rows])

print("digraph G {")
for row in rows:
    columns = row.split('\x01')
    commit = columns[0]
    label = columns[1]
    print('"{}" [label="{}"];'.format(commit, label))
    for parent in columns[2].split(' '):
        if parent == "":
            continue
        if not parent in seen_commits:
            continue
        print('"{}" -> "{}"'.format(commit, parent))
print("}")

如果您将该文件作为git-log-dot放在$PATH上,并使用chmod +x git-log-dot,如果您输入git log-dotgit将自动运行它。(这是旧版本的遗留物,当时git被分发为单独的脚本,如git-checkoutgit-reset等。)

您还需要Graphviz。在macOS上,我使用brew install graphviz进行安装;在Ubuntu上,我认为您可以使用sudo apt-get graphviz进行安装。

图形化整个仓库看起来仍然有些混乱:

git log-dot | dot -Tpng -o graph.png

entire repo

但是仅绘制masterbranch1的第一个父级看起来非常干净:

git log-dot --first-parent master branch1 | dot -Tpng -o graph.png

just two key branches

在上面的示例中,我还使用了-Grankdir=LR使图形水平化,但默认的垂直方向也很好。

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