An mdBook preprocessor that injects Git metadata (commit hash, full hash, tag, date/time, branch) into each chapter — as a header, a footer, or both — with flexible templates, alignment, and CSS-style margins.
- Injects the latest Git commit information per chapter (and subchapters).
- Header and/or footer placement with independent configuration.
- Message templating via
message.header/message.footer/message.both. - Split alignment for header/footer or a single legacy value.
- CSS-style margins (TRBL) with per-placement overrides and shorthand.
- Timezone-aware date/time rendering (local, UTC, source, or fixed offset).
- Optional hyperlinks for commit and branch to your remote provider.
- Branch verification with graceful fallback to
"main". - Only the
htmlrenderer is supported.
From crates.io:
cargo install mdbook-gitinfoFrom source (in this repo):
cargo install --path .Ensure the mdbook-gitinfo binary is on your PATH.
Add to book.toml:
[preprocessor.gitinfo]
enable = true
# choose placement(s)
header = false # default: false
footer = true # default: true
# common formatting
font-size = "0.9em"
separator = " • "
date-format = "%Y-%m-%d"
time-format = "%H:%M:%S"
branch = "main"
hyperlink = true # make hash/branch clickable when possible
# optional timezone handling
timezone = "local" # "local" (default) | "utc" | "source" | "fixed:+02:00"
[preprocessor.gitinfo.message]
footer = "Built {{date}}{{sep}}commit: {{hash}}"You can configure options either with dotted keys under [preprocessor.gitinfo] or with nested tables like [preprocessor.gitinfo.message]. Use one style consistently for readability; both work and merge as expected.
The new timezone option controls how commit timestamps are rendered.
| Value | Description |
|---|---|
local (default) |
Convert to system local time. |
utc |
Convert to Coordinated Universal Time (UTC). |
source |
Use the commit’s recorded timezone offset (as authored). |
fixed:+HH:MM or fixed:-HH:MM |
Force a specific fixed offset. |
| anything else | Emits a warning and falls back to local. |
Note
The offset is always applied, but not shown unless you include %z, %:z, or %Z in your time-format
Placeholders: {{hash}}, {{long}}, {{tag}}, {{date}}, {{sep}}, {{branch}}
Precedence (per placement): message.header/footer ➝ message.both ➝ legacy header_message/footer_message ➝ legacy template.
If a placement-specific template is set (
message.headerormessage.footer),message.bothis ignored for that placement.
Dotted keys:
[preprocessor.gitinfo]
message.header = "Last updated: <em>{{date}}</em>"
message.footer = "branch: {{branch}}{{sep}}commit: {{hash}}"
message.both = "<em>{{date}}</em>{{sep}}branch: {{branch}}"Table form (equivalent):
[preprocessor.gitinfo.message]
header = "Last updated: <em>{{date}}</em>"
footer = "branch: {{branch}}{{sep}}commit: {{hash}}"
both = "<em>{{date}}</em>{{sep}}branch: {{branch}}"Values: "left" | "center" | "right" (default center for both).
Resolution: align.header and/or align.footer override align.both.
If neither is set, both default to "center".
Dotted keys:
[preprocessor.gitinfo]
align.header = "left"
align.footer = "right"
align.both = "center" # used only for any placement not explicitly setTable form (equivalent):
[preprocessor.gitinfo.align]
both = "center"
header = "left"
footer = "right"Margins accept CSS-style Top Right Bottom Left values. Units can be px, em, etc., or unitless (0).
You can provide:
- a single value (applies to all sides),
- an array with 1–4 items (CSS shorthand),
- or named sides (
top/right/bottom/left).
Resolution: margin.header / margin.footer override margin.both per placement.
Defaults (when unset):
- Header:
["0", "0", "2em", "0"](space below the header block) - Footer:
["2em", "0", "0", "0"](space above the footer block) - Legacy
margin-top(if present) is treated as footer top spacing.
Dotted keys (array shorthand):
[preprocessor.gitinfo]
margin.header = ["0", "0", "1.25em", "0"] # T R B L
margin.footer = ["2em", "0", "0", "0"] # T R B L
margin.both = "1em" # all sides = 1em unless overriddenDotted keys (named sides):
[preprocessor.gitinfo]
margin.header.top = "5em"
margin.footer.bottom = "2em"
margin.both.left = "0.5em"Table form (equivalent):
[preprocessor.gitinfo.margin]
both = ["1em"] # all sides = 1em
header = ["0", "0", "1.25em", "0"] # T R B L
footer = { top = "2em" } # named sides formUse these tokens inside your message templates:
{{hash}}— short commit hash{{long}}— full commit hash{{tag}}— nearest tag{{date}}— commit date and time (combined using yourdate-formatandtime-format){{sep}}— the configured separator (e.g.," • "){{branch}}— branch name
With the configuration above, a footer will be injected similar to:
<footer class="gitinfo-footer" style="font-size:0.8em;padding:4px;margin:2em 0 0 0;text-align:center;display:block;">
branch: <b><a href="somelinktosomeawesomerepo">main</a></b> • commit: <a href="somelinktosomeawesomerepo">9296b47</a>
</footer>The preprocessor inserts blank lines around injected blocks so Markdown headings/paragraphs render correctly.
font-size— e.g.,"0.8em"separator— string used by{{sep}}date-format,time-format— chrono formatting strings (examples below)branch— default"main". If the branch isn’t found, the preprocessor falls back to"main"with a warning.hyperlink— whentrue,{{hash}}and{{branch}}are linked to your provider (derived from CI env vars likeGITHUB_SERVER_URL/GITHUB_REPOSITORY,CI_SERVER_URL/CI_PROJECT_PATH, Bitbucket vars, orremote.origin.url).
For DateTime format specifiers refer to chrono::format:
When using actions/checkout@v4, set fetch-depth: 0 so the plugin can access commit history:
jobs:
deploy:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# … your build & deploy steps- Tested with mdBook 0.4.x.
- Renderer support: html only.