首页
/ Mermaid GitGraph 图完全指南:从 commit/branch/merge 语法到主题变量的源码级解析

Mermaid GitGraph 图完全指南:从 commit/branch/merge 语法到主题变量的源码级解析

2026-09-06 14:48:22作者:凤尚柏Louis

本文基于 Mermaid 仓库的官方语法文档 gitgraph.md 展开,系统讲解 Git Graph 图的声明式语法——commitbranchcheckoutmergecherry-pick 五大操作,全部 gitGraph 配置项(showBranchesmainBranchNameparallelCommits 等)、LR/TB/BT 方向控制与 git0~git7 系列主题变量。结合 packages/mermaid/src/diagrams/git/gitGraphAst.ts 等源码,你将既会写图,也能理解每个语法糖背后的状态机与校验规则。

什么是 Git Graph 图

Git Graph 是对 Git 提交与 Git 操作(命令)在各分支上的图形化表示。这类图对开发者和 DevOps 团队分享 Git 分支策略特别有用,例如直观展示 Git Flow 的工作方式。

一个最基础的示例,标题通过 front matter 的 title 指令设置:

---
title: Example Git diagram
---
gitGraph
   commit
   commit
   branch develop
   checkout develop
   commit
   commit
   checkout main
   merge develop
   commit
   commit

Mermaid 支持四个基本 Git 操作:

  • commit:在当前分支上表示一次新提交;
  • branch:创建并切换到新分支,将其设为当前分支(等价于 git 中创建分支并 checkout);
  • checkout:切换到已存在的分支,并将其设为当前分支(checkoutswitch 可以互换使用);
  • merge:把一个已存在的分支合并进当前分支。

借助这几个关键命令,你可以非常快速地在 Mermaid 中画出 Git 图。

从源码结构看,GitGraph 图由 gitGraphDiagram.ts 注册为标准的 DiagramDefinition:解析器(gitGraphParser.ts,由 Jison 生成)、数据模型(gitGraphAst.ts 导出的 db 对象)、渲染器(gitGraphRenderer.ts)与样式(styles.js)各司其职。所有状态都收敛在 gitGraphAst.ts 的一个 ImperativeState 中,包含 commits(提交映射)、branches(分支到 HEAD 提交的映射)、currBranch(当前分支)、direction(方向,默认 'LR')与自增序号 seq 等字段,这正是"每条命令按书写顺序依次作用"这一声明式语义的实现基础。

声明式语法与初始状态

GitGraph 语法非常直接:它是一种声明式写法,每个提交按其在代码中出现的顺序依次画在时间线上,即按插入顺序逐条执行命令。

第一步是用 gitGraph 关键字声明图类型,它告诉 Mermaid 你要画一张 Git 图并按此解析后续代码。

每个 Git 图都从 main 分支初始化,因此除非创建其他分支,提交默认都会落在 main 上——这与 Git 本身的工作方式一致(最初总是从 main 分支,即旧称的 master 分支开始),并且 main 分支默认就是当前分支

三个提交都落在默认 main 分支上的最小图:

    gitGraph
       commit
       commit
       commit

仔细观察上面的图:默认分支 main 上有三个提交,并且每个提交都被赋予了唯一且随机的 ID。源码印证了这一点:当未提供 id 时,commit 函数 生成的 ID 是 seq + '-' + 7位随机串(随机串由 getID() 产生)。

自定义 commit ID

声明提交时可以用 id 属性指定自定义 ID,格式为 id: 加双引号包裹的值,例如 commit id: "your_custom_id"

    gitGraph
       commit id: "Alpha"
       commit id: "Beta"
       commit id: "Gamma"

在实现中,commit 会把 idmsg 统一经过 common.sanitizeText 清洗;若 ID 已存在,源码只记录 warn("Commit ID ... already exists"),不会中断渲染。

修改 commit 类型

Mermaid 中提交有三种类型,在图中的图形略有差异:

  • NORMAL:默认提交类型,实心圆表示;
  • REVERSE:强调某次提交为"回退提交",带叉的实心圆表示;
  • HIGHLIGHT:高亮某次提交,实心矩形表示。

