git log两个分支,忽略其他分支

时间:2017-03-15 20:03:55

标签: git

考虑这个示例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

上面的脚本在branch1分支之外创建了两个分支(branch2master);我们将master合并到branch1几次,然后最终将branch1合并回master。同时,我们会在branch2合并之前将master合并回branch1

如果我在主人身上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 :(得分:0)

不幸的是,没有。问题源于git log将其提交选择过程与其绘图过程相结合的方式。没有--first-parent,它跟随每个合并提交的所有父项 - 但 --first-parent,它剥离其他父项,以便当它到达节点之间的连接点时,即使它绘制的两个提交都有一个合并链接,链接也是从内部数据结构中消失

如果您可以在--no-walk中合并--graphgit log,则可以这样做:

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

答案 1 :(得分:0)

git log --graph不会做正确的事情,但使用dot(又名Graphviz)生成正确的图表非常容易。

我使用了来自this answergit-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("}")

如果您将该文件放在$PATH git-log-dotchmod +x git-log-dot上,git会在您输入git log-dot时自动运行该文件。 (这是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使图形水平,但默认的垂直方向也非常好。)

相关问题