[英]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
分支的两个分支( branch1
和branch2
); 我们将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
在这个例子中,我主要感兴趣的是master
和branch1
之间的合并; 我对其他已合并为master
分支的提交不感兴趣。 在这种情况下,只有另一个分支( branch2
)并且它只有一个提交,所以它不会太糟糕地破坏图形,但是当游戏中有更多分支时它会变得更糟,但我只想专注于master
和branch1
。
如果我使用git log --graph --oneline --first-parent master branch1
,图形看起来几乎正确,只观察master
和branch1
的第一个父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-dot
和chmod +x git-log-dot
,如果你输入git log-dot
, git
会自动运行它。 (当git
作为单独的脚本分发, git-checkout
, git-reset
等时,这是遗留下来的保留)
你还需要Graphviz。 在macOS上我用brew install graphviz
安装它; 在Ubuntu上我相信你可以用sudo apt-get graphviz
安装它。
绘制整个回购图仍然看起来有点令人困惑:
git log-dot | dot -Tpng -o graph.png
但只绘制master
和branch1
的第一个父母看起来像哨子一样干净:
git log-dot --first-parent master branch1 | dot -Tpng -o graph.png
(在上面的示例中,我还使用了-Grankdir = LR来使图形水平,但默认的垂直方向也非常好。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.