考虑这个示例 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 master
git merge --no-edit --no-ff branch1
git log --graph --oneline
我们创建一个分支 branch1
,从 master
分支向上 merge 几次,最后 merge 回 master
。
git log --oneline --graph
看起来奇怪地扭曲了。
* 2c3b97a Merge branch 'branch1'
|\
| * 1d722df 5 (on branch1)
| * 54039b6 Merge branch 'master' into branch1
| |\
| |/
|/|
* | d80d82c 4 (on master)
| * 2399286 3 (on branch1)
| * 9a0cb38 Merge branch 'master' into branch1
| |\
| |/
|/|
* | 31df841 1 (on master)
| * 5809072 2 (on branch1)
|/
* 08fc7a6 initial commit
如果它看起来像这样,图表会更简单:
* 2c3b97a Merge branch 'branch1'
|\
| * 1d722df 5 (on branch1)
| * 54039b6 Merge branch 'master' into branch1
|/|
* | d80d82c 4 (on master)
| * 2399286 3 (on branch1)
| * 9a0cb38 Merge branch 'master' into branch1
|/|
* | 31df841 1 (on master)
| * 5809072 2 (on branch1)
|/
* 08fc7a6 initial commit
据我所知,它看起来不像那样的原因是 git log
总是喜欢在右侧显示每个 merge 提交的“第二个父级”,所以对于每个 merge 提交,它都必须向右蛇行。 (“第二父”是 merge 进来的分支;“第一父”是我们要 merge 到的分支。)
- 有没有办法说服
git log
生成我更喜欢的更简单的图表?有一个 old gist from 2013建议解决此问题(“让我指定哪些分支向左下沉”;那里也有其他有趣的想法),但我看不到这方面的进展。 - 假设
git log
不能自然地做到这一点,我可以使用另一个 git commit 绘图工具/库来制作这样的图表吗?
最佳答案
感谢torek's suggestion试试dot
(又名 Graphviz )我编写了这个 Python 脚本以在 dot
中生成输出文件格式。它生成了一个这样的图表,对我来说看起来很不错:
#!/usr/bin/env python3
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(b'\x00')[1::2]
seen_commits = set([row.split(b'\x01')[0].decode() for row in rows])
print("digraph G {")
for row in rows:
columns = row.split(b'\x01')
commit = columns[0].decode()
label = columns[1].decode()
parents = columns[2].decode().split(' ')
print('"{}" [label="{}"];'.format(commit, label))
for parent in parents:
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
如果您键入 git log-dot
将自动运行它. (这是 git
作为单独脚本分发时的遗留问题, git-checkout
、 git-reset
等)
您还需要 Graphviz。在 macOS 上,我用 brew install graphviz
安装了它;在 Ubuntu 上,我相信你可以用 sudo apt-get graphviz
安装它.
您可以使用 git log-dot
生成 PNG 文件像这样:
git log-dot | dot -Tpng -o graph.png
(在上面的示例中,我还使用了 -Grankdir=LR
使图形水平,但默认的垂直方向也很不错。)
关于git 日志 : show second parent on the left,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42820177/