Commit 0ef6d47
Implement MDS048 git-hook-sync rule and pre-merge-commit hook automation (#212)
* Add pre-merge-commit subcommand with install/uninstall/status
- Add new `pre-merge-commit` top-level command alongside `merge-driver`
- Supports `install [files...]` to install hook for specified files
- Supports `uninstall` to safely remove mdsmith-managed hooks
- Supports `status` to show installation state and configured files
- Hook runs `mdsmith fix` then `git add` to stage resolved conflicts
- Comprehensive test coverage for all subcommands
- Update main.go to register new command in CLI
Agent-Logs-Url: https://github.com/jeduden/mdsmith/sessions/0a73443c-afb9-4783-88c8-91e27470ea9d
Co-authored-by: jeduden <1117699+jeduden@users.noreply.github.com>
* Document pre-merge-commit command in CLI reference
- Add pre-merge-commit to commands table
- Document install/uninstall/status subcommands
- Explain hook behavior: runs after per-file merges, before merge commit
- Note that hook stages resolved files with git add
- Auto-fix table formatting
Agent-Logs-Url: https://github.com/jeduden/mdsmith/sessions/0a73443c-afb9-4783-88c8-91e27470ea9d
Co-authored-by: jeduden <1117699+jeduden@users.noreply.github.com>
* Remove hardcoded files from CLI subcommands
Replace hardcoded default files with automatic discovery:
- Add discoverFilesWithGeneratedContent() function
- Scans repo for files with <?catalog?>, <?include?>, <?toc?>
- Falls back to PLAN.md, README.md if nothing found
- Update merge-driver install to use discovery
- Update pre-merge-commit install to use discovery
- Update help text to document auto-discovery
- Add comprehensive tests for discovery function
- All tests pass (8.859s)
Agent-Logs-Url: https://github.com/jeduden/mdsmith/sessions/ead687d0-ae03-4873-ae05-a8258bc7c5a6
Co-authored-by: jeduden <1117699+jeduden@users.noreply.github.com>
* Add sync detection to pre-merge-commit status command
Agent-Logs-Url: https://github.com/jeduden/mdsmith/sessions/d914ddb4-6726-4899-a1b4-b4ec40d9b086
Co-authored-by: jeduden <1117699+jeduden@users.noreply.github.com>
* Implement MDS047 git-hook-sync rule to detect out-of-sync hooks
Agent-Logs-Url: https://github.com/jeduden/mdsmith/sessions/265ff37d-15ad-45a4-84c7-22c2408c97be
Co-authored-by: jeduden <1117699+jeduden@users.noreply.github.com>
* Renumber git-hook-sync from MDS047 to MDS048 to avoid PR conflict
Agent-Logs-Url: https://github.com/jeduden/mdsmith/sessions/1cf0592b-01df-4155-9933-fc145afe524b
Co-authored-by: jeduden <1117699+jeduden@users.noreply.github.com>
* Fix MDS048 integration tests - add missing import and fixture
Added githooksync package import to rules_test.go so MDS048
is registered in the rule registry. Created minimal good fixture
since MDS048 is a meta rule requiring actual git repo setup
(tested via unit tests in rule_test.go).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: jeduden <1117699+jeduden@users.noreply.github.com>
* Fix CI lint and mdsmith check errors
Lint fixes:
- Add error checks for w.Close() calls in test cleanup
- Refactor Check function to be under 60 lines (funlen)
- Run gofmt on discover_test.go
mdsmith check fixes:
- Wrap long lines in MDS048 README.md
- Fix broken link to rule.go (use ../githooksync/rule.go)
- Use backticks for directive examples to avoid parsing
- Increase table max-rows limit to 45 for rules index
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: jeduden <1117699+jeduden@users.noreply.github.com>
* Fix remaining errcheck lint errors in test cleanup
Add error checks for remaining w.Close() calls at lines
197 and 231 in premergecommit_test.go.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: jeduden <1117699+jeduden@users.noreply.github.com>
* Address PR #212 review: align MDS048 with real installer behavior
- Move discovery and hook parsing into a shared internal/githooks
package so the CLI and the git-hook-sync rule cannot drift.
- Read .gitattributes (the real source of truth for merge driver
assignments) instead of parsing .git/config sections that mdsmith
never writes; only check when merge.mdsmith.driver is registered.
- Use the canonical "# mdsmith merge-driver pre-merge-commit hook"
marker so the rule recognises hooks the installer writes.
- Resolve hooks dir via "git rev-parse --git-path hooks" so the
rule works in worktrees, submodules, and core.hooksPath repos.
- Resolve the git repo root from the file's directory (not the
process CWD) so linting absolute paths and the NotInGitRepo
test no longer depend on where mdsmith is invoked from.
- Drop FixableRule from MDS048; hook installation is a side-
effecting operation outside the scope of mdsmith fix.
- Stop rewriting .mdsmith.yml during install commands; print the
enable-rule snippet instead, per CLAUDE.md guidance about
modifying linter config.
- Normalize discovered paths to forward slashes so comparisons
against .gitattributes / hook content work on Windows.
- Replace the brittle extractFilesFromHook parser with one that
pulls the first single-quoted token after each "fix --" marker.
- Track reported repos per Rule instance so duplicate diagnostics
are not emitted while linting many files in the same repo.
- Update tests and the rule README to match the real installer
layout (.gitattributes + merge.mdsmith.driver).
* Improve test coverage on pre-merge-commit and shared githooks helpers
Add tests covering the install/uninstall/status dispatch, the
not-in-git-repo error branches, the auto-discovery branch when
install is invoked without arguments, and the unmanaged-hook path
in status. Also add metadata tests for the MDS048 rule and
boundary-condition tests for the firstQuotedAfter parser.
* Lift coverage on changed files toward 100%
Adds focused tests for the remaining uncovered branches:
- githooks: empty-dir GitRepoRoot, fallback ResolveHooksDir when
the directory is not a git repo, skipping non-Markdown files in
DiscoverFiles, single-field lines in ExtractGitattributesFiles,
and edge cases in firstQuotedAfter.
- githooksync rule: merge-driver registered without .gitattributes
on disk, and a pre-merge-commit hook that lacks the mdsmith
marker (user-authored hook).
- pre-merge-commit CLI: install refusing to overwrite a
user-authored hook.
- merge-driver CLI: install with no args (auto-discovery branch)
and the not-in-git-repo error path.
Also drops an unreachable branch in Rule.Check (filepath.Dir
never returns "" for a non-empty path).
Per-package coverage on the new code:
- internal/githooks: 97.9%
- internal/rules/githooksync: 98.0%
* Cover the remaining new code paths
Adds tests for:
- main.go run() dispatching to pre-merge-commit
- merge-driver and pre-merge-commit install: not-in-git-repo,
loadConfig error (malformed .mdsmith.yml), and bad
max-input-size (invalid size string)
* Address Copilot round 2: bool-enable + dedupe FilesMatch
- Drop the `configured` gate on Rule.Check so the zero-value Rule
runs when enabled via the bool form `git-hook-sync: true` (the
framework only calls ApplySettings for mapping configs, leaving
the gate stuck at false otherwise).
- ApplySettings still rejects unknown keys, but no longer flips a
state flag the Check path depends on.
- Make FilesMatch tolerant of duplicate entries on either side by
comparing deduplicated sets.
- Fix two integration tests that wrote `max-input-bytes` (an
unknown key) to .mdsmith.yml; use the supported `max-input-size`
key instead.
* Address Copilot round 3: collapse diagnostics, decode shell quotes
- Rule.Check now emits at most one diagnostic per repository per
lint run, joining both .gitattributes and pre-merge-commit hook
drift into a single message. Brings the implementation in line
with the behavior the README has always claimed.
- Treat "merge.mdsmith.driver registered, but .gitattributes has
no merge=mdsmith entries" as drift when discovered files exist.
The driver would not run for any file, so silently passing was
the wrong default.
- Teach firstQuotedAfter to decode the POSIX shell-quote escape
shellQuote produces ('a'\''b.md' -> a'b.md), so file paths that
contain a single quote round-trip correctly through the
pre-merge-commit hook script.
* Fix gofmt: rephrase comment to avoid doc-comment auto-typography
gofmt's doc-comment formatter rewrites consecutive ASCII single
quotes into typographic right-double-quote, which mangled the
shell-quote example in firstQuotedAfter's doc comment. Rephrase
the comment so it conveys the same idea without the offending
character sequence.
* Address Copilot round 4: directive parsing, deterministic order
- DiscoverFiles now scans line-by-line and uses
gensection.IsRawStartMarker / IsRawEndMarker so prose mentions
of <?catalog?> (e.g. inside backticks) are no longer detected as
directive-bearing. Avoids bloating .gitattributes / hook files
and silences false drift diagnostics.
- Skip non-regular files (symlinks, FIFOs, devices, sockets) in
DiscoverFiles. Matches the project's secure-by-default stance
on symlinks and prevents hangs on FIFO entries.
- Sort and dedupe the discovered file list so the output is
deterministic across platforms and filesystems. The list is
printed to users and embedded into generated artifacts, so
stability matters for review diffs.
- Replace the non-ASCII warning glyph in `pre-merge-commit status`
output with a plain "Warning:" prefix for terminal/grep
compatibility.
- Add regression tests covering prose-only directive mentions and
sorted deduplicated discovery output.
* Address Copilot round 5: normalize and validate managed paths
- Add githooks.NormalizeManagedPath / NormalizeManagedPaths that
convert paths to repo-relative + forward-slash form, reject
empty inputs, reject whitespace (which the .gitattributes
parser cannot recover), and reject paths that escape the repo.
- Apply the normalizer to the explicit-args branch in both
`merge-driver install` and `pre-merge-commit install`, and
share the resolution logic in resolveManagedFiles so the two
commands can't drift on path handling.
- Document the whitespace constraint on
ExtractGitattributesFiles, since the parser splits on
whitespace and cannot tokenize paths that contain it. The
install-time normalizer enforces the constraint, keeping the
installer and the drift checker in lockstep.
* Cover the path-validation error branches
Both install commands now have a test that exercises the
NormalizeManagedPaths failure path (whitespace in arg), covering
the corresponding stderr/return-2 branches in resolveManagedFiles
that codecov flagged as untested.
* Cover more new branches: ReadFile errors, symlink skip, normalize paths
- Add a happy-path test for NormalizeManagedPaths so the success
return is exercised from the package's own tests (codecov tracks
per-package coverage, so the cmd/mdsmith call sites are not
counted toward githooks.go coverage).
- Add a SkipsSymlinks test that creates a real .md file plus a
matching symlink and asserts only the regular file is returned,
exercising the non-regular file skip in DiscoverFiles.
- Add ReadError tests for `pre-merge-commit uninstall` and
`pre-merge-commit status` that point hookPath at a directory so
os.ReadFile returns a non-IsNotExist error.
- Add a RemoveError test for uninstall that exercises the
os.Remove failure branch when permissions can deny it; the test
self-skips when running as root, where chmod is bypassed.
* Address Copilot round 6: surface read errors, render empty as (none)
- Drop the duplicated ExtractGitattributesFiles doc comment.
- mergeDriverDrift now surfaces non-ENOENT read errors on
.gitattributes as a "cannot verify merge-driver assignments"
diagnostic instead of silently passing. Permission/IO failures
no longer mask real misconfiguration.
- preMergeCommitHookDrift does the same for the hook script: a
non-ENOENT read failure is reported as
"cannot verify pre-merge-commit hook" rather than treated as
"in sync".
- When the mdsmith-managed hook contains no parsable
`fix -- '...'` entries, the drift message renders the installed
list as "(none)" rather than a blank string.
- Tests cover the (none) rendering and both new read-error
branches by pointing each path at a directory so ReadFile
returns IsADirectory.
* Move githooksync once-per-repo state to package scope
The engine clones Configurable rules per file when the rule is
enabled with a settings mapping (even an empty {}). With per-Rule
state, each clone reset the reported set, so the "at most one
diagnostic per repository" guarantee broke as soon as a user
opted in via mapping syntax.
- Move reportedRepos / reportedMu to package scope so all clones
share one set, regardless of whether the rule is enabled with
`git-hook-sync: true` or `git-hook-sync: {}`.
- Add resetReportedForTest so tests do not leak repo paths into
later cases.
- Add a regression test that calls rule.CloneRule twice and
verifies the second clone does not re-emit the diagnostic for
the same repo.
* Address Copilot round 7: fenced-code, normalization, hermeticity
- DiscoverFiles now tracks fenced-code state (CommonMark backtick
and tilde fences) and ignores directive markers inside fences.
mdsmith only parses processing-instructions at the document
root, so files that merely show <?catalog?> in a code example
are no longer treated as directive-bearing.
- NormalizeManagedPath now performs the whitespace check on the
normalized repo-relative result rather than the raw input, so a
repo whose own path contains spaces (Windows/macOS home dirs)
accepts absolute inputs as long as the repo-relative tail is
whitespace-free.
- resolveManagedFiles funnels both the explicit-args branch and
the auto-discovery branch through NormalizeManagedPaths, so the
installer cannot write a token that the drift checker would
reject (or vice versa).
- Update the pre-merge-commit hook header comment to mention both
install entry points (`mdsmith merge-driver install` and
`mdsmith pre-merge-commit install`) so users see accurate
guidance regardless of which subcommand they used.
- Make the MDS048 integration fixture hermetic by writing its
fixture file path inside a fresh non-repo tempdir; the rule's
GitRepoRoot lookup fails there, so the fixture cannot fail
based on a contributor's locally-installed merge driver / hook.
* Skip directive markers in indented code blocks too
CommonMark treats a line beginning with a tab or four-plus spaces as
an indented code block; internal/lint.pi_parser refuses to parse a
processing-instruction on such lines for the same reason. Bring
hasDirectiveMarker in line with that rule so a directive shown in an
indented example does not trigger discovery.
Add a regression test covering both 4-space and tab-indented
markers.
* Address Copilot round 9: local config scope, doc accuracy
- HasMdsmithMergeDriver now uses `git config --local` so a
user-global merge driver cannot opt every clone into MDS048's
drift checks. Documented the local-only scope.
- Update the pre-merge-commit usage text to list catalog,
include, *and* toc, matching what discovery actually scans for.
- Align the rule's inline comment and README with the actual
behavior: the once-per-repo guard lives for the lifetime of
the mdsmith process, not a single lint run.
* Address Copilot round 10: split rule from install fallback
The shared discovery helper used to fall back to
[PLAN.md, README.md] whenever a repo contained no directive-
bearing files. The fallback makes sense for install commands but
not for the git-hook-sync rule: the rule should not compare
against fictional paths.
- DiscoverFiles now returns whatever the walk produced (possibly
empty) and never invents PLAN.md / README.md.
- DiscoverFilesForInstall is a thin wrapper that applies the
install-only fallback. Both `merge-driver install` and
`pre-merge-commit install` use this variant via the existing
CLI shim.
- Drift messages render an empty discovered list as "(none)" so
a stale .gitattributes / hook in a directive-free repo still
produces a readable warning.
- Update the rule README to document the rule-vs-install
difference, and drop the spurious "git-hook-sync:" prefix from
the example diagnostic so the snippet matches mdsmith's actual
output (the rule ID/name are printed by the formatter).
* Address Copilot round 11: precise closing fence + accurate README
- isClosingFence now requires the line to end in whitespace after
the fence run, per CommonMark. A line like "\`\`\`not-a-closing-
fence" is content, not a fence terminator, so a directive marker
later in the same fenced block is correctly ignored. Add a
regression test that opens a fence, embeds a "\`\`\`text" line,
and asserts the directive marker afterwards is not discovered.
- Update the rule README to describe the actual empty-discovery
behavior: when discovery is empty, the rule is silent if no
managed source lists files, but reports stale entries when one
still does (e.g. left over from install-time PLAN.md/README.md
fallback). The previous wording wrongly implied it never fires.
* Address Copilot round 12: drain stderr pipes + document fallback
- Replace the five hand-rolled `os.Pipe` redirections in
premergecommit_test.go with the existing captureStderr helper,
which drains and closes the read end. The previous pattern left
the read end open, risking FD leaks and blocked writes once the
kernel buffer filled.
- Update both install commands' help text to mention the
install-time fallback to PLAN.md and README.md when no
directive-bearing files are discovered, so users are not
surprised when those entries appear in fresh repos.
* Address Copilot round 13: reject glob inputs, fix test comment
- NormalizeManagedPath now rejects any path containing `*`, `?`,
or `[`. The pre-merge-commit hook script wraps each managed
entry in a `[ -e <path> ]` guard, and `[ -e ]` treats its
argument as a literal filename, so a glob like docs/*.md would
always be skipped even when files match. The drift checker
likewise compares exact paths, so accepting globs would create
silent false matches. Reject them at install time.
- Update the comment on TestRunPreMergeCommitUninstall_RemoveError
to describe what actually happens: the test creates an
mdsmith-marked hook file and drops write permission from the
hooks directory so os.Remove fails with EACCES (not ENOTEMPTY,
which the previous comment claimed). The probe-and-skip path
for root unchanged.
* Address Copilot round 14: env-robust tests + parser/doc tightening
- Replace six hard-coded `<repo>/.git/hooks` test setups in
internal/rules/githooksync/rule_test.go with
`githooks.ResolveHooksDir(dir)` so the tests do not break on
developer machines that set core.hooksPath.
- TestResolveHooksDir_Default now asks git itself
(`git rev-parse --git-path hooks`) for the expected hooks
directory rather than hard-coding `.git/hooks`. A non-default
global core.hooksPath no longer makes the test flap.
- ExtractHookFiles skips comment and blank lines so a commented-
out example in a hook script (e.g. a "see also" note) does not
produce a false managed-file entry. Add a regression test.
- Update the rule README to describe install behavior accurately:
`pre-merge-commit install` rewrites the hook so stale entries
drop, but `merge-driver install` is append-only on
.gitattributes. Mention that users must edit .gitattributes by
hand to remove obsolete `merge=mdsmith` lines.
* Address Copilot round 15: command prefix + uniform fixture isolation
- README now spells the install commands as
`mdsmith pre-merge-commit install` and
`mdsmith merge-driver install` consistently. Users copying the
command no longer hit a shell-not-found.
- Apply fixtureFilePath to bad/ and fixed/ runners too, not just
good/. Future MDS048 (or any other git-aware rule) bad/fixed
fixtures will use a non-repo tempdir as f.Path automatically,
staying hermetic from the contributor's local git config.
* Address Copilot round 16: pin core.hooksPath in test repos
Add an initTestRepo helper to both cmd/mdsmith and
internal/rules/githooksync test packages. The helper runs
`git init` and immediately pins core.hooksPath to
<repo>/.git/hooks in the repo-local config. Replace every
bare `git init <dir>` in those packages' tests with the
helper.
The pin keeps tests hermetic: a contributor whose global git
config sets core.hooksPath to a custom directory can no longer
have these tests create, modify, or delete hook files in their
real environment. install/uninstall/status, the drift rule,
and the integration runner all read hooks via
ResolveHooksDir, which honors the now-local core.hooksPath.
* Skip TestDiscoverFiles_SkipsSymlinks where symlinks unsupported
Use the repo's existing testutil.SkipIfSymlinkUnsupported helper so
the test cleanly skips on Windows / sandboxed CI environments where
os.Symlink fails without elevated privileges, matching the pattern
used by other symlink-creating tests in the codebase.
* Address Copilot round 18: skip rule on stdin + surface status warnings
- MDS048's Check now short-circuits when f.FS == nil. RunSource
(used by stdin and other in-memory inputs) leaves FS nil, and
filepath.Dir("<stdin>") would otherwise resolve git repo
discovery against the process working directory and emit drift
diagnostics unrelated to the linted content.
- Update existing rule tests to set f.FS = os.DirFS(dir) so the
rule still runs against the temp repo, and add a regression
test that confirms a nil-FS file is silently skipped.
- pre-merge-commit status now surfaces a non-fatal "Warning:
could not load config / could not resolve max-input-size"
message instead of silently skipping drift detection. The user
can no longer be misled into thinking the hook is in sync when
the comparison was never executed.
- Extract a printManagedHookStatus helper so runPreMergeCommitStatus
stays under the funlen limit, and add tests for both new
warning branches.
* Treat <=3 spaces + tab as indented code in discovery
isIndentedCodeBlock previously only flagged lines that started
with a tab in column 0 or had four-plus leading spaces. A line
like ' \t<?catalog?>' (up to three spaces followed by a tab)
is also an indented code block per CommonMark, and mdsmith's PI
parser refuses to parse a processing-instruction there. Update
the gate to scan past leading spaces and treat the next tab as
indented code, so discovery cannot pick those markers up either.
Extend the indented-code regression test to cover the
spaces-then-tab case alongside the existing 4-space and column-0
tab cases.
* Address Copilot round 19: skip walk + document config bump
- Add a cheap opt-in pre-check in MDS048's Check that probes
the local merge driver registration and the pre-merge-commit
hook before invoking the repo-wide discovery walk. When
neither source is opted in (and the hook is not unreadable),
the rule returns nil immediately and avoids the O(repo) walk
for projects that don't use mdsmith hooks at all.
- Distinguish "hook absent" (ENOENT) from "hook unreadable" via
a small peekHookSource helper so the IO-error warning path in
preMergeCommitHookDrift still fires even when the merge
driver isn't registered.
- Add a regression test that confirms the rule emits no
diagnostics in a repo with directive-bearing files but no
mdsmith hooks installed.
- Document the .mdsmith.yml table-readability bump in the PR
description (40 -> 45) so reviewers can see the rationale: the
rules index table grew past 40 rows when MDS048 was added.
---------
Co-authored-by: anthropic-code-agent[bot] <242468646+Claude@users.noreply.github.com>
Co-authored-by: jeduden <1117699+jeduden@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>1 parent 926fddc commit 0ef6d47
17 files changed
Lines changed: 3085 additions & 56 deletions
File tree
- cmd/mdsmith
- docs/reference
- internal
- githooks
- integration
- rules
- MDS048-git-hook-sync
- good
- githooksync
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
122 | 122 | | |
123 | 123 | | |
124 | 124 | | |
125 | | - | |
| 125 | + | |
126 | 126 | | |
127 | 127 | | |
128 | 128 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
| 39 | + | |
39 | 40 | | |
40 | 41 | | |
41 | 42 | | |
| |||
74 | 75 | | |
75 | 76 | | |
76 | 77 | | |
77 | | - | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | | - | |
86 | | - | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
87 | 89 | | |
88 | 90 | | |
89 | 91 | | |
| |||
129 | 131 | | |
130 | 132 | | |
131 | 133 | | |
| 134 | + | |
| 135 | + | |
132 | 136 | | |
133 | 137 | | |
134 | 138 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| 13 | + | |
13 | 14 | | |
14 | 15 | | |
15 | 16 | | |
| |||
27 | 28 | | |
28 | 29 | | |
29 | 30 | | |
30 | | - | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
31 | 35 | | |
32 | 36 | | |
33 | 37 | | |
| |||
352 | 356 | | |
353 | 357 | | |
354 | 358 | | |
355 | | - | |
356 | | - | |
357 | | - | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
358 | 393 | | |
359 | 394 | | |
360 | 395 | | |
| |||
378 | 413 | | |
379 | 414 | | |
380 | 415 | | |
381 | | - | |
382 | | - | |
383 | | - | |
384 | | - | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
385 | 419 | | |
386 | 420 | | |
387 | 421 | | |
| |||
402 | 436 | | |
403 | 437 | | |
404 | 438 | | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
405 | 442 | | |
406 | 443 | | |
407 | 444 | | |
408 | 445 | | |
409 | 446 | | |
410 | | - | |
411 | | - | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
412 | 451 | | |
413 | 452 | | |
414 | | - | |
415 | | - | |
416 | | - | |
417 | | - | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
418 | 456 | | |
419 | | - | |
420 | | - | |
421 | | - | |
422 | | - | |
423 | | - | |
424 | | - | |
425 | | - | |
426 | | - | |
427 | | - | |
| 457 | + | |
428 | 458 | | |
429 | 459 | | |
430 | 460 | | |
| |||
480 | 510 | | |
481 | 511 | | |
482 | 512 | | |
483 | | - | |
| 513 | + | |
484 | 514 | | |
| 515 | + | |
485 | 516 | | |
486 | 517 | | |
487 | 518 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
299 | 299 | | |
300 | 300 | | |
301 | 301 | | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
302 | 399 | | |
303 | 400 | | |
304 | 401 | | |
| |||
704 | 801 | | |
705 | 802 | | |
706 | 803 | | |
707 | | - | |
| 804 | + | |
708 | 805 | | |
709 | 806 | | |
710 | 807 | | |
| |||
717 | 814 | | |
718 | 815 | | |
719 | 816 | | |
720 | | - | |
| 817 | + | |
721 | 818 | | |
722 | 819 | | |
723 | 820 | | |
| |||
726 | 823 | | |
727 | 824 | | |
728 | 825 | | |
729 | | - | |
| 826 | + | |
730 | 827 | | |
731 | 828 | | |
732 | 829 | | |
| |||
0 commit comments