From 09f0abb0efde83cfc4b850ebdc41f6ed3b61a123 Mon Sep 17 00:00:00 2001 From: Nikolai Merinov Date: Fri, 19 Oct 2018 15:07:05 +0500 Subject: [PATCH] init: --dissociate option to copy objects borrowed with --reference "repo init --reference" has two purposes: to decrease bandwidth used at clone time, and to decrease disk usage afterward, by using the reference repositories as an alternate store of objects even after the clone. The downside is that it makes the borrowing repositories dependent on the reference repositories, so it is easy to end up with missing objects by mistake after a cleanup operation like "git gc". To prevent that, v2.3.0-rc0~30^2 (clone: --dissociate option to mark that reference is only temporary, 2014-10-14), "git clone" gained a --dissociate option that makes --reference reuse objects from the reference repository at clone time but copy them over instead of using the reference as an alternate. This is more straightforward to use than plain --reference, at the cost of higher disk usage. Introduce a --dissociate to "repo init" that brings the same benefits to repo. The option is simply passed on to "git clone". Change-Id: Ib50a549eb71e0a2b3e234aea57537923962a80d4 --- project.py | 10 ++++++++++ repo | 3 +++ subcmds/init.py | 11 +++++++++++ 3 files changed, 24 insertions(+) diff --git a/project.py b/project.py index d551351b..a7001b01 100755 --- a/project.py +++ b/project.py @@ -1310,6 +1310,16 @@ class Project(object): submodules=submodules)): return False + mp = self.manifest.manifestProject + dissociate = mp.config.GetBoolean('repo.dissociate') + if dissociate: + alternates_file = os.path.join(self.gitdir, 'objects/info/alternates') + if os.path.exists(alternates_file): + cmd = ['repack', '-a', '-d'] + if GitCommand(self, cmd, bare=True).Wait() != 0: + return False + platform_utils.remove(alternates_file) + if self.worktree: self._InitMRef() else: diff --git a/repo b/repo index 6d3e8c2f..998731c6 100755 --- a/repo +++ b/repo @@ -190,6 +190,9 @@ group.add_option('--mirror', group.add_option('--reference', dest='reference', help='location of mirror directory', metavar='DIR') +group.add_option('--dissociate', + dest='dissociate', action='store_true', + help='dissociate from reference mirrors after clone') group.add_option('--depth', type='int', default=None, dest='depth', help='create a shallow clone with given depth; see git clone') diff --git a/subcmds/init.py b/subcmds/init.py index 4e51dfe8..6e99658f 100644 --- a/subcmds/init.py +++ b/subcmds/init.py @@ -61,6 +61,11 @@ directory use as much data as possible from the local reference directory when fetching from the server. This will make the sync go a lot faster by reducing data traffic on the network. +The --dissociate option can be used to borrow the objects from +the directory specified with the --reference option only to reduce +network transfer, and stop borrowing from them after a first clone +is made by making necessary local copies of borrowed objects. + The --no-clone-bundle option disables any attempt to use $URL/clone.bundle to bootstrap a new Git repository from a resumeable bundle file on a content delivery network. This @@ -103,6 +108,9 @@ to update the working directory files. g.add_option('--reference', dest='reference', help='location of mirror directory', metavar='DIR') + g.add_option('--dissociate', + dest='dissociate', action='store_true', + help='dissociate from reference mirrors after clone') g.add_option('--depth', type='int', default=None, dest='depth', help='create a shallow clone with given depth; see git clone') @@ -219,6 +227,9 @@ to update the working directory files. if opt.reference: m.config.SetString('repo.reference', opt.reference) + if opt.dissociate: + m.config.SetString('repo.dissociate', 'true') + if opt.archive: if is_new: m.config.SetString('repo.archive', 'true')