summaryrefslogtreecommitdiffstats
path: root/subcmds
diff options
context:
space:
mode:
Diffstat (limited to 'subcmds')
-rw-r--r--subcmds/sync.py71
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')