diff options
| -rw-r--r-- | subcmds/sync.py | 71 |
1 files changed, 57 insertions, 14 deletions
diff --git a/subcmds/sync.py b/subcmds/sync.py index ecf2ffc0..cc0b17e9 100644 --- a/subcmds/sync.py +++ b/subcmds/sync.py | |||
| @@ -457,6 +457,59 @@ later is required to fix a server side protocol bug. | |||
| 457 | else: | 457 | else: |
| 458 | self.manifest._Unload() | 458 | self.manifest._Unload() |
| 459 | 459 | ||
| 460 | def _DeleteProject(self, path): | ||
| 461 | print('Deleting obsolete path %s' % path, file=sys.stderr) | ||
| 462 | |||
| 463 | # Delete the .git directory first, so we're less likely to have a partially | ||
| 464 | # working git repository around. There shouldn't be any git projects here, | ||
| 465 | # so rmtree works. | ||
| 466 | try: | ||
| 467 | shutil.rmtree(os.path.join(path, '.git')) | ||
| 468 | except OSError: | ||
| 469 | print('Failed to remove %s' % os.path.join(path, '.git'), file=sys.stderr) | ||
| 470 | print('error: Failed to delete obsolete path %s' % path, file=sys.stderr) | ||
| 471 | print(' remove manually, then run sync again', file=sys.stderr) | ||
| 472 | return -1 | ||
| 473 | |||
| 474 | # Delete everything under the worktree, except for directories that contain | ||
| 475 | # another git project | ||
| 476 | dirs_to_remove = [] | ||
| 477 | failed = False | ||
| 478 | for root, dirs, files in os.walk(path): | ||
| 479 | for f in files: | ||
| 480 | try: | ||
| 481 | os.remove(os.path.join(root, f)) | ||
| 482 | except OSError: | ||
| 483 | print('Failed to remove %s' % os.path.join(root, f), file=sys.stderr) | ||
| 484 | failed = True | ||
| 485 | dirs[:] = [d for d in dirs | ||
| 486 | if not os.path.lexists(os.path.join(root, d, '.git'))] | ||
| 487 | dirs_to_remove += [os.path.join(root, d) for d in dirs | ||
| 488 | if os.path.join(root, d) not in dirs_to_remove] | ||
| 489 | for d in reversed(dirs_to_remove): | ||
| 490 | if len(os.listdir(d)) == 0: | ||
| 491 | try: | ||
| 492 | os.rmdir(d) | ||
| 493 | except OSError: | ||
| 494 | print('Failed to remove %s' % os.path.join(root, d), file=sys.stderr) | ||
| 495 | failed = True | ||
| 496 | continue | ||
| 497 | if failed: | ||
| 498 | print('error: Failed to delete obsolete path %s' % path, file=sys.stderr) | ||
| 499 | print(' remove manually, then run sync again', file=sys.stderr) | ||
| 500 | return -1 | ||
| 501 | |||
| 502 | # Try deleting parent dirs if they are empty | ||
| 503 | project_dir = path | ||
| 504 | while project_dir != self.manifest.topdir: | ||
| 505 | if len(os.listdir(project_dir)) == 0: | ||
| 506 | os.rmdir(project_dir) | ||
| 507 | else: | ||
| 508 | break | ||
| 509 | project_dir = os.path.dirname(project_dir) | ||
| 510 | |||
| 511 | return 0 | ||
| 512 | |||
| 460 | def UpdateProjectList(self): | 513 | def UpdateProjectList(self): |
| 461 | new_project_paths = [] | 514 | new_project_paths = [] |
| 462 | for project in self.GetProjects(None, missing_ok=True): | 515 | for project in self.GetProjects(None, missing_ok=True): |
| @@ -477,8 +530,8 @@ later is required to fix a server side protocol bug. | |||
| 477 | continue | 530 | continue |
| 478 | if path not in new_project_paths: | 531 | if path not in new_project_paths: |
| 479 | # If the path has already been deleted, we don't need to do it | 532 | # If the path has already been deleted, we don't need to do it |
| 480 | if os.path.exists(self.manifest.topdir + '/' + path): | 533 | gitdir = os.path.join(self.manifest.topdir, path, '.git') |
| 481 | gitdir = os.path.join(self.manifest.topdir, path, '.git') | 534 | if os.path.exists(gitdir): |
| 482 | project = Project( | 535 | project = Project( |
| 483 | manifest = self.manifest, | 536 | manifest = self.manifest, |
| 484 | name = path, | 537 | name = path, |
| @@ -497,18 +550,8 @@ later is required to fix a server side protocol bug. | |||
| 497 | print(' commit changes, then run sync again', | 550 | print(' commit changes, then run sync again', |
| 498 | file=sys.stderr) | 551 | file=sys.stderr) |
| 499 | return -1 | 552 | return -1 |
| 500 | else: | 553 | elif self._DeleteProject(project.worktree): |
| 501 | print('Deleting obsolete path %s' % project.worktree, | 554 | return -1 |
| 502 | file=sys.stderr) | ||
| 503 | shutil.rmtree(project.worktree) | ||
| 504 | # Try deleting parent subdirs if they are empty | ||
| 505 | project_dir = os.path.dirname(project.worktree) | ||
| 506 | while project_dir != self.manifest.topdir: | ||
| 507 | try: | ||
| 508 | os.rmdir(project_dir) | ||
| 509 | except OSError: | ||
| 510 | break | ||
| 511 | project_dir = os.path.dirname(project_dir) | ||
| 512 | 555 | ||
| 513 | new_project_paths.sort() | 556 | new_project_paths.sort() |
| 514 | fd = open(file_path, 'w') | 557 | fd = open(file_path, 'w') |