type 属性声明,例如 commit type: HIGHLIGHT。未指定时默认取 NORMAL。三种类型与自定义 ID 组合的示例:

    gitGraph
       commit id: "Normal"
       commit
       commit id: "Reverse" type: REVERSE
       commit
       commit id: "Highlight" type: HIGHLIGHT
       commit

添加 Tag

你可以像 Git 中的 tag/release 概念一样,用 tag 属性给提交打标签:commit tag: "your_custom_tag"idtypetag 这些属性可以在同一条提交声明中任意混搭:

    gitGraph
       commit
       commit id: "Normal" tag: "v1.0.0"
       commit
       commit id: "Reverse" type: REVERSE tag: "RC_1"
       commit
       commit id: "Highlight" type: HIGHLIGHT tag: "8.8.4"
       commit

创建新分支

使用 branch 关键字并给出新分支名。分支名必须唯一,不能与已有分支重名;如果分支名容易与关键字混淆,需要用 "" 引号包裹。用法示例:branch developbranch "cherry-pick"

Mermaid 读到 branch 时会创建该分支并将其设为当前分支,等价于 Git 中"创建并切换"。这一点在源码 branch 函数 中可以直接看到:它先校验重名(抛出 "Trying to create an existing branch..." 错误),然后把新分支的 HEAD 指向当前 head,最后自动调用 checkout(name)

    gitGraph
       commit
       commit
       branch develop
       commit
       commit
       commit

起始于默认 main 分支并推送两个提交;创建 develop 分支后,其成为当前分支,之后的所有提交都落在 develop 上。

切换(checkout)已存在分支

使用 checkout 关键字并给出一个已存在的分支名;若找不到该分支会报控制台错误。用法示例:checkout develop

源码 checkout 函数 的校验逻辑:分支不存在时抛出 "Trying to checkout branch which is not yet created" 错误;存在时更新 currBranch,并把 head 定位到该分支记录的 HEAD 提交(若该分支尚无提交则 head 置为 null)。

    gitGraph
       commit
       commit
       branch develop
       commit
       commit
       commit
       checkout main
       commit
       commit

在上一例基础上,用 checkout main 把当前分支切回 main,其后的两个提交注册到 main 上。

合并两个分支

使用 merge 关键字并给出要合并进来的分支名。找不到该分支会报错;只能合并两个不同的分支,不能把一个分支合并到自身(会抛错)。用法示例:merge develop

Mermaid 读到 merge 时,找到目标分支及其 HEAD 提交,把它与当前分支的 HEAD 提交连接,每次合并都会产生一个合并提交(merge commit),图中以实心双圆表示。

merge 函数 的校验链相当严格,与文档描述的规则一一对应:

  1. 当前分支与目标分支是同一分支 → "Cannot merge a branch to itself";
  2. 当前分支没有任何提交 → "Current branch (...) has no commits";
  3. 目标分支不存在 → "Branch to be merged (...) does not exist";
  4. 目标分支没有任何提交 → "Branch to be merged (...) has no commits";
  5. 两个分支 HEAD 相同 → "Both branches have same head";
  6. 自定义 id 与已有提交 ID 冲突 → 报错并要求换一个唯一 ID。
    gitGraph
       commit
       commit
       branch develop
       commit
       commit
       commit
       checkout main
       commit
       commit
       merge develop
       commit
       commit

develop 被合并进 main,产生一个合并提交;当前分支仍是 main,最后两个提交注册到 main

合并提交也可以像提交一样装饰属性,可以一个都不用、部分用或全用:

  • id:用自定义 ID 覆盖默认 ID;
  • tag:给合并提交添加自定义 tag;
  • type:覆盖合并提交的默认形状(使用前面提到的 commit 类型)。

例如:merge develop id: "my_custom_id" tag: "my_custom_tag" type: REVERSE。下面是一个多分支交叉的完整例子,最后一行演示了带属性的合并:

    gitGraph
       commit id: "1"
       commit id: "2"
       branch nice_feature
       checkout nice_feature
       commit id: "3"
       checkout main
       commit id: "4"
       checkout nice_feature
       branch very_nice_feature
       checkout very_nice_feature
       commit id: "5"
       checkout main
       commit id: "6"
       checkout nice_feature
       commit id: "7"
       checkout main
       merge nice_feature id: "customID" tag: "customTag" type: REVERSE
       checkout very_nice_feature
       commit id: "8"
       checkout main
       commit id: "9"

