diff options
Diffstat (limited to 'project.py')
-rw-r--r-- | project.py | 82 |
1 files changed, 57 insertions, 25 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: |
@@ -1876,8 +1881,6 @@ class Project(object): | |||
1876 | cmd.append('--quiet') | 1881 | cmd.append('--quiet') |
1877 | if not self.worktree: | 1882 | if not self.worktree: |
1878 | cmd.append('--update-head-ok') | 1883 | cmd.append('--update-head-ok') |
1879 | if self.manifest.IsMirror: | ||
1880 | cmd.append('--prune') | ||
1881 | cmd.append(name) | 1884 | cmd.append(name) |
1882 | 1885 | ||
1883 | # If using depth then we should not get all the tags since they may | 1886 | # If using depth then we should not get all the tags since they may |
@@ -1897,7 +1900,7 @@ class Project(object): | |||
1897 | 1900 | ||
1898 | if not self.manifest.IsMirror: | 1901 | if not self.manifest.IsMirror: |
1899 | branch = self.revisionExpr | 1902 | branch = self.revisionExpr |
1900 | if is_sha1 and depth: | 1903 | if is_sha1 and depth and git_require((1, 8, 3)): |
1901 | # Shallow checkout of a specific commit, fetch from that commit and not | 1904 | # Shallow checkout of a specific commit, fetch from that commit and not |
1902 | # the heads only as the commit might be deeper in the history. | 1905 | # the heads only as the commit might be deeper in the history. |
1903 | spec.append(branch) | 1906 | spec.append(branch) |
@@ -1960,8 +1963,15 @@ class Project(object): | |||
1960 | # got what we wanted, else trigger a second run of all | 1963 | # got what we wanted, else trigger a second run of all |
1961 | # refs. | 1964 | # refs. |
1962 | if not self._CheckForSha1(): | 1965 | if not self._CheckForSha1(): |
1963 | return self._RemoteFetch(name=name, current_branch_only=False, | 1966 | if not depth: |
1964 | initial=False, quiet=quiet, alt_dir=alt_dir) | 1967 | # Avoid infinite recursion when depth is True (since depth implies |
1968 | # current_branch_only) | ||
1969 | return self._RemoteFetch(name=name, current_branch_only=False, | ||
1970 | initial=False, quiet=quiet, alt_dir=alt_dir) | ||
1971 | if self.clone_depth: | ||
1972 | self.clone_depth = None | ||
1973 | return self._RemoteFetch(name=name, current_branch_only=current_branch_only, | ||
1974 | initial=False, quiet=quiet, alt_dir=alt_dir) | ||
1965 | 1975 | ||
1966 | return ok | 1976 | return ok |
1967 | 1977 | ||
@@ -2155,19 +2165,24 @@ class Project(object): | |||
2155 | raise GitError('%s merge %s ' % (self.name, head)) | 2165 | raise GitError('%s merge %s ' % (self.name, head)) |
2156 | 2166 | ||
2157 | def _InitGitDir(self, mirror_git=None): | 2167 | def _InitGitDir(self, mirror_git=None): |
2158 | if not os.path.exists(self.gitdir): | 2168 | init_git_dir = not os.path.exists(self.gitdir) |
2159 | 2169 | init_obj_dir = not os.path.exists(self.objdir) | |
2160 | # Initialize the bare repository, which contains all of the objects. | 2170 | # Initialize the bare repository, which contains all of the objects. |
2161 | if not os.path.exists(self.objdir): | 2171 | if init_obj_dir: |
2162 | os.makedirs(self.objdir) | 2172 | os.makedirs(self.objdir) |
2163 | self.bare_objdir.init() | 2173 | self.bare_objdir.init() |
2164 | 2174 | ||
2165 | # If we have a separate directory to hold refs, initialize it as well. | 2175 | # If we have a separate directory to hold refs, initialize it as well. |
2166 | if self.objdir != self.gitdir: | 2176 | if self.objdir != self.gitdir: |
2177 | if init_git_dir: | ||
2167 | os.makedirs(self.gitdir) | 2178 | os.makedirs(self.gitdir) |
2179 | |||
2180 | if init_obj_dir or init_git_dir: | ||
2168 | self._ReferenceGitDir(self.objdir, self.gitdir, share_refs=False, | 2181 | self._ReferenceGitDir(self.objdir, self.gitdir, share_refs=False, |
2169 | copy_all=True) | 2182 | copy_all=True) |
2183 | self._CheckDirReference(self.objdir, self.gitdir, share_refs=False) | ||
2170 | 2184 | ||
2185 | if init_git_dir: | ||
2171 | mp = self.manifest.manifestProject | 2186 | mp = self.manifest.manifestProject |
2172 | ref_dir = mp.config.GetString('repo.reference') or '' | 2187 | ref_dir = mp.config.GetString('repo.reference') or '' |
2173 | 2188 | ||
@@ -2273,6 +2288,21 @@ class Project(object): | |||
2273 | msg = 'manifest set to %s' % self.revisionExpr | 2288 | msg = 'manifest set to %s' % self.revisionExpr |
2274 | self.bare_git.symbolic_ref('-m', msg, ref, dst) | 2289 | self.bare_git.symbolic_ref('-m', msg, ref, dst) |
2275 | 2290 | ||
2291 | def _CheckDirReference(self, srcdir, destdir, share_refs): | ||
2292 | symlink_files = self.shareable_files | ||
2293 | symlink_dirs = self.shareable_dirs | ||
2294 | if share_refs: | ||
2295 | symlink_files += self.working_tree_files | ||
2296 | symlink_dirs += self.working_tree_dirs | ||
2297 | to_symlink = symlink_files + symlink_dirs | ||
2298 | for name in set(to_symlink): | ||
2299 | dst = os.path.realpath(os.path.join(destdir, name)) | ||
2300 | if os.path.lexists(dst): | ||
2301 | src = os.path.realpath(os.path.join(srcdir, name)) | ||
2302 | # Fail if the links are pointing to the wrong place | ||
2303 | if src != dst: | ||
2304 | raise GitError('cannot overwrite a local work tree') | ||
2305 | |||
2276 | def _ReferenceGitDir(self, gitdir, dotgit, share_refs, copy_all): | 2306 | def _ReferenceGitDir(self, gitdir, dotgit, share_refs, copy_all): |
2277 | """Update |dotgit| to reference |gitdir|, using symlinks where possible. | 2307 | """Update |dotgit| to reference |gitdir|, using symlinks where possible. |
2278 | 2308 | ||
@@ -2284,13 +2314,11 @@ class Project(object): | |||
2284 | copy_all: If true, copy all remaining files from |gitdir| -> |dotgit|. | 2314 | copy_all: If true, copy all remaining files from |gitdir| -> |dotgit|. |
2285 | This saves you the effort of initializing |dotgit| yourself. | 2315 | This saves you the effort of initializing |dotgit| yourself. |
2286 | """ | 2316 | """ |
2287 | # These objects can be shared between several working trees. | 2317 | symlink_files = self.shareable_files |
2288 | symlink_files = ['description', 'info'] | 2318 | symlink_dirs = self.shareable_dirs |
2289 | symlink_dirs = ['hooks', 'objects', 'rr-cache', 'svn'] | ||
2290 | if share_refs: | 2319 | if share_refs: |
2291 | # These objects can only be used by a single working tree. | 2320 | symlink_files += self.working_tree_files |
2292 | symlink_files += ['config', 'packed-refs', 'shallow'] | 2321 | symlink_dirs += self.working_tree_dirs |
2293 | symlink_dirs += ['logs', 'refs'] | ||
2294 | to_symlink = symlink_files + symlink_dirs | 2322 | to_symlink = symlink_files + symlink_dirs |
2295 | 2323 | ||
2296 | to_copy = [] | 2324 | to_copy = [] |
@@ -2302,8 +2330,8 @@ class Project(object): | |||
2302 | src = os.path.realpath(os.path.join(gitdir, name)) | 2330 | src = os.path.realpath(os.path.join(gitdir, name)) |
2303 | dst = os.path.realpath(os.path.join(dotgit, name)) | 2331 | dst = os.path.realpath(os.path.join(dotgit, name)) |
2304 | 2332 | ||
2305 | if os.path.lexists(dst) and not os.path.islink(dst): | 2333 | if os.path.lexists(dst): |
2306 | raise GitError('cannot overwrite a local work tree') | 2334 | continue |
2307 | 2335 | ||
2308 | # If the source dir doesn't exist, create an empty dir. | 2336 | # If the source dir doesn't exist, create an empty dir. |
2309 | if name in symlink_dirs and not os.path.lexists(src): | 2337 | if name in symlink_dirs and not os.path.lexists(src): |
@@ -2332,11 +2360,15 @@ class Project(object): | |||
2332 | 2360 | ||
2333 | def _InitWorkTree(self): | 2361 | def _InitWorkTree(self): |
2334 | dotgit = os.path.join(self.worktree, '.git') | 2362 | dotgit = os.path.join(self.worktree, '.git') |
2335 | if not os.path.exists(dotgit): | 2363 | init_dotgit = not os.path.exists(dotgit) |
2364 | if init_dotgit: | ||
2336 | os.makedirs(dotgit) | 2365 | os.makedirs(dotgit) |
2337 | self._ReferenceGitDir(self.gitdir, dotgit, share_refs=True, | 2366 | self._ReferenceGitDir(self.gitdir, dotgit, share_refs=True, |
2338 | copy_all=False) | 2367 | copy_all=False) |
2339 | 2368 | ||
2369 | self._CheckDirReference(self.gitdir, dotgit, share_refs=True) | ||
2370 | |||
2371 | if init_dotgit: | ||
2340 | _lwrite(os.path.join(dotgit, HEAD), '%s\n' % self.GetRevisionId()) | 2372 | _lwrite(os.path.join(dotgit, HEAD), '%s\n' % self.GetRevisionId()) |
2341 | 2373 | ||
2342 | cmd = ['read-tree', '--reset', '-u'] | 2374 | cmd = ['read-tree', '--reset', '-u'] |