Merge "Fail if gitdir does not point to objdir during sync"

This commit is contained in:
Conley Owens 2015-07-15 19:30:40 +00:00 committed by Gerrit Code Review
commit b3d6e67196

View File

@ -544,6 +544,12 @@ class RepoHook(object):
class Project(object): class Project(object):
# These objects can be shared between several working trees.
shareable_files = ['description', 'info']
shareable_dirs = ['hooks', 'objects', 'rr-cache', 'svn']
# These objects can only be used by a single working tree.
working_tree_files = ['config', 'packed-refs', 'shallow']
working_tree_dirs = ['logs', 'refs']
def __init__(self, def __init__(self,
manifest, manifest,
name, name,
@ -645,7 +651,7 @@ class Project(object):
@property @property
def Exists(self): def Exists(self):
return os.path.isdir(self.gitdir) return os.path.isdir(self.gitdir) and os.path.isdir(self.objdir)
@property @property
def CurrentBranch(self): def CurrentBranch(self):
@ -1131,7 +1137,6 @@ class Project(object):
"%s" % (tarpath, str(e)), file=sys.stderr) "%s" % (tarpath, str(e)), file=sys.stderr)
self._CopyAndLinkFiles() self._CopyAndLinkFiles()
return True return True
if is_new is None: if is_new is None:
is_new = not self.Exists is_new = not self.Exists
if is_new: if is_new:
@ -2162,19 +2167,24 @@ class Project(object):
raise GitError('%s merge %s ' % (self.name, head)) raise GitError('%s merge %s ' % (self.name, head))
def _InitGitDir(self, mirror_git=None): def _InitGitDir(self, mirror_git=None):
if not os.path.exists(self.gitdir): init_git_dir = not os.path.exists(self.gitdir)
init_obj_dir = not os.path.exists(self.objdir)
# Initialize the bare repository, which contains all of the objects. # Initialize the bare repository, which contains all of the objects.
if not os.path.exists(self.objdir): if init_obj_dir:
os.makedirs(self.objdir) os.makedirs(self.objdir)
self.bare_objdir.init() self.bare_objdir.init()
# If we have a separate directory to hold refs, initialize it as well. # If we have a separate directory to hold refs, initialize it as well.
if self.objdir != self.gitdir: if self.objdir != self.gitdir:
if init_git_dir:
os.makedirs(self.gitdir) os.makedirs(self.gitdir)
if init_obj_dir or init_git_dir:
self._ReferenceGitDir(self.objdir, self.gitdir, share_refs=False, self._ReferenceGitDir(self.objdir, self.gitdir, share_refs=False,
copy_all=True) copy_all=True)
self._CheckDirReference(self.objdir, self.gitdir, share_refs=False)
if init_git_dir:
mp = self.manifest.manifestProject mp = self.manifest.manifestProject
ref_dir = mp.config.GetString('repo.reference') or '' ref_dir = mp.config.GetString('repo.reference') or ''
@ -2280,6 +2290,21 @@ class Project(object):
msg = 'manifest set to %s' % self.revisionExpr msg = 'manifest set to %s' % self.revisionExpr
self.bare_git.symbolic_ref('-m', msg, ref, dst) self.bare_git.symbolic_ref('-m', msg, ref, dst)
def _CheckDirReference(self, srcdir, destdir, share_refs):
symlink_files = self.shareable_files
symlink_dirs = self.shareable_dirs
if share_refs:
symlink_files += self.working_tree_files
symlink_dirs += self.working_tree_dirs
to_symlink = symlink_files + symlink_dirs
for name in set(to_symlink):
dst = os.path.realpath(os.path.join(destdir, name))
if os.path.lexists(dst):
src = os.path.realpath(os.path.join(srcdir, name))
# Fail if the links are pointing to the wrong place
if src != dst:
raise GitError('cannot overwrite a local work tree')
def _ReferenceGitDir(self, gitdir, dotgit, share_refs, copy_all): def _ReferenceGitDir(self, gitdir, dotgit, share_refs, copy_all):
"""Update |dotgit| to reference |gitdir|, using symlinks where possible. """Update |dotgit| to reference |gitdir|, using symlinks where possible.
@ -2291,13 +2316,11 @@ class Project(object):
copy_all: If true, copy all remaining files from |gitdir| -> |dotgit|. copy_all: If true, copy all remaining files from |gitdir| -> |dotgit|.
This saves you the effort of initializing |dotgit| yourself. This saves you the effort of initializing |dotgit| yourself.
""" """
# These objects can be shared between several working trees. symlink_files = self.shareable_files
symlink_files = ['description', 'info'] symlink_dirs = self.shareable_dirs
symlink_dirs = ['hooks', 'objects', 'rr-cache', 'svn']
if share_refs: if share_refs:
# These objects can only be used by a single working tree. symlink_files += self.working_tree_files
symlink_files += ['config', 'packed-refs', 'shallow'] symlink_dirs += self.working_tree_dirs
symlink_dirs += ['logs', 'refs']
to_symlink = symlink_files + symlink_dirs to_symlink = symlink_files + symlink_dirs
to_copy = [] to_copy = []
@ -2309,8 +2332,8 @@ class Project(object):
src = os.path.realpath(os.path.join(gitdir, name)) src = os.path.realpath(os.path.join(gitdir, name))
dst = os.path.realpath(os.path.join(dotgit, name)) dst = os.path.realpath(os.path.join(dotgit, name))
if os.path.lexists(dst) and not os.path.islink(dst): if os.path.lexists(dst):
raise GitError('cannot overwrite a local work tree') continue
# If the source dir doesn't exist, create an empty dir. # If the source dir doesn't exist, create an empty dir.
if name in symlink_dirs and not os.path.lexists(src): if name in symlink_dirs and not os.path.lexists(src):
@ -2339,11 +2362,15 @@ class Project(object):
def _InitWorkTree(self): def _InitWorkTree(self):
dotgit = os.path.join(self.worktree, '.git') dotgit = os.path.join(self.worktree, '.git')
if not os.path.exists(dotgit): init_dotgit = not os.path.exists(dotgit)
if init_dotgit:
os.makedirs(dotgit) os.makedirs(dotgit)
self._ReferenceGitDir(self.gitdir, dotgit, share_refs=True, self._ReferenceGitDir(self.gitdir, dotgit, share_refs=True,
copy_all=False) copy_all=False)
self._CheckDirReference(self.gitdir, dotgit, share_refs=True)
if init_dotgit:
_lwrite(os.path.join(dotgit, HEAD), '%s\n' % self.GetRevisionId()) _lwrite(os.path.join(dotgit, HEAD), '%s\n' % self.GetRevisionId())
cmd = ['read-tree', '--reset', '-u'] cmd = ['read-tree', '--reset', '-u']