从其他分支 cherry-pick 提交

与真实 Git 类似,Mermaid 支持用 cherry-pick 关键字把另一个分支上的提交摘到当前分支。必须用 id 属性给出要摘取的提交 ID:cherry-pick id: "your_custom_id"。执行后,当前分支上会创建一个代表 cherry-pick 的新提交,以樱桃图形高亮,并带有一个标注来源提交 ID 的 tag。

五条重要规则(与 cherryPick 函数 的校验逻辑一致):

  1. 必须提供已存在的提交 id,不存在则报错——因此要先用 commit id:"..." 的方式声明提交;
  2. 被摘取的提交不能已存在于当前分支,cherry-pick 的提交必须来自其他分支;
  3. 当前分支在执行 cherry-pick 之前必须至少有一个提交,否则抛错;
  4. cherry-pick 合并提交时,parent 属性必填,省略或提供无效父提交 ID 都会抛错;
  5. 指定的父提交必须是该合并提交的直接父提交(源码用 sourceCommit.parents.includes(parentCommitId) 校验)。

示例:

    gitGraph
        commit id: "ZERO"
        branch develop
        branch release
        commit id:"A"
        checkout main
        commit id:"ONE"
        checkout develop
        commit id:"B"
        checkout main
        merge develop id:"MERGE"
        commit id:"TWO"
        checkout release
        cherry-pick id:"MERGE" parent:"B"
        commit id:"THREE"
        checkout develop
        commit id:"C"

源码层面还有一个细节:cherry-pick 生成的提交类型是 commitType.CHERRY_PICK,若未显式提供 tag,会自动附加 cherry-pick:<来源ID>(合并提交还会带 |parent:<父ID>)作为 tag,这就是图中樱桃节点上出现来源标注的由来。

GitGraph 专属配置项

Mermaid 提供一组 gitGraph 配置项,可以在 front matter 的 config 指令中设置。完整清单:

配置项 类型 默认值 说明
showBranches Boolean true 设为 false 时图中不显示分支名与分支线
showCommitLabel Boolean true 设为 false 时图中不显示提交标签
mainBranchName String main 默认/根分支的名称
mainBranchOrder Number 0 main 分支在分支列表中的位置,默认 0 即排在最前
parallelCommits Boolean false 设为 true 时,距父提交 x 个距离的提交画在同一层,不体现时间先后
rotateCommitLabel Boolean true 提交标签是否旋转 45 度(详见下文布局小节)

这组配置的类型定义见 config.type.ts 中的 GitGraphDiagramConfig,默认值由 schemas/config.schema.yaml 加载(defaultConfig.ts 中从 JSON Schema 读取),而运行时读取走 getConfig():用 cleanAndMerge 把默认值与用户通过 mermaid.initialize() 或 front matter 传入的 gitGraph 配置合并。单元测试 gitGraph.spec.ts 也逐条断言了 showBranchesshowCommitLabelrotateCommitLabelparallelCommits 属性存在。

隐藏分支名和分支线

showBranches: false 隐藏分支名和线(渲染器 gitGraphRenderer.tsshowBranches 为真时才绘制分支元素):

---
config:
  logLevel: 'debug'
  theme: 'base'
  gitGraph:
    showBranches: false
---
      gitGraph
        commit
        branch hotfix
        checkout hotfix
        commit
        branch develop
        checkout develop
        commit id:"ash" tag:"abc"
        branch featureB
        checkout featureB
        commit type:HIGHLIGHT
        checkout main
        checkout hotfix
        commit type:NORMAL
        checkout develop
        commit type:REVERSE
        checkout featureB
        commit
        checkout main
        merge hotfix
        checkout featureB
        commit
        checkout develop
        branch featureA
        commit
        checkout develop
        merge hotfix
        checkout featureA
        commit
        checkout featureB
        commit
        checkout develop
        merge featureA
        branch release
        checkout release
        commit
        checkout main
        commit
        checkout release
        merge main
        checkout develop
        merge release

提交标签布局:旋转或水平

Mermaid 支持两种提交标签布局,默认是旋转(rotated):标签放在提交圆下方并旋转 45 度,便于阅读,对长标签特别友好;另一种是水平(horizontal):标签水平居中放在提交圆下方,不旋转,适合短标签。用 rotateCommitLabel 关键字切换,默认 true(旋转)。

