#!/usr/bin/env python # Copyright 2013 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # # Usage: # gclient-new-workdir.py <repository> <new_workdir> [<branch>] # import os import shutil import subprocess import sys import textwrap def print_err(msg): print >> sys.stderr, msg def usage(msg=None): if msg is not None: print_err('\n' + textwrap.dedent(msg) + '\n') usage_msg = 'Run without arguments to get usage help.' else: usage_msg = '''\ usage: %s <repository> <new_workdir> Clone an existing gclient directory, taking care of all sub-repositories Works similarly to 'git new-workdir'. <repository> should contain a .gclient file <new_workdir> must not exist ''' % os.path.basename(sys.argv[0]) print_err(textwrap.dedent(usage_msg)) sys.exit(1) def parse_options(): if sys.platform == 'win32': usage('This script cannot run on Windows because it uses symlinks.') if len(sys.argv) != 3: usage() repository = os.path.abspath(sys.argv[1]) new_workdir = sys.argv[2] if not os.path.exists(repository): usage('Repository does not exist: ' + repository) if os.path.exists(new_workdir): usage('New workdir already exists: ' + new_workdir) return repository, new_workdir def main(): repository, new_workdir = parse_options() gclient = os.path.join(repository, '.gclient') if not os.path.exists(gclient): print_err('No .gclient file: ' + gclient) os.makedirs(new_workdir) os.symlink(gclient, os.path.join(new_workdir, '.gclient')) for root, dirs, _ in os.walk(repository): if '.git' in dirs: workdir = root.replace(repository, new_workdir, 1) make_workdir(os.path.join(root, '.git'), os.path.join(workdir, '.git')) def make_workdir(repository, new_workdir): print('Creating: ' + new_workdir) os.makedirs(new_workdir) GIT_DIRECTORY_WHITELIST = [ 'config', 'info', 'hooks', 'logs/refs', 'objects', 'packed-refs', 'refs', 'remotes', 'rr-cache', 'svn' ] for entry in GIT_DIRECTORY_WHITELIST: make_symlink(repository, new_workdir, entry) shutil.copy2(os.path.join(repository, 'HEAD'), os.path.join(new_workdir, 'HEAD')) subprocess.check_call(['git', 'checkout', '-f'], cwd=new_workdir.rstrip('.git')) def make_symlink(repository, new_workdir, link): if not os.path.exists(os.path.join(repository, link)): return link_dir = os.path.dirname(os.path.join(new_workdir, link)) if not os.path.exists(link_dir): os.makedirs(link_dir) os.symlink(os.path.join(repository, link), os.path.join(new_workdir, link)) if __name__ == '__main__': sys.exit(main())