summaryrefslogtreecommitdiff
path: root/tools/buildman/builder.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/buildman/builder.py')
-rw-r--r--tools/buildman/builder.py48
1 files changed, 40 insertions, 8 deletions
diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py
index dbb75b35c1..c93946842a 100644
--- a/tools/buildman/builder.py
+++ b/tools/buildman/builder.py
@@ -1541,41 +1541,73 @@ class Builder:
"""Prepare the working directory for a thread.
This clones or fetches the repo into the thread's work directory.
+ Optionally, it can create a linked working tree of the repo in the
+ thread's work directory instead.
Args:
thread_num: Thread number (0, 1, ...)
- setup_git: True to set up a git repo clone
+ setup_git:
+ 'clone' to set up a git clone
+ 'worktree' to set up a git worktree
"""
thread_dir = self.GetThreadDir(thread_num)
builderthread.Mkdir(thread_dir)
git_dir = os.path.join(thread_dir, '.git')
- # Clone the repo if it doesn't already exist
- # TODO(sjg@chromium): Perhaps some git hackery to symlink instead, so
- # we have a private index but uses the origin repo's contents?
+ # Create a worktree or a git repo clone for this thread if it
+ # doesn't already exist
if setup_git and self.git_dir:
src_dir = os.path.abspath(self.git_dir)
- if os.path.exists(git_dir):
+ if os.path.isdir(git_dir):
+ # This is a clone of the src_dir repo, we can keep using
+ # it but need to fetch from src_dir.
Print('\rFetching repo for thread %d' % thread_num,
newline=False)
gitutil.Fetch(git_dir, thread_dir)
terminal.PrintClear()
- else:
+ elif os.path.isfile(git_dir):
+ # This is a worktree of the src_dir repo, we don't need to
+ # create it again or update it in any way.
+ pass
+ elif os.path.exists(git_dir):
+ # Don't know what could trigger this, but we probably
+ # can't create a git worktree/clone here.
+ raise ValueError('Git dir %s exists, but is not a file '
+ 'or a directory.' % git_dir)
+ elif setup_git == 'worktree':
+ Print('\rChecking out worktree for thread %d' % thread_num,
+ newline=False)
+ gitutil.AddWorktree(src_dir, thread_dir)
+ terminal.PrintClear()
+ elif setup_git == 'clone' or setup_git == True:
Print('\rCloning repo for thread %d' % thread_num,
newline=False)
gitutil.Clone(src_dir, thread_dir)
terminal.PrintClear()
+ else:
+ raise ValueError("Can't setup git repo with %s." % setup_git)
def _PrepareWorkingSpace(self, max_threads, setup_git):
"""Prepare the working directory for use.
- Set up the git repo for each thread.
+ Set up the git repo for each thread. Creates a linked working tree
+ if git-worktree is available, or clones the repo if it isn't.
Args:
max_threads: Maximum number of threads we expect to need.
- setup_git: True to set up a git repo clone
+ setup_git: True to set up a git worktree or a git clone
"""
builderthread.Mkdir(self._working_dir)
+ if setup_git and self.git_dir:
+ src_dir = os.path.abspath(self.git_dir)
+ if gitutil.CheckWorktreeIsAvailable(src_dir):
+ setup_git = 'worktree'
+ # If we previously added a worktree but the directory for it
+ # got deleted, we need to prune its files from the repo so
+ # that we can check out another in its place.
+ gitutil.PruneWorktrees(src_dir)
+ else:
+ setup_git = 'clone'
for thread in range(max_threads):
self._PrepareThread(thread, setup_git)