summaryrefslogtreecommitdiffstats
path: root/subcmds/sync.py
diff options
context:
space:
mode:
Diffstat (limited to 'subcmds/sync.py')
-rw-r--r--subcmds/sync.py85
1 files changed, 4 insertions, 81 deletions
diff --git a/subcmds/sync.py b/subcmds/sync.py
index eada76a7..f2af0ec3 100644
--- a/subcmds/sync.py
+++ b/subcmds/sync.py
@@ -16,7 +16,6 @@
16 16
17from __future__ import print_function 17from __future__ import print_function
18 18
19import errno
20import json 19import json
21import netrc 20import netrc
22from optparse import SUPPRESS_HELP 21from optparse import SUPPRESS_HELP
@@ -633,74 +632,6 @@ later is required to fix a server side protocol bug.
633 else: 632 else:
634 self.manifest._Unload() 633 self.manifest._Unload()
635 634
636 def _DeleteProject(self, path):
637 print('Deleting obsolete path %s' % path, file=sys.stderr)
638
639 # Delete the .git directory first, so we're less likely to have a partially
640 # working git repository around. There shouldn't be any git projects here,
641 # so rmtree works.
642 dotgit = os.path.join(path, '.git')
643 # Try to remove plain files first in case of git worktrees. If this fails
644 # for any reason, we'll fall back to rmtree, and that'll display errors if
645 # it can't remove things either.
646 try:
647 platform_utils.remove(dotgit)
648 except OSError:
649 pass
650 try:
651 platform_utils.rmtree(dotgit)
652 except OSError as e:
653 if e.errno != errno.ENOENT:
654 print('error: %s: %s' % (dotgit, str(e)), file=sys.stderr)
655 print('error: %s: Failed to delete obsolete path; remove manually, then '
656 'run sync again' % (path,), file=sys.stderr)
657 return 1
658
659 # Delete everything under the worktree, except for directories that contain
660 # another git project
661 dirs_to_remove = []
662 failed = False
663 for root, dirs, files in platform_utils.walk(path):
664 for f in files:
665 try:
666 platform_utils.remove(os.path.join(root, f))
667 except OSError as e:
668 print('Failed to remove %s (%s)' % (os.path.join(root, f), str(e)), file=sys.stderr)
669 failed = True
670 dirs[:] = [d for d in dirs
671 if not os.path.lexists(os.path.join(root, d, '.git'))]
672 dirs_to_remove += [os.path.join(root, d) for d in dirs
673 if os.path.join(root, d) not in dirs_to_remove]
674 for d in reversed(dirs_to_remove):
675 if platform_utils.islink(d):
676 try:
677 platform_utils.remove(d)
678 except OSError as e:
679 print('Failed to remove %s (%s)' % (os.path.join(root, d), str(e)), file=sys.stderr)
680 failed = True
681 elif len(platform_utils.listdir(d)) == 0:
682 try:
683 platform_utils.rmdir(d)
684 except OSError as e:
685 print('Failed to remove %s (%s)' % (os.path.join(root, d), str(e)), file=sys.stderr)
686 failed = True
687 continue
688 if failed:
689 print('error: Failed to delete obsolete path %s' % path, file=sys.stderr)
690 print(' remove manually, then run sync again', file=sys.stderr)
691 return 1
692
693 # Try deleting parent dirs if they are empty
694 project_dir = path
695 while project_dir != self.manifest.topdir:
696 if len(platform_utils.listdir(project_dir)) == 0:
697 platform_utils.rmdir(project_dir)
698 else:
699 break
700 project_dir = os.path.dirname(project_dir)
701
702 return 0
703
704 def UpdateProjectList(self, opt): 635 def UpdateProjectList(self, opt):
705 new_project_paths = [] 636 new_project_paths = []
706 for project in self.GetProjects(None, missing_ok=True): 637 for project in self.GetProjects(None, missing_ok=True):
@@ -727,23 +658,15 @@ later is required to fix a server side protocol bug.
727 remote=RemoteSpec('origin'), 658 remote=RemoteSpec('origin'),
728 gitdir=gitdir, 659 gitdir=gitdir,
729 objdir=gitdir, 660 objdir=gitdir,
661 use_git_worktrees=os.path.isfile(gitdir),
730 worktree=os.path.join(self.manifest.topdir, path), 662 worktree=os.path.join(self.manifest.topdir, path),
731 relpath=path, 663 relpath=path,
732 revisionExpr='HEAD', 664 revisionExpr='HEAD',
733 revisionId=None, 665 revisionId=None,
734 groups=None) 666 groups=None)
735 667 if not project.DeleteWorktree(
736 if project.IsDirty() and opt.force_remove_dirty: 668 quiet=opt.quiet,
737 print('WARNING: Removing dirty project "%s": uncommitted changes ' 669 force=opt.force_remove_dirty):
738 'erased' % project.relpath, file=sys.stderr)
739 self._DeleteProject(project.worktree)
740 elif project.IsDirty():
741 print('error: Cannot remove project "%s": uncommitted changes '
742 'are present' % project.relpath, file=sys.stderr)
743 print(' commit changes, then run sync again',
744 file=sys.stderr)
745 return 1
746 elif self._DeleteProject(project.worktree):
747 return 1 670 return 1
748 671
749 new_project_paths.sort() 672 new_project_paths.sort()