Commit 3338209
feat(pm): make mcpp.lock authoritative for git deps (2026.8.1.2) (#330)
* feat: use mcpp.lock commit as offline anchor for git deps
- Add LockedGitSource + parse_git_source to lock_io.cppm.
- Load mcpp.lock in prepare_build and use recorded branch commit to skip
git ls-remote when the local cache still matches.
- For tag/rev, reuse cached clone and fail early in --offline when missing.
- Update e2e test 24 to assert branch deps do not re-ls-remote on rebuild.
- Add unit tests for git source parsing.
Closes #329
* fix(pm): address PR #330 review feedback
- tests: assert 'from lock' on rebuild instead of vacuous 'ls-remote'
- prepare: dedupe cache-key formula via computeGitRoot(resolvedGitRev)
- prepare: add anchor.url == spec.git to offline anchor match
- prepare: drop 'mcpp update' from offline diagnostics (offline no-op)
- commands: refresh stale comment in cmd_update about lockfile semantics
- lock_io: split fragment on last '@' (branch names with '@') and
reset empty resolvedCommit so the offline branch prints the right hint
* fix(e2e): force prepare_build for the 24_git_dependency lock-anchor check
A bare second `mcpp build` takes the try_fast_build path when
build.ninja is fresh (no source change), so prepare_build is skipped
and neither the lock-anchor code nor `git ls-remote` runs — leaving
the `from lock` assertion vacuous (it cannot match; same failure
mode as the original ls-remote assertion the reviewer flagged).
Run `mcpp clean` first so the fast-path cannot fire; mcpp.lock and
the git cache (in MCPP_HOME/git) both survive `mcpp clean`, so the
next build re-prepares, hits the anchor, prints 'from lock' and skips
both ls-remote and the clone.
* refactor(pm): make mcpp.lock authoritative for git deps (2026.8.1.2)
The lock was read for the first time in the previous commits of this PR, but
only as a hint the local clone had to confirm: a recorded commit counted while
`~/.mcpp/git/<hash>` existed, and otherwise the branch was re-resolved over the
network and the lock rewritten. That hands "which commit do we build" to the
survival of a cache directory. `mcpp new` does not gitignore `mcpp.lock` — it is
meant to be committed — so the failure is ordinary: clone the project on a second
machine, get a different commit, and see the lock quietly change under you.
Measured on the new e2e assertion, with the branch moved and the cache evicted:
the previous head built v2, this builds the v1 the lock recorded. `cargo build` /
`cargo update` split it the same way.
Making the lock authoritative also collapses the block into two independent
questions, each with at most one network operation and therefore exactly one
--offline gate: which commit (tag/rev name one; a branch is answered by the lock,
else by ls-remote), and is it on disk (the commit picks the cache directory; a
miss is a clone). The separate tag/rev leg goes with it, taking its per-build
"from cache" noise line and its "is locked but its local cache is missing"
message — which was emitted for deps that were never in the lock.
Four defects fixed along the way:
- --offline refused git remotes that are local directories. docs/05-mcpp-toml.md
defines --offline as "never touch the network ... anything already installed
still builds", and prepare.cppm's dependency-download gate draws the same line
in a comment; ls-remote/clone against a local path are filesystem reads, so
refusing them buys no isolation. Remotes are now classified by shape, which
keeps a Windows drive letter (C:\repo — colon, no @) on the local side.
- A clone killed between `git clone` and `git checkout` served the wrong commit
forever: the directory is named after the commit but was only checked for
existence. Branch deps now compare `git rev-parse HEAD` and re-clone on
mismatch (tag/rev keep the ref name as identity, so there is nothing to
compare).
- The clone depended on `cd` changing drive on Windows. cmd.exe needs `cd /d`,
and MCPP_HOME routinely sits on a different drive than the project; every
other cross-drive site in the repo (process.cppm, msvc.cppm) writes /d, this
one did not. `git -C <dir>` needs no shell at all.
- An unreadable mcpp.lock was a plain warning, invisible to --strict. Per
src/diag.cppm that is the degraded channel: the engine silently does less than
asked — every git branch dep falls back to the network.
Also: parse_git_source no longer splits a tag/rev whose name contains '@' (only
branch entries carry @<commit>, which is what the writer emits), the cmd_update
comment now records the right causality, and docs/CHANGELOG cover the new
semantics in both languages.
Co-authored-by: speak-agent <248744407+speak-agent@users.noreply.github.com>
---------
Co-authored-by: sunrisepeak <speakshen@163.com>
Co-authored-by: speak-agent <248744407+speak-agent@users.noreply.github.com>1 parent 7f1489d commit 3338209
10 files changed
Lines changed: 466 additions & 57 deletions
File tree
- docs
- zh
- src
- build
- pm
- toolchain
- tests
- e2e
- unit
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
6 | 28 | | |
7 | 29 | | |
8 | 30 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
339 | 339 | | |
340 | 340 | | |
341 | 341 | | |
342 | | - | |
| 342 | + | |
343 | 343 | | |
344 | 344 | | |
| 345 | + | |
345 | 346 | | |
346 | 347 | | |
347 | 348 | | |
| |||
356 | 357 | | |
357 | 358 | | |
358 | 359 | | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
359 | 379 | | |
360 | 380 | | |
361 | 381 | | |
| |||
454 | 474 | | |
455 | 475 | | |
456 | 476 | | |
457 | | - | |
| 477 | + | |
458 | 478 | | |
459 | 479 | | |
460 | 480 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
310 | 310 | | |
311 | 311 | | |
312 | 312 | | |
313 | | - | |
| 313 | + | |
314 | 314 | | |
315 | 315 | | |
| 316 | + | |
316 | 317 | | |
317 | 318 | | |
318 | 319 | | |
| |||
325 | 326 | | |
326 | 327 | | |
327 | 328 | | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
328 | 344 | | |
329 | 345 | | |
330 | 346 | | |
| |||
443 | 459 | | |
444 | 460 | | |
445 | 461 | | |
446 | | - | |
| 462 | + | |
447 | 463 | | |
448 | 464 | | |
449 | 465 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
0 commit comments