summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Chang <jasonnc@google.com>2023-05-23 13:06:55 -0700
committerJason Chang <jasonnc@google.com>2023-05-25 22:37:04 +0000
commit17833322d9e0c650310e55f806d5e3545c265c2a (patch)
tree67cd339bede0227bd43bd1e6fb9cc66fcb83d6b4
parent04cba4add52b11a27d09d73c2cbfebcd67a1f2cc (diff)
downloadgit-repo-17833322d9e0c650310e55f806d5e3545c265c2a.tar.gz
Add envar to replace shallow clones with partial
An investigation go/git-repo-shallow shows a number of problems when doing a shallow git fetch/clone. This change introduces an environment variable REPO_ALLOW_SHALLOW. When this environment variable is set to 1 during a repo init or repo sync all shallow git fetch commands are replaced with partial fetch commands. Any shallow repository needing update is unshallowed. This behavior continues until a subsequent repo sync command is run with REPO_ALLOW_SHALLOW set to 1. Bug: b/274340522 Change-Id: I1c3188270629359e52449788897d9d4988ebf280 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/374754 Reviewed-by: Josip Sokcevic <sokcevic@google.com> Tested-by: Jason Chang <jasonnc@google.com>
-rw-r--r--manifest_xml.py6
-rw-r--r--project.py30
-rw-r--r--subcmds/init.py6
-rw-r--r--subcmds/sync.py13
4 files changed, 55 insertions, 0 deletions
diff --git a/manifest_xml.py b/manifest_xml.py
index 14b03a30..555bf736 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -982,6 +982,12 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
982 return None 982 return None
983 983
984 @property 984 @property
985 def CloneFilterForDepth(self):
986 if self.manifestProject.clone_filter_for_depth:
987 return self.manifestProject.clone_filter_for_depth
988 return None
989
990 @property
985 def PartialCloneExclude(self): 991 def PartialCloneExclude(self):
986 exclude = self.manifest.manifestProject.partial_clone_exclude or "" 992 exclude = self.manifest.manifestProject.partial_clone_exclude or ""
987 return set(x.strip() for x in exclude.split(",")) 993 return set(x.strip() for x in exclude.split(","))
diff --git a/project.py b/project.py
index ff018393..83f3eff9 100644
--- a/project.py
+++ b/project.py
@@ -1186,6 +1186,7 @@ class Project(object):
1186 ssh_proxy=None, 1186 ssh_proxy=None,
1187 clone_filter=None, 1187 clone_filter=None,
1188 partial_clone_exclude=set(), 1188 partial_clone_exclude=set(),
1189 clone_filter_for_depth=None,
1189 ): 1190 ):
1190 """Perform only the network IO portion of the sync process. 1191 """Perform only the network IO portion of the sync process.
1191 Local working directory/branch state is not affected. 1192 Local working directory/branch state is not affected.
@@ -1295,6 +1296,10 @@ class Project(object):
1295 else: 1296 else:
1296 depth = self.manifest.manifestProject.depth 1297 depth = self.manifest.manifestProject.depth
1297 1298
1299 if depth and clone_filter_for_depth:
1300 depth = None
1301 clone_filter = clone_filter_for_depth
1302
1298 # See if we can skip the network fetch entirely. 1303 # See if we can skip the network fetch entirely.
1299 remote_fetched = False 1304 remote_fetched = False
1300 if not ( 1305 if not (
@@ -3885,6 +3890,11 @@ class ManifestProject(MetaProject):
3885 return self.config.GetString("repo.partialcloneexclude") 3890 return self.config.GetString("repo.partialcloneexclude")
3886 3891
3887 @property 3892 @property
3893 def clone_filter_for_depth(self):
3894 """Replace shallow clone with partial clone."""
3895 return self.config.GetString("repo.clonefilterfordepth")
3896
3897 @property
3888 def manifest_platform(self): 3898 def manifest_platform(self):
3889 """The --platform argument from `repo init`.""" 3899 """The --platform argument from `repo init`."""
3890 return self.config.GetString("manifest.platform") 3900 return self.config.GetString("manifest.platform")
@@ -3961,6 +3971,7 @@ class ManifestProject(MetaProject):
3961 manifest_name=spec.manifestName, 3971 manifest_name=spec.manifestName,
3962 this_manifest_only=True, 3972 this_manifest_only=True,
3963 outer_manifest=False, 3973 outer_manifest=False,
3974 clone_filter_for_depth=mp.clone_filter_for_depth,
3964 ) 3975 )
3965 3976
3966 def Sync( 3977 def Sync(
@@ -3991,6 +4002,7 @@ class ManifestProject(MetaProject):
3991 tags="", 4002 tags="",
3992 this_manifest_only=False, 4003 this_manifest_only=False,
3993 outer_manifest=True, 4004 outer_manifest=True,
4005 clone_filter_for_depth=None,
3994 ): 4006 ):
3995 """Sync the manifest and all submanifests. 4007 """Sync the manifest and all submanifests.
3996 4008
@@ -4035,6 +4047,8 @@ class ManifestProject(MetaProject):
4035 current sub manifest. 4047 current sub manifest.
4036 outer_manifest: a boolean, whether to start at the outermost 4048 outer_manifest: a boolean, whether to start at the outermost
4037 manifest. 4049 manifest.
4050 clone_filter_for_depth: a string, when specified replaces shallow
4051 clones with partial.
4038 4052
4039 Returns: 4053 Returns:
4040 a boolean, whether the sync was successful. 4054 a boolean, whether the sync was successful.
@@ -4297,6 +4311,9 @@ class ManifestProject(MetaProject):
4297 file=sys.stderr, 4311 file=sys.stderr,
4298 ) 4312 )
4299 4313
4314 if clone_filter_for_depth is not None:
4315 self.ConfigureCloneFilterForDepth(clone_filter_for_depth)
4316
4300 if use_superproject is not None: 4317 if use_superproject is not None:
4301 self.config.SetBoolean("repo.superproject", use_superproject) 4318 self.config.SetBoolean("repo.superproject", use_superproject)
4302 4319
@@ -4311,6 +4328,7 @@ class ManifestProject(MetaProject):
4311 submodules=submodules, 4328 submodules=submodules,
4312 clone_filter=clone_filter, 4329 clone_filter=clone_filter,
4313 partial_clone_exclude=self.manifest.PartialCloneExclude, 4330 partial_clone_exclude=self.manifest.PartialCloneExclude,
4331 clone_filter_for_depth=self.manifest.CloneFilterForDepth,
4314 ).success 4332 ).success
4315 if not success: 4333 if not success:
4316 r = self.GetRemote() 4334 r = self.GetRemote()
@@ -4415,6 +4433,18 @@ class ManifestProject(MetaProject):
4415 4433
4416 return True 4434 return True
4417 4435
4436 def ConfigureCloneFilterForDepth(self, clone_filter_for_depth):
4437 """Configure clone filter to replace shallow clones.
4438
4439 Args:
4440 clone_filter_for_depth: a string or None, e.g. 'blob:none' will
4441 disable shallow clones and replace with partial clone. None will
4442 enable shallow clones.
4443 """
4444 self.config.SetString(
4445 "repo.clonefilterfordepth", clone_filter_for_depth
4446 )
4447
4418 def _ConfigureDepth(self, depth): 4448 def _ConfigureDepth(self, depth):
4419 """Configure the depth we'll sync down. 4449 """Configure the depth we'll sync down.
4420 4450
diff --git a/subcmds/init.py b/subcmds/init.py
index 9946466d..6d7fd857 100644
--- a/subcmds/init.py
+++ b/subcmds/init.py
@@ -20,6 +20,8 @@ from command import InteractiveCommand, MirrorSafeCommand
20from git_command import git_require, MIN_GIT_VERSION_SOFT, MIN_GIT_VERSION_HARD 20from git_command import git_require, MIN_GIT_VERSION_SOFT, MIN_GIT_VERSION_HARD
21from wrapper import Wrapper 21from wrapper import Wrapper
22 22
23_REPO_ALLOW_SHALLOW = os.environ.get("REPO_ALLOW_SHALLOW")
24
23 25
24class Init(InteractiveCommand, MirrorSafeCommand): 26class Init(InteractiveCommand, MirrorSafeCommand):
25 COMMON = True 27 COMMON = True
@@ -125,6 +127,9 @@ to update the working directory files.
125 # manifest project is special and is created when instantiating the 127 # manifest project is special and is created when instantiating the
126 # manifest which happens before we parse options. 128 # manifest which happens before we parse options.
127 self.manifest.manifestProject.clone_depth = opt.manifest_depth 129 self.manifest.manifestProject.clone_depth = opt.manifest_depth
130 clone_filter_for_depth = (
131 "blob:none" if (_REPO_ALLOW_SHALLOW == "0") else None
132 )
128 if not self.manifest.manifestProject.Sync( 133 if not self.manifest.manifestProject.Sync(
129 manifest_url=opt.manifest_url, 134 manifest_url=opt.manifest_url,
130 manifest_branch=opt.manifest_branch, 135 manifest_branch=opt.manifest_branch,
@@ -140,6 +145,7 @@ to update the working directory files.
140 partial_clone=opt.partial_clone, 145 partial_clone=opt.partial_clone,
141 clone_filter=opt.clone_filter, 146 clone_filter=opt.clone_filter,
142 partial_clone_exclude=opt.partial_clone_exclude, 147 partial_clone_exclude=opt.partial_clone_exclude,
148 clone_filter_for_depth=clone_filter_for_depth,
143 clone_bundle=opt.clone_bundle, 149 clone_bundle=opt.clone_bundle,
144 git_lfs=opt.git_lfs, 150 git_lfs=opt.git_lfs,
145 use_superproject=opt.use_superproject, 151 use_superproject=opt.use_superproject,
diff --git a/subcmds/sync.py b/subcmds/sync.py
index a44ed5b4..9ae8a4ce 100644
--- a/subcmds/sync.py
+++ b/subcmds/sync.py
@@ -79,6 +79,8 @@ _ONE_DAY_S = 24 * 60 * 60
79_REPO_AUTO_GC = "REPO_AUTO_GC" 79_REPO_AUTO_GC = "REPO_AUTO_GC"
80_AUTO_GC = os.environ.get(_REPO_AUTO_GC) == "1" 80_AUTO_GC = os.environ.get(_REPO_AUTO_GC) == "1"
81 81
82_REPO_ALLOW_SHALLOW = os.environ.get("REPO_ALLOW_SHALLOW")
83
82 84
83class _FetchOneResult(NamedTuple): 85class _FetchOneResult(NamedTuple):
84 """_FetchOne return value. 86 """_FetchOne return value.
@@ -638,6 +640,7 @@ later is required to fix a server side protocol bug.
638 ssh_proxy=self.ssh_proxy, 640 ssh_proxy=self.ssh_proxy,
639 clone_filter=project.manifest.CloneFilter, 641 clone_filter=project.manifest.CloneFilter,
640 partial_clone_exclude=project.manifest.PartialCloneExclude, 642 partial_clone_exclude=project.manifest.PartialCloneExclude,
643 clone_filter_for_depth=project.manifest.CloneFilterForDepth,
641 ) 644 )
642 success = sync_result.success 645 success = sync_result.success
643 remote_fetched = sync_result.remote_fetched 646 remote_fetched = sync_result.remote_fetched
@@ -1440,6 +1443,7 @@ later is required to fix a server side protocol bug.
1440 submodules=mp.manifest.HasSubmodules, 1443 submodules=mp.manifest.HasSubmodules,
1441 clone_filter=mp.manifest.CloneFilter, 1444 clone_filter=mp.manifest.CloneFilter,
1442 partial_clone_exclude=mp.manifest.PartialCloneExclude, 1445 partial_clone_exclude=mp.manifest.PartialCloneExclude,
1446 clone_filter_for_depth=mp.manifest.CloneFilterForDepth,
1443 ) 1447 )
1444 finish = time.time() 1448 finish = time.time()
1445 self.event_log.AddSync( 1449 self.event_log.AddSync(
@@ -1589,6 +1593,15 @@ later is required to fix a server side protocol bug.
1589 _PostRepoUpgrade(manifest, quiet=opt.quiet) 1593 _PostRepoUpgrade(manifest, quiet=opt.quiet)
1590 1594
1591 mp = manifest.manifestProject 1595 mp = manifest.manifestProject
1596
1597 if _REPO_ALLOW_SHALLOW is not None:
1598 if _REPO_ALLOW_SHALLOW == "1":
1599 mp.ConfigureCloneFilterForDepth(None)
1600 elif (
1601 _REPO_ALLOW_SHALLOW == "0" and mp.clone_filter_for_depth is None
1602 ):
1603 mp.ConfigureCloneFilterForDepth("blob:none")
1604
1592 if opt.mp_update: 1605 if opt.mp_update:
1593 self._UpdateAllManifestProjects(opt, mp, manifest_name) 1606 self._UpdateAllManifestProjects(opt, mp, manifest_name)
1594 else: 1607 else: