|
@@ -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):
|
|
|
|
|
-
|
|
|
|
|
- # Initialize the bare repository, which contains all of the objects.
|
|
|
|
|
- if not os.path.exists(self.objdir):
|
|
|
|
|
- os.makedirs(self.objdir)
|
|
|
|
|
- self.bare_objdir.init()
|
|
|
|
|
-
|
|
|
|
|
- # If we have a separate directory to hold refs, initialize it as well.
|
|
|
|
|
- if self.objdir != 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.
|
|
|
|
|
+ if init_obj_dir:
|
|
|
|
|
+ os.makedirs(self.objdir)
|
|
|
|
|
+ self.bare_objdir.init()
|
|
|
|
|
+
|
|
|
|
|
+ # If we have a separate directory to hold refs, initialize it as well.
|
|
|
|
|
+ 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 = ['description', 'info']
|
|
|
|
|
- symlink_dirs = ['hooks', 'objects', 'rr-cache', 'svn']
|
|
|
|
|
|
|
+ symlink_files = self.shareable_files
|
|
|
|
|
+ symlink_dirs = self.shareable_dirs
|
|
|
if share_refs:
|
|
if share_refs:
|
|
|
- # These objects can only be used by a single working tree.
|
|
|
|
|
- symlink_files += ['config', 'packed-refs', 'shallow']
|
|
|
|
|
- symlink_dirs += ['logs', 'refs']
|
|
|
|
|
|
|
+ symlink_files += self.working_tree_files
|
|
|
|
|
+ symlink_dirs += self.working_tree_dirs
|
|
|
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):
|
|
|
|
|
- raise GitError('cannot overwrite a local work tree')
|
|
|
|
|
|
|
+ if os.path.lexists(dst):
|
|
|
|
|
+ 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']
|