diff options
Diffstat (limited to 'subcmds')
| -rw-r--r-- | subcmds/init.py | 24 | ||||
| -rw-r--r-- | subcmds/sync.py | 24 |
2 files changed, 42 insertions, 6 deletions
diff --git a/subcmds/init.py b/subcmds/init.py index 3c68c2c3..8a29321e 100644 --- a/subcmds/init.py +++ b/subcmds/init.py | |||
| @@ -15,6 +15,8 @@ | |||
| 15 | # limitations under the License. | 15 | # limitations under the License. |
| 16 | 16 | ||
| 17 | from __future__ import print_function | 17 | from __future__ import print_function |
| 18 | |||
| 19 | import optparse | ||
| 18 | import os | 20 | import os |
| 19 | import platform | 21 | import platform |
| 20 | import re | 22 | import re |
| @@ -128,6 +130,10 @@ to update the working directory files. | |||
| 128 | g.add_option('--clone-filter', action='store', default='blob:none', | 130 | g.add_option('--clone-filter', action='store', default='blob:none', |
| 129 | dest='clone_filter', | 131 | dest='clone_filter', |
| 130 | help='filter for use with --partial-clone [default: %default]') | 132 | help='filter for use with --partial-clone [default: %default]') |
| 133 | # TODO(vapier): Expose option with real help text once this has been in the | ||
| 134 | # wild for a while w/out significant bug reports. Goal is by ~Sep 2020. | ||
| 135 | g.add_option('--worktree', action='store_true', | ||
| 136 | help=optparse.SUPPRESS_HELP) | ||
| 131 | g.add_option('--archive', | 137 | g.add_option('--archive', |
| 132 | dest='archive', action='store_true', | 138 | dest='archive', action='store_true', |
| 133 | help='checkout an archive instead of a git repository for ' | 139 | help='checkout an archive instead of a git repository for ' |
| @@ -246,6 +252,20 @@ to update the working directory files. | |||
| 246 | if opt.dissociate: | 252 | if opt.dissociate: |
| 247 | m.config.SetString('repo.dissociate', 'true') | 253 | m.config.SetString('repo.dissociate', 'true') |
| 248 | 254 | ||
| 255 | if opt.worktree: | ||
| 256 | if opt.mirror: | ||
| 257 | print('fatal: --mirror and --worktree are incompatible', | ||
| 258 | file=sys.stderr) | ||
| 259 | sys.exit(1) | ||
| 260 | if opt.submodules: | ||
| 261 | print('fatal: --submodules and --worktree are incompatible', | ||
| 262 | file=sys.stderr) | ||
| 263 | sys.exit(1) | ||
| 264 | m.config.SetString('repo.worktree', 'true') | ||
| 265 | if is_new: | ||
| 266 | m.use_git_worktrees = True | ||
| 267 | print('warning: --worktree is experimental!', file=sys.stderr) | ||
| 268 | |||
| 249 | if opt.archive: | 269 | if opt.archive: |
| 250 | if is_new: | 270 | if is_new: |
| 251 | m.config.SetString('repo.archive', 'true') | 271 | m.config.SetString('repo.archive', 'true') |
| @@ -459,6 +479,10 @@ to update the working directory files. | |||
| 459 | % ('.'.join(str(x) for x in MIN_GIT_VERSION_SOFT),), | 479 | % ('.'.join(str(x) for x in MIN_GIT_VERSION_SOFT),), |
| 460 | file=sys.stderr) | 480 | file=sys.stderr) |
| 461 | 481 | ||
| 482 | if opt.worktree: | ||
| 483 | # Older versions of git supported worktree, but had dangerous gc bugs. | ||
| 484 | git_require((2, 15, 0), fail=True, msg='git gc worktree corruption') | ||
| 485 | |||
| 462 | self._SyncManifest(opt) | 486 | self._SyncManifest(opt) |
| 463 | self._LinkManifest(opt.manifest_name) | 487 | self._LinkManifest(opt.manifest_name) |
| 464 | 488 | ||
diff --git a/subcmds/sync.py b/subcmds/sync.py index 0ac308e6..49867a97 100644 --- a/subcmds/sync.py +++ b/subcmds/sync.py | |||
| @@ -15,6 +15,8 @@ | |||
| 15 | # limitations under the License. | 15 | # limitations under the License. |
| 16 | 16 | ||
| 17 | from __future__ import print_function | 17 | from __future__ import print_function |
| 18 | |||
| 19 | import errno | ||
| 18 | import json | 20 | import json |
| 19 | import netrc | 21 | import netrc |
| 20 | from optparse import SUPPRESS_HELP | 22 | from optparse import SUPPRESS_HELP |
| @@ -569,7 +571,8 @@ later is required to fix a server side protocol bug. | |||
| 569 | gc_gitdirs = {} | 571 | gc_gitdirs = {} |
| 570 | for project in projects: | 572 | for project in projects: |
| 571 | # Make sure pruning never kicks in with shared projects. | 573 | # Make sure pruning never kicks in with shared projects. |
| 572 | if len(project.manifest.GetProjectsWithName(project.name)) > 1: | 574 | if (not project.use_git_worktrees and |
| 575 | len(project.manifest.GetProjectsWithName(project.name)) > 1): | ||
| 573 | print('%s: Shared project %s found, disabling pruning.' % | 576 | print('%s: Shared project %s found, disabling pruning.' % |
| 574 | (project.relpath, project.name)) | 577 | (project.relpath, project.name)) |
| 575 | if git_require((2, 7, 0)): | 578 | if git_require((2, 7, 0)): |
| @@ -637,13 +640,22 @@ later is required to fix a server side protocol bug. | |||
| 637 | # Delete the .git directory first, so we're less likely to have a partially | 640 | # Delete the .git directory first, so we're less likely to have a partially |
| 638 | # working git repository around. There shouldn't be any git projects here, | 641 | # working git repository around. There shouldn't be any git projects here, |
| 639 | # so rmtree works. | 642 | # so rmtree works. |
| 643 | dotgit = os.path.join(path, '.git') | ||
| 644 | # Try to remove plain files first in case of git worktrees. If this fails | ||
| 645 | # for any reason, we'll fall back to rmtree, and that'll display errors if | ||
| 646 | # it can't remove things either. | ||
| 647 | try: | ||
| 648 | platform_utils.remove(dotgit) | ||
| 649 | except OSError: | ||
| 650 | pass | ||
| 640 | try: | 651 | try: |
| 641 | platform_utils.rmtree(os.path.join(path, '.git')) | 652 | platform_utils.rmtree(dotgit) |
| 642 | except OSError as e: | 653 | except OSError as e: |
| 643 | print('Failed to remove %s (%s)' % (os.path.join(path, '.git'), str(e)), file=sys.stderr) | 654 | if e.errno != errno.ENOENT: |
| 644 | print('error: Failed to delete obsolete path %s' % path, file=sys.stderr) | 655 | print('error: %s: %s' % (dotgit, str(e)), file=sys.stderr) |
| 645 | print(' remove manually, then run sync again', file=sys.stderr) | 656 | print('error: %s: Failed to delete obsolete path; remove manually, then ' |
| 646 | return 1 | 657 | 'run sync again' % (path,), file=sys.stderr) |
| 658 | return 1 | ||
| 647 | 659 | ||
| 648 | # Delete everything under the worktree, except for directories that contain | 660 | # Delete everything under the worktree, except for directories that contain |
| 649 | # another git project | 661 | # another git project |
