diff options
Diffstat (limited to 'project.py')
| -rw-r--r-- | project.py | 67 |
1 files changed, 47 insertions, 20 deletions
| @@ -544,6 +544,12 @@ class RepoHook(object): | |||
| 544 | 544 | ||
| 545 | 545 | ||
| 546 | class Project(object): | 546 | class Project(object): |
| 547 | # These objects can be shared between several working trees. | ||
| 548 | shareable_files = ['description', 'info'] | ||
| 549 | shareable_dirs = ['hooks', 'objects', 'rr-cache', 'svn'] | ||
| 550 | # These objects can only be used by a single working tree. | ||
| 551 | working_tree_files = ['config', 'packed-refs', 'shallow'] | ||
| 552 | working_tree_dirs = ['logs', 'refs'] | ||
| 547 | def __init__(self, | 553 | def __init__(self, |
| 548 | manifest, | 554 | manifest, |
| 549 | name, | 555 | name, |
| @@ -645,7 +651,7 @@ class Project(object): | |||
| 645 | 651 | ||
| 646 | @property | 652 | @property |
| 647 | def Exists(self): | 653 | def Exists(self): |
| 648 | return os.path.isdir(self.gitdir) | 654 | return os.path.isdir(self.gitdir) and os.path.isdir(self.objdir) |
| 649 | 655 | ||
| 650 | @property | 656 | @property |
| 651 | def CurrentBranch(self): | 657 | def CurrentBranch(self): |
| @@ -1131,7 +1137,6 @@ class Project(object): | |||
| 1131 | "%s" % (tarpath, str(e)), file=sys.stderr) | 1137 | "%s" % (tarpath, str(e)), file=sys.stderr) |
| 1132 | self._CopyAndLinkFiles() | 1138 | self._CopyAndLinkFiles() |
| 1133 | return True | 1139 | return True |
| 1134 | |||
| 1135 | if is_new is None: | 1140 | if is_new is None: |
| 1136 | is_new = not self.Exists | 1141 | is_new = not self.Exists |
| 1137 | if is_new: | 1142 | if is_new: |
| @@ -2162,19 +2167,24 @@ class Project(object): | |||
| 2162 | raise GitError('%s merge %s ' % (self.name, head)) | 2167 | raise GitError('%s merge %s ' % (self.name, head)) |
| 2163 | 2168 | ||
| 2164 | def _InitGitDir(self, mirror_git=None): | 2169 | def _InitGitDir(self, mirror_git=None): |
| 2165 | if not os.path.exists(self.gitdir): | 2170 | init_git_dir = not os.path.exists(self.gitdir) |
| 2166 | 2171 | init_obj_dir = not os.path.exists(self.objdir) | |
| 2167 | # Initialize the bare repository, which contains all of the objects. | 2172 | # Initialize the bare repository, which contains all of the objects. |
| 2168 | if not os.path.exists(self.objdir): | 2173 | if init_obj_dir: |
| 2169 | os.makedirs(self.objdir) | 2174 | os.makedirs(self.objdir) |
| 2170 | self.bare_objdir.init() | 2175 | self.bare_objdir.init() |
| 2171 | 2176 | ||
| 2172 | # If we have a separate directory to hold refs, initialize it as well. | 2177 | # If we have a separate directory to hold refs, initialize it as well. |
| 2173 | if self.objdir != self.gitdir: | 2178 | if self.objdir != self.gitdir: |
| 2179 | if init_git_dir: | ||
| 2174 | os.makedirs(self.gitdir) | 2180 | os.makedirs(self.gitdir) |
| 2181 | |||
| 2182 | if init_obj_dir or init_git_dir: | ||
| 2175 | self._ReferenceGitDir(self.objdir, self.gitdir, share_refs=False, | 2183 | self._ReferenceGitDir(self.objdir, self.gitdir, share_refs=False, |
| 2176 | copy_all=True) | 2184 | copy_all=True) |
| 2185 | self._CheckDirReference(self.objdir, self.gitdir, share_refs=False) | ||
| 2177 | 2186 | ||
| 2187 | if init_git_dir: | ||
| 2178 | mp = self.manifest.manifestProject | 2188 | mp = self.manifest.manifestProject |
| 2179 | ref_dir = mp.config.GetString('repo.reference') or '' | 2189 | ref_dir = mp.config.GetString('repo.reference') or '' |
| 2180 | 2190 | ||
| @@ -2280,6 +2290,21 @@ class Project(object): | |||
| 2280 | msg = 'manifest set to %s' % self.revisionExpr | 2290 | msg = 'manifest set to %s' % self.revisionExpr |
| 2281 | self.bare_git.symbolic_ref('-m', msg, ref, dst) | 2291 | self.bare_git.symbolic_ref('-m', msg, ref, dst) |
| 2282 | 2292 | ||
| 2293 | def _CheckDirReference(self, srcdir, destdir, share_refs): | ||
| 2294 | symlink_files = self.shareable_files | ||
| 2295 | symlink_dirs = self.shareable_dirs | ||
| 2296 | if share_refs: | ||
| 2297 | symlink_files += self.working_tree_files | ||
| 2298 | symlink_dirs += self.working_tree_dirs | ||
| 2299 | to_symlink = symlink_files + symlink_dirs | ||
| 2300 | for name in set(to_symlink): | ||
| 2301 | dst = os.path.realpath(os.path.join(destdir, name)) | ||
| 2302 | if os.path.lexists(dst): | ||
| 2303 | src = os.path.realpath(os.path.join(srcdir, name)) | ||
| 2304 | # Fail if the links are pointing to the wrong place | ||
| 2305 | if src != dst: | ||
| 2306 | raise GitError('cannot overwrite a local work tree') | ||
| 2307 | |||
| 2283 | def _ReferenceGitDir(self, gitdir, dotgit, share_refs, copy_all): | 2308 | def _ReferenceGitDir(self, gitdir, dotgit, share_refs, copy_all): |
| 2284 | """Update |dotgit| to reference |gitdir|, using symlinks where possible. | 2309 | """Update |dotgit| to reference |gitdir|, using symlinks where possible. |
| 2285 | 2310 | ||
| @@ -2291,13 +2316,11 @@ class Project(object): | |||
| 2291 | copy_all: If true, copy all remaining files from |gitdir| -> |dotgit|. | 2316 | copy_all: If true, copy all remaining files from |gitdir| -> |dotgit|. |
| 2292 | This saves you the effort of initializing |dotgit| yourself. | 2317 | This saves you the effort of initializing |dotgit| yourself. |
| 2293 | """ | 2318 | """ |
| 2294 | # These objects can be shared between several working trees. | 2319 | symlink_files = self.shareable_files |
| 2295 | symlink_files = ['description', 'info'] | 2320 | symlink_dirs = self.shareable_dirs |
| 2296 | symlink_dirs = ['hooks', 'objects', 'rr-cache', 'svn'] | ||
| 2297 | if share_refs: | 2321 | if share_refs: |
| 2298 | # These objects can only be used by a single working tree. | 2322 | symlink_files += self.working_tree_files |
| 2299 | symlink_files += ['config', 'packed-refs', 'shallow'] | 2323 | symlink_dirs += self.working_tree_dirs |
| 2300 | symlink_dirs += ['logs', 'refs'] | ||
| 2301 | to_symlink = symlink_files + symlink_dirs | 2324 | to_symlink = symlink_files + symlink_dirs |
| 2302 | 2325 | ||
| 2303 | to_copy = [] | 2326 | to_copy = [] |
| @@ -2309,8 +2332,8 @@ class Project(object): | |||
| 2309 | src = os.path.realpath(os.path.join(gitdir, name)) | 2332 | src = os.path.realpath(os.path.join(gitdir, name)) |
| 2310 | dst = os.path.realpath(os.path.join(dotgit, name)) | 2333 | dst = os.path.realpath(os.path.join(dotgit, name)) |
| 2311 | 2334 | ||
| 2312 | if os.path.lexists(dst) and not os.path.islink(dst): | 2335 | if os.path.lexists(dst): |
| 2313 | raise GitError('cannot overwrite a local work tree') | 2336 | continue |
| 2314 | 2337 | ||
| 2315 | # If the source dir doesn't exist, create an empty dir. | 2338 | # If the source dir doesn't exist, create an empty dir. |
| 2316 | if name in symlink_dirs and not os.path.lexists(src): | 2339 | if name in symlink_dirs and not os.path.lexists(src): |
| @@ -2339,11 +2362,15 @@ class Project(object): | |||
| 2339 | 2362 | ||
| 2340 | def _InitWorkTree(self): | 2363 | def _InitWorkTree(self): |
| 2341 | dotgit = os.path.join(self.worktree, '.git') | 2364 | dotgit = os.path.join(self.worktree, '.git') |
| 2342 | if not os.path.exists(dotgit): | 2365 | init_dotgit = not os.path.exists(dotgit) |
| 2366 | if init_dotgit: | ||
| 2343 | os.makedirs(dotgit) | 2367 | os.makedirs(dotgit) |
| 2344 | self._ReferenceGitDir(self.gitdir, dotgit, share_refs=True, | 2368 | self._ReferenceGitDir(self.gitdir, dotgit, share_refs=True, |
| 2345 | copy_all=False) | 2369 | copy_all=False) |
| 2346 | 2370 | ||
| 2371 | self._CheckDirReference(self.gitdir, dotgit, share_refs=True) | ||
| 2372 | |||
| 2373 | if init_dotgit: | ||
| 2347 | _lwrite(os.path.join(dotgit, HEAD), '%s\n' % self.GetRevisionId()) | 2374 | _lwrite(os.path.join(dotgit, HEAD), '%s\n' % self.GetRevisionId()) |
| 2348 | 2375 | ||
| 2349 | cmd = ['read-tree', '--reset', '-u'] | 2376 | cmd = ['read-tree', '--reset', '-u'] |
