Commit 84d33f3
fix: Preserve directory symlinks when pruning submodule move sources
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.
Assisted-by: GPT 6.0
Co-authored-by: GPT 6.0 <codex@openai.com>1 parent 43a43cd commit 84d33f3
2 files changed
Lines changed: 43 additions & 6 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 | | |
| |||
1120 | 1134 | | |
1121 | 1135 | | |
1122 | 1136 | | |
1123 | | - | |
| 1137 | + | |
1124 | 1138 | | |
1125 | 1139 | | |
1126 | 1140 | | |
| |||
1151 | 1165 | | |
1152 | 1166 | | |
1153 | 1167 | | |
1154 | | - | |
| 1168 | + | |
1155 | 1169 | | |
1156 | 1170 | | |
1157 | 1171 | | |
| |||
1504 | 1518 | | |
1505 | 1519 | | |
1506 | 1520 | | |
1507 | | - | |
| 1521 | + | |
1508 | 1522 | | |
1509 | 1523 | | |
1510 | | - | |
| 1524 | + | |
1511 | 1525 | | |
1512 | 1526 | | |
1513 | 1527 | | |
| |||
| 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 | + | |
256 | 270 | | |
257 | 271 | | |
258 | 272 | | |
259 | 273 | | |
260 | 274 | | |
261 | 275 | | |
262 | 276 | | |
| 277 | + | |
263 | 278 | | |
264 | 279 | | |
265 | 280 | | |
| |||
296 | 311 | | |
297 | 312 | | |
298 | 313 | | |
299 | | - | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
300 | 317 | | |
301 | 318 | | |
302 | 319 | | |
| |||
336 | 353 | | |
337 | 354 | | |
338 | 355 | | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
339 | 362 | | |
340 | 363 | | |
341 | 364 | | |
| |||
0 commit comments