| id | MDS048 |
|---|---|
| name | git-hook-sync |
| status | ready |
| description | Git artifacts must match the canonical glob-based template derived from .mdsmith.yml. |
| category | structural |
| nature | structure |
| maintainability | |
| markdownlint | |
| rumdl | |
| mado | |
| panache | |
| obsidian-linter | |
| gomarklint |
Git artifacts must match the canonical glob-based template derived from .mdsmith.yml.
The .gitattributes managed block and the
pre-merge-commit hook must match a canonical
template. That template is computed from the
project's .mdsmith.yml ignore patterns. Editing
.mdsmith.yml keeps both git artifacts in sync.
One limitation: ignore patterns that cannot appear
verbatim in .gitattributes are dropped from the
managed block. Negation patterns starting with !
and patterns containing whitespace fall in this
bucket. mdsmith fix itself still honors them, so
the merge-driver scope can diverge from mdsmith fix's scope when the ignore: list relies on those
forms.
Markdown files can contain generated sections like
<?catalog?>, <?include?>, and <?toc?>. They need
special handling during git merges to regenerate content
and avoid conflicts. Two artifacts cooperate:
.gitattributesassigns themdsmithmerge driver to markdown files. The managed block uses globs (e.g.*.md merge=mdsmith) plus markdown-scoped exclude overrides (e.g.demo/**/*.md -merge) so the assignment scope tracks.mdsmith.ymlignore patterns rather than enumerating individual files. Each ignore pattern is intersected with the markdown include extensions, so an exclude line never disables git's merge for a non-markdown file in a grandfathered tree.- The pre-merge-commit hook re-runs
mdsmith fix .once every per-file merge has resolved, so generated sections reflect the final merged state. The hook script is glob-driven (no embedded file list), so its scope tracks the same ignore patterns automatically.
This rule detects when either artifact drifts from the canonical template.
This rule has no configuration settings beyond enabling/disabling it.
Enable (default: disabled):
rules:
git-hook-sync: trueDisable:
rules:
git-hook-sync: falseThe rule:
- Reads
.mdsmith.ymlignore patterns and computes the canonical glob set: include patterns (default:*.md,*.markdown) followed by markdown-scoped exclude patterns for eachignore:entry (ademo/**ignore becomesdemo/**/*.mdanddemo/**/*.markdown). - If
merge.mdsmith.driveris registered in git config, reads.gitattributesand compares the BEGIN/END managed block against the canonical render. - Reads the pre-merge-commit hook (when it carries the mdsmith marker) and compares the script against the canonical glob-based template.
- Reports a warning if either artifact drifts.
.gitattributes does not support negation patterns
(!*.md is a syntax error there). The managed block
exploits last-match-wins instead: include lines come first,
then <exclude> -merge lines override them for matching
paths.
This rule is partially auto-fixable:
.gitattributesis auto-fixed bymdsmith fixwhen the merge driver is registered (merge.mdsmith.driverin git config). The fixer rewrites the managed block with the canonical globs, preserving any non-mdsmith entries surrounding it.- Pre-merge-commit hook is not auto-fixed (it is an executable script). You must manually re-run:
mdsmith pre-merge-commit install.gitattributes is a tracked file. It is not system
configuration, and not executable. So it should be
auto-fixable like other content issues. Build systems
running mdsmith fix reconcile drift automatically.
The pre-merge-commit hook remains manual-only because modifying executable files during automated fixes could be surprising or unsafe.
When mdsmith fix updates .gitattributes, the fixer also
runs git add -- .gitattributes. The regenerated file then
lands in the index next to the markdown files the hook
stages, so a merge commit produced by the
pre-merge-commit hook flow includes both. If staging fails
(for example, the index is locked by another git process),
the on-disk fix is still applied and the failure is
recorded. Check() keeps emitting a "staging failed"
diagnostic until a later Fix() call re-runs git add
successfully.
To register the merge driver, write the canonical
.gitattributes block, and install the hook:
mdsmith merge-driver install
mdsmith pre-merge-commit installBoth commands write the canonical glob-based content from
the project's .mdsmith.yml, so re-running them is
idempotent.
.mdsmith.yml ignores test fixtures, and .gitattributes
mirrors that exactly:
# .mdsmith.yml
ignore:
- "demo/**"
- "vendor/**"# .gitattributes
# BEGIN mdsmith merge-driver
*.md merge=mdsmith
*.markdown merge=mdsmith
demo/**/*.md -merge
demo/**/*.markdown -merge
vendor/**/*.md -merge
vendor/**/*.markdown -merge
# END mdsmith merge-driver
.gitattributes still uses the old per-file format from a
pre-glob install:
# BEGIN mdsmith merge-driver
README.md merge=mdsmith
docs/index.md merge=mdsmith
# END mdsmith merge-driver
Diagnostic: .gitattributes managed block is out of sync. The message lists the installed include and exclude
patterns and the canonical patterns the rule expected.
- ID: MDS048
- Name:
git-hook-sync - Status: ready
- Default: disabled
- Fixable: partial (
.gitattributesis auto-fixed; hook requires manualmdsmith pre-merge-commit install) - Implementation: source
- Category: structural