繁体   English   中英

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

[英]git log two branches, ignoring others

考虑这个示例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的第一个父branch1 ,但是合并提交没有绘制合并线,即使它们的第二个父项出现在日志中。

* 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 commit 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

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

不幸的是,没有。 问题源于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扫描收集节点,然后第二次重新扫描重新--first-parent图形,重新填充每个部分的核心内数据结构提交,抛出父链接到我们在第一次扫描期间没有加载的节点(而不是丢弃除第一次扫描之外的所有节点)。 这给了我们一个适合绘图的修改后的提交图,我们甚至不需要rev-list--stdin

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

我使用了这个答案中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("}")

如果你把这个文件放在你的$PATH作为git-log-dotchmod +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

整个回购

但只绘制masterbranch1的第一个父母看起来像哨子一样干净:

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

只是两个关键的分支

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM