Commit 286af15
fix: Preserve submodule paths and release checkout handles on Windows
A quick rubber-stamp, admittedly. V4 will probably review all tests and
make it more proper, if there can be such a thing in python anyway.
<!-- agent -->
Both Windows failures came from os.renames() pruning a directory symlink
above the source after the rename succeeded. Unlike POSIX, Windows rmdir()
can remove a directory symlink even when its target is nonempty. Moving a
checkout through a worktree alias therefore deleted the alias and broke
configuration updates and rollback. Renaming metadata through a linked
.git/modules directory deleted that link and broke config.lock creation.
Route checkout moves, rollback, and metadata renames through one helper.
It creates destination parents and renames the source, then prunes empty
source parents only until it reaches a symlink or a directory it cannot
remove. This keeps ordinary empty-directory cleanup while preserving
parent links and their targets, including targets that become empty.
Leaf symlinks continue to move as links rather than moving their targets.
Exercise Windows directory-symlink removal semantics on POSIX in the
existing compatibility tests, and use native behavior on Windows. Both
reported failures reproduced locally before the fix. Strengthen assertions
that worktree and metadata parent aliases survive, their targets remain
directories, and leaf metadata symlinks move without moving their targets.
A further Windows run exposed a separate sharing violation during the
checkout move. Submodule.add() read HEAD through its temporary Repo but
left that Repo's persistent cat-file processes open. Those processes can
hold the checkout as their current directory and prevent its rename.
Close the owned Repo with a context manager when reading HEAD, including
on read failure, instead of waiting for garbage collection.
Add a regression that observes the real cat-file processes started for the
new checkout and requires them to have exited before add() returns. It
failed before the fix and now passes, along with the immediate move.
Validation: 155 passed, 3 skipped, and 1 expected failure across the
submodule and diff suites plus the commit-message hook success test on
macOS. Ruff lint and formatting, mypy for the changed module, and
git diff --check passed. Native Windows validation remains for CI.
Assisted-by: GPT 6.0
Co-authored-by: GPT 6.0 <codex@openai.com>1 parent 43a43cd commit 286af15
2 files changed
Lines changed: 76 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
444 | 444 | | |
445 | 445 | | |
446 | 446 | | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
447 | 461 | | |
448 | 462 | | |
449 | 463 | | |
| |||
685 | 699 | | |
686 | 700 | | |
687 | 701 | | |
688 | | - | |
| 702 | + | |
| 703 | + | |
| 704 | + | |
689 | 705 | | |
690 | 706 | | |
691 | 707 | | |
| |||
1120 | 1136 | | |
1121 | 1137 | | |
1122 | 1138 | | |
1123 | | - | |
| 1139 | + | |
1124 | 1140 | | |
1125 | 1141 | | |
1126 | 1142 | | |
| |||
1151 | 1167 | | |
1152 | 1168 | | |
1153 | 1169 | | |
1154 | | - | |
| 1170 | + | |
1155 | 1171 | | |
1156 | 1172 | | |
1157 | 1173 | | |
| |||
1504 | 1520 | | |
1505 | 1521 | | |
1506 | 1522 | | |
1507 | | - | |
| 1523 | + | |
1508 | 1524 | | |
1509 | 1525 | | |
1510 | | - | |
| 1526 | + | |
1511 | 1527 | | |
1512 | 1528 | | |
1513 | 1529 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
252 | 252 | | |
253 | 253 | | |
254 | 254 | | |
255 | | - | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 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 | + | |
256 | 300 | | |
257 | 301 | | |
258 | 302 | | |
259 | 303 | | |
260 | 304 | | |
261 | 305 | | |
262 | 306 | | |
| 307 | + | |
263 | 308 | | |
264 | 309 | | |
265 | 310 | | |
| |||
296 | 341 | | |
297 | 342 | | |
298 | 343 | | |
299 | | - | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
300 | 347 | | |
301 | 348 | | |
302 | 349 | | |
| |||
336 | 383 | | |
337 | 384 | | |
338 | 385 | | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
339 | 392 | | |
340 | 393 | | |
341 | 394 | | |
| |||
0 commit comments