旋转布局:

---
config:
  logLevel: 'debug'
  theme: 'base'
  gitGraph:
    rotateCommitLabel: true
---
gitGraph
  commit id: "feat(api): ..."
  commit id: "a"
  commit id: "b"
  commit id: "fix(client): .extra long label.."
  branch c2
  commit id: "feat(modules): ..."
  commit id: "test(client): ..."
  checkout main
  commit id: "fix(api): ..."
  commit id: "ci: ..."
  branch b1
  commit
  branch b2
  commit

水平布局(仅把 rotateCommitLabel 改为 false,图体不变):

---
config:
  logLevel: 'debug'
  theme: 'base'
  gitGraph:
    rotateCommitLabel: false
---
gitGraph
  commit id: "feat(api): ..."
  commit id: "a"
  commit id: "b"
  commit id: "fix(client): .extra long label.."
  branch c2
  commit id: "feat(modules): ..."
  commit id: "test(client): ..."
  checkout main
  commit id: "fix(api): ..."
  commit id: "ci: ..."
  branch b1
  commit
  branch b2
  commit

隐藏提交标签

showCommitLabel: false 隐藏提交标签。与上一节组合使用的示例(showBranchesshowCommitLabel 同时关闭):

---
config:
  logLevel: 'debug'
  theme: 'base'
  gitGraph:
    showBranches: false
    showCommitLabel: false
---
      gitGraph
        commit
        branch hotfix
        checkout hotfix
        commit
        branch develop
        checkout develop
        commit id:"ash"
        branch featureB
        checkout featureB
        commit type:HIGHLIGHT
        checkout main
        checkout hotfix
        commit type:NORMAL
        checkout develop
        commit type:REVERSE
        checkout featureB
        commit
        checkout main
        merge hotfix
        checkout featureB
        commit
        checkout develop
        branch featureA
        commit
        checkout develop
        merge hotfix
        checkout featureA
        commit
        checkout featureB
        commit
        checkout develop
        merge featureA
        branch release
        checkout release
        commit
        checkout main
        commit
        checkout release
        merge main
        checkout develop
        merge release

自定义 main 分支名

mainBranchName 把默认分支改成任意字符串。下面把默认分支改名为 MetroLine1,画了一张"想象中的地铁线路图":

---
config:
  logLevel: 'debug'
  theme: 'base'
  gitGraph:
    showBranches: true
    showCommitLabel: true
    mainBranchName: 'MetroLine1'
---
      gitGraph
        commit id:"NewYork"
        commit id:"Dallas"
        branch MetroLine2
        commit id:"LosAngeles"
        commit id:"Chicago"
        commit id:"Houston"
        branch MetroLine3
        commit id:"Phoenix"
        commit type: HIGHLIGHT id:"Denver"
        commit id:"Boston"
        checkout MetroLine1
        commit id:"Atlanta"
        merge MetroLine3
        commit id:"Miami"
        commit id:"Washington"
        merge MetroLine2 tag:"MY JUNCTION"
        commit id:"Boston"
        commit id:"Detroit"
        commit type:REVERSE id:"SanFrancisco"

注意这里 checkout MetroLine1merge MetroLine3merge MetroLine2 tag:"MY JUNCTION" 中的名字都必须与新分支名一致——从源码 状态初始化 可见,mainBranchName 会同时决定初始 currBranchbranchConfig 的初始键。

自定义分支顺序

默认情况下,分支按它们在图中定义/出现的顺序展示。用 order 关键字(正整数)可以自定义顺序,写在分支定义后面:

---
config:
  logLevel: 'debug'
  theme: 'base'
  gitGraph:
    showBranches: true
    showCommitLabel: true
---
      gitGraph
      commit
      branch test1 order: 3
      branch test2 order: 2
      branch test3 order: 1

Mermaid 遵循 order 的优先顺序规则:

  1. main 分支默认 order 为 0,永远最先展示(除非用 mainBranchOrder 配置改动它);
  2. 未指定 order 的分支,按出现顺序展示;
  3. 指定了 order 的分支,按 order 值排序展示。

要完全控制所有分支的顺序,必须为所有分支都定义 order

