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
This commit is contained in:
Nikolai Merinov 2018-10-19 15:07:05 +05:00
parent b3133a3164
commit 09f0abb0ef
3 changed files with 24 additions and 0 deletions

View File

@ -1310,6 +1310,16 @@ class Project(object):
submodules=submodules)): submodules=submodules)):
return False 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: if self.worktree:
self._InitMRef() self._InitMRef()
else: else:

3
repo
View File

@ -190,6 +190,9 @@ group.add_option('--mirror',
group.add_option('--reference', group.add_option('--reference',
dest='reference', dest='reference',
help='location of mirror directory', metavar='DIR') 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, group.add_option('--depth', type='int', default=None,
dest='depth', dest='depth',
help='create a shallow clone with given depth; see git clone') help='create a shallow clone with given depth; see git clone')

View File

@ -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 directory when fetching from the server. This will make the sync
go a lot faster by reducing data traffic on the network. 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 The --no-clone-bundle option disables any attempt to use
$URL/clone.bundle to bootstrap a new Git repository from a $URL/clone.bundle to bootstrap a new Git repository from a
resumeable bundle file on a content delivery network. This resumeable bundle file on a content delivery network. This
@ -103,6 +108,9 @@ to update the working directory files.
g.add_option('--reference', g.add_option('--reference',
dest='reference', dest='reference',
help='location of mirror directory', metavar='DIR') 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, g.add_option('--depth', type='int', default=None,
dest='depth', dest='depth',
help='create a shallow clone with given depth; see git clone') help='create a shallow clone with given depth; see git clone')
@ -219,6 +227,9 @@ to update the working directory files.
if opt.reference: if opt.reference:
m.config.SetString('repo.reference', opt.reference) m.config.SetString('repo.reference', opt.reference)
if opt.dissociate:
m.config.SetString('repo.dissociate', 'true')
if opt.archive: if opt.archive:
if is_new: if is_new:
m.config.SetString('repo.archive', 'true') m.config.SetString('repo.archive', 'true')