Commit 82ee65f
Fix protected-paths guard to use merge-tree simulation (ADO 5347121) (microsoft-foundry#493)
* Fix protected-paths guard to use merge-tree simulation (ADO 5347121)
`guard_protected_paths()` in `.github/scripts/sync-core.sh` previously
compared blobs at `sync_branch_tip:<path>` against `public_main:<path>`.
Because `git fast-export --import-marks` combined with pathspec filters
forces `--full-tree` mode, every emitted commit becomes a `deleteall` plus
one `M` record per included file -- so excluded paths (`.github/`) are
absent from the sync-branch-tip tree even when the eventual rebase-merge
into public main would preserve them unchanged. The result: once a
protected workflow file exists on public main, the guard hard-fails
every incremental sync regardless of whether the merge would actually
disturb the file. Scheduled sync has been paused since 2026-06-08.
This change replaces the blob comparison with a `git merge-tree
--write-tree` simulation. The guard now computes the prospective
post-rebase-merge tree from public `origin/main` and the sync branch,
then compares the public-main blob against the merged-tree blob for each
protected path. Both topologies are correctly classified:
* Normal incremental sync (`--import-marks` parent chain anchors to
previous sync-import commits that also lacked `.github/`): the
3-way merge preserves `.github/` from public main, so the result
tree has the unchanged blob and the guard passes.
* Seed-marks recovery (parent chain anchors to public_sha that HAS
`.github/`): the new sync commit's parent tree contains `.github/`
while its own tree does not -- a real delete in the rebase-merge.
The result tree omits the protected file and the guard correctly
hard-fails with the existing "MISSING from sync branch" error.
Non-zero exit from `merge-tree` is surfaced via a distinct conflict
error so real prospective-merge conflicts are not conflated with
protected-paths violations. For the synthetic true-orphan case (no
common ancestor; only test fixtures hit this in practice), the guard
falls back to the sync-branch tree directly, preserving orphan-wipe
detection -- explicitly NOT using `--allow-unrelated-histories`, which
empirically produces a UNION tree that would silently false-pass orphan
wipes.
Requires git >= 2.38 for `merge-tree --write-tree`. GitHub-hosted CI
runners (ubuntu-latest) are at 2.43+. The guard validates the git
version up front and fails loudly with a useful message if it is too
old.
GitHub's actual sync-PR merge strategy (`gh pr merge --rebase` with
`--squash` fallback) produces the same protected-path blob set as a
3-way merge from `merge-tree`'s perspective, so the simulation is sound
for either path.
Tests (from PR microsoft-foundry#492 which landed the failing reproducer):
T64-T68 guard unit tests on synthesized branches PASS (unchanged)
T69 normal incremental + protected file RED -> GREEN
T70 seed-recovery wipe (regression coverage) PASS (unchanged)
Local test summary (WSL): Tests run: 75 | Passed: 66 | Failed: 9.
The 9 failures (T29, T31, T32, T35, T36, T48, T50, T54, T55) are
pre-existing environment-only issues (getcwd quirks, missing `jq`,
verify-sync drift detection on the local fixture) that reproduce
identically on `main` without this change. CI runners pass cleanly.
Docs: `docs/repo-sync-automation.md` -- the "Known issue: guard
incompatible with `fast-export --import-marks` + pathspec" section is
removed; the Protected-paths guard intro and False-positive risk
subsection are rewritten to describe the new merge-tree semantics; a
2026-06-09 Changelog entry records the fix. The 2026-06-08 historical
entry is updated only to drop a now-dead anchor link.
Re-enabling the scheduled cron in `.github/workflows/sync-to-public.yml`
is tracked separately as ADO 5347122 (post-CI-confirmation follow-up).
Bug: https://msdata.visualstudio.com/Vienna/_workitems/edit/5347121
Repro PR (tests-first): microsoft-foundry/foundry-samples-pr#492
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Clarify divergent-content error message: "prospective merge result blob"
The error message previously said "vs sync branch blob" but the blob
being shown is from the prospective post-rebase-merge tree
(`result_blob`), not the sync-branch-tip tree. Rephrase to match
actual semantics and add an inline comment explaining the distinction.
T67 only greps for the substring `divergent content` so the rename
is safe.
Addresses microsoft-foundry/foundry-samples-pr#493 (review).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent 0746f27 commit 82ee65f
2 files changed
Lines changed: 113 additions & 64 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
271 | 271 | | |
272 | 272 | | |
273 | 273 | | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 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 | + | |
274 | 343 | | |
275 | | - | |
| 344 | + | |
276 | 345 | | |
277 | 346 | | |
278 | | - | |
| 347 | + | |
279 | 348 | | |
280 | 349 | | |
281 | 350 | | |
| |||
287 | 356 | | |
288 | 357 | | |
289 | 358 | | |
290 | | - | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
291 | 364 | | |
292 | 365 | | |
293 | 366 | | |
294 | 367 | | |
295 | 368 | | |
296 | | - | |
297 | | - | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
298 | 374 | | |
299 | 375 | | |
300 | 376 | | |
| |||
323 | 399 | | |
324 | 400 | | |
325 | 401 | | |
326 | | - | |
| 402 | + | |
327 | 403 | | |
328 | 404 | | |
329 | 405 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
230 | 230 | | |
231 | 231 | | |
232 | 232 | | |
233 | | - | |
234 | | - | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
235 | 250 | | |
236 | 251 | | |
237 | 252 | | |
| |||
270 | 285 | | |
271 | 286 | | |
272 | 287 | | |
273 | | - | |
274 | | - | |
275 | | - | |
276 | | - | |
277 | | - | |
278 | | - | |
279 | | - | |
280 | | - | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
281 | 300 | | |
282 | 301 | | |
283 | 302 | | |
| |||
305 | 324 | | |
306 | 325 | | |
307 | 326 | | |
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 | 327 | | |
356 | 328 | | |
357 | 329 | | |
| |||
612 | 584 | | |
613 | 585 | | |
614 | 586 | | |
615 | | - | |
| 587 | + | |
| 588 | + | |
616 | 589 | | |
617 | 590 | | |
618 | 591 | | |
| |||
0 commit comments