再看一个配合 mainBranchOrder: 2 的例子:

---
config:
  logLevel: 'debug'
  theme: 'base'
  gitGraph:
    showBranches: true
    showCommitLabel: true
    mainBranchOrder: 2
---
      gitGraph
      commit
      branch test1 order: 3
      branch test2
      branch test3
      branch test4 order: 1

排序结果:test2test3(未指定 order,按定义顺序)→ test4(order 1)→ main(order 2,因覆盖了 mainBranchOrder 而不再置顶)→ test1(order 3)。

排序逻辑的实现在 getBranchesAsObjArray():未显式指定 order 的分支被赋予 0.<索引> 形式的浮点数(即"按出现顺序"排在前),再与显式 order 一起统一按数值升序排列——这解释了为什么"无 order 分支"整体排在"有 order 分支"之前。

方向控制:LR / TB / BT(v10.3.0+)

Mermaid 支持三种图方向:Left-to-Right(默认)、Top-to-BottomBottom-to-Top。写法是在 gitGraph 关键字后加 LR:TB:BT:

左到右(默认,LR:

默认方向是提交从左到右展开、分支上下堆叠。也可以显式写出 LR:

    gitGraph LR:
       commit
       commit
       branch develop
       commit
       commit
       checkout main
       commit
       commit
       merge develop
       commit
       commit

上到下(TB:

TB 方向下提交从上到下展开,分支左右并排。在 gitGraph 后加 TB:

    gitGraph TB:
       commit
       commit
       branch develop
       commit
       commit
       checkout main
       commit
       commit
       merge develop
       commit
       commit

下到上(BT:)(v11.0.0+)

BT 方向下提交从下到上展开,分支左右并排。在 gitGraph 后加 BT:

    gitGraph BT:
       commit
       commit
       branch develop
       commit
       commit
       checkout main
       commit
       commit
       merge develop
       commit
       commit

方向由解析器回调 setDirection 写入状态(初始值 'LR'),渲染器根据 direction 决定坐标映射。

并行提交(v10.8.0+)

默认情况下 GitGraph 通过提交的水平位置传达时间信息:例如两个提交距父提交同样远时,先写的会画得更靠近父提交。开启 parallelCommits: true 可关闭这种时间差——距父提交 x 个距离的提交会画在同一层。

时间顺序模式(默认,parallelCommits: false):

---
config:
  gitGraph:
    parallelCommits: false
---
gitGraph:
  commit
  branch develop
  commit
  commit
  checkout main
  commit
  commit

并行模式(parallelCommits: true):

---
config:
  gitGraph:
    parallelCommits: true
---
gitGraph:
  commit
  branch develop
  commit
  commit
  checkout main
  commit
  commit

主题与主题变量

Mermaid 支持预定义主题,也可以用主题变量覆盖任何主题的既有取值。GitGraph 可用的预定义主题:baseforestdarkdefaultneutral。切换主题可以用 initialize 调用或 front matter 指令(directives 说明),主题机制详见 theming 文档

以同一张多分支图分别套用不同主题为例(theme: 'base' / 'forest' / 'default' / 'dark' / 'neutral' 只需替换 front matter 中的 theme 值):

---
config:
  logLevel: 'debug'
  theme: 'default'
---
      gitGraph
        commit type:HIGHLIGHT
        branch hotfix
        checkout hotfix
        commit
        branch develop
        checkout develop
        commit id:"ash" tag:"abc"
        branch featureB
        checkout featureB
        commit type:HIGHLIGHT
        checkout main
        checkout hotfix
        commit type:NORMAL
        checkout develop
        commit type:REVERSE
        checkout featureB
        commit
        checkout main
        merge hotfix
        checkout featureB
        commit
        checkout develop
        branch featureA
        commit
        checkout develop
        merge hotfix
        checkout featureA
        commit
        checkout featureB
        commit
        checkout develop
        merge featureA
        branch release
        checkout release
        commit
        checkout main
        commit
        checkout release
        merge main
        checkout develop
        merge release

用主题变量定制外观

主题变量控制图各元素的颜色与排版。以 default 主题为基准示例,覆盖方式统一是 front matter 的 themeVariables

重要说明:主题变量最多覆盖 8 个分支 的颜色/样式,超出后循环复用——第 9 个分支使用第 1 个分支(索引 0)的取值。

分支颜色git0 ~ git7git0 驱动第 1 个分支,git1 驱动第 2 个,依此类推:

---
config:
  logLevel: 'debug'
  theme: 'default'
  themeVariables:
      'git0': '#ff0000'
      'git1': '#00ff00'
      'git2': '#0000ff'
      'git3': '#ff00ff'
      'git4': '#00ffff'
      'git5': '#ffff00'
      'git6': '#ff00ff'
      'git7': '#00ffff'
---
       gitGraph
       commit
       branch develop
       commit tag:"v1.0.0"
       commit
       checkout main
       commit type: HIGHLIGHT
       commit
       merge develop
       commit
       branch featureA
       commit

分支标签颜色gitBranchLabel0 ~ gitBranchLabel7,规则相同:

---
config:
  logLevel: 'debug'
  theme: 'default'
  themeVariables:
    'gitBranchLabel0': '#ffffff'
    'gitBranchLabel1': '#ffffff'
    'gitBranchLabel2': '#ffffff'
    'gitBranchLabel3': '#ffffff'
    'gitBranchLabel4': '#ffffff'
    'gitBranchLabel5': '#ffffff'
    'gitBranchLabel6': '#ffffff'
    'gitBranchLabel7': '#ffffff'
---
  gitGraph
    checkout main
    branch branch1
    branch branch2
    branch branch3
    branch branch4
    branch branch5
    branch branch6
    branch branch7
    branch branch8
    branch branch9
    checkout branch1
    commit

由于只有 8 组标签变量,branch8branch9 会分别复用索引 0(main)与索引 1(branch1)的配色——即分支主题变量循环复用

提交标签颜色与字号commitLabelColorcommitLabelBackgroundcommitLabelFontSize

---
config:
  logLevel: 'debug'
  theme: 'default'
  themeVariables:
    commitLabelColor: '#ff0000'
    commitLabelBackground: '#00ff00'
    commitLabelFontSize: '16px'
---
       gitGraph
       commit
       branch develop
       commit tag:"v1.0.0"
       commit
       checkout main
       commit type: HIGHLIGHT
       commit
       merge develop
       commit
       branch featureA
       commit

Tag 标签tagLabelColortagLabelBackgroundtagLabelBorder 控制 tag 的文字颜色、背景与边框;tagLabelFontSize 控制 tag 字号:

---
config:
  logLevel: 'debug'
  theme: 'default'
  themeVariables:
    tagLabelColor: '#ff0000'
    tagLabelBackground: '#00ff00'
    tagLabelBorder: '#0000ff'
    tagLabelFontSize: '16px'
---
       gitGraph
       commit
       branch develop
       commit tag:"v1.0.0"
       commit
       checkout main
       commit type: HIGHLIGHT
       commit
       merge develop
       commit
       branch featureA
       commit

高亮提交颜色gitInv0 ~ gitInv7 按分支索引控制各分支上 HIGHLIGHT 提交的颜色(同样最多 8 个、循环复用):

---
config:
  logLevel: 'debug'
  theme: 'default'
  themeVariables:
    'gitInv0': '#ff0000'
---
       gitGraph
       commit
       branch develop
       commit tag:"v1.0.0"
       commit
       checkout main
       commit type: HIGHLIGHT
       commit
       merge develop
       commit
       branch featureA
       commit

仓库中的实现与测试索引

想在源码层面继续深入 GitGraph,可以从以下入口按调用链阅读(均在仓库相对路径下):

小结

GitGraph 图用不到十行声明式文本,就能表达 commit、branch、checkout、merge 与 cherry-pick 构成的完整分支协作流程;每个提交支持 id/type/tag 属性,每条 branch 支持 ordergitGraph 关键字支持 LR:/TB:/BT: 方向,front matter 的 gitGraph 配置节与 git0~git7gitBranchLabel*commitLabel*tagLabel*gitInv* 主题变量则覆盖布局、命名、排序与外观的全部定制需求。配合源码中的严格校验(重名分支、空分支合并、cherry-pick 父提交约束等),你在写图时遇到的每个报错都能在 gitGraphAst.ts 中找到对应逻辑。

登录后查看全文
热门项目推荐
相关项目推荐