diff options
author | Conley Owens <cco3@android.com> | 2015-07-15 19:30:40 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2015-07-15 19:30:41 +0000 |
commit | b3d6e67196b4f9d85f3c11453a9502a6e71364d7 (patch) | |
tree | 6cff2795a98c3e6b04e2cc16b80607d994216c18 /project.py | |
parent | 503d66d8af1f13660b0982746e44060652a92b65 (diff) | |
parent | 384b3c594831e79348a2eb98809ef9f3e34f6aa2 (diff) | |
download | git-repo-b3d6e67196b4f9d85f3c11453a9502a6e71364d7.tar.gz |
Merge "Fail if gitdir does not point to objdir during sync"
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'] |