git 日志 : show second parent on the left

标签 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 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 到的分支。)

  1. 有没有办法说服 git log 生成我更喜欢的更简单的图表?有一个 old gist from 2013建议解决此问题(“让我指定哪些分支向左下沉”;那里也有其他有趣的想法),但我看不到这方面的进展。
  2. 假设 git log 不能自然地做到这一点,我可以使用另一个 git commit 绘图工具/库来制作这样的图表吗?

最佳答案

感谢torek's suggestion试试dot (又名 Graphviz )我编写了这个 Python 脚本以在 dot 中生成输出文件格式。它生成了一个这样的图表,对我来说看起来很不错:

enter image description here

#!/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-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 生成 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/

相关文章:

git - 为什么 .gitignore 和 .metadata 没有被提交?

git - 我怎么知道 repo 将 "push"到哪里?

git - --follow-tags 似乎不适用于 `git push`

git - 更改 git 提交历史记录但保留更改

git - 读取 GIT merge 标记

php - 是否应该使用 git checkin capistrano 配置文件?

Git:使用 git hook 将回车符\r 转换为新行\n?

git - 列出来自单个远程的 git 分支

git - 连接后从代理收到 HTTP 代码 501

Git 忽略和 Maven 目标