adam.treat@samsung.com | 62d817c | 2013-11-05 15:18:13 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | # Copyright 2013 The Chromium Authors. All rights reserved. |
| 3 | # Use of this source code is governed by a BSD-style license that can be |
| 4 | # found in the LICENSE file. |
| 5 | # |
| 6 | # Usage: |
Wei-Yin Chen (陳威尹) | 0520349 | 2017-05-11 00:07:53 -0700 | [diff] [blame] | 7 | # gclient-new-workdir.py [options] <repository> <new_workdir> |
adam.treat@samsung.com | 62d817c | 2013-11-05 15:18:13 +0000 | [diff] [blame] | 8 | # |
| 9 | |
Wei-Yin Chen (陳威尹) | 0520349 | 2017-05-11 00:07:53 -0700 | [diff] [blame] | 10 | import argparse |
adam.treat@samsung.com | 62d817c | 2013-11-05 15:18:13 +0000 | [diff] [blame] | 11 | import os |
| 12 | import shutil |
| 13 | import subprocess |
| 14 | import sys |
Wei-Yin Chen (陳威尹) | 56e4ad9 | 2017-05-23 01:05:38 -0700 | [diff] [blame^] | 15 | import textwrap |
adam.treat@samsung.com | 62d817c | 2013-11-05 15:18:13 +0000 | [diff] [blame] | 16 | |
sammc@chromium.org | 900a33f | 2015-09-29 06:57:09 +0000 | [diff] [blame] | 17 | import git_common |
| 18 | |
adam.treat@samsung.com | 62d817c | 2013-11-05 15:18:13 +0000 | [diff] [blame] | 19 | |
pgervais@chromium.org | f13c205 | 2013-11-15 20:09:23 +0000 | [diff] [blame] | 20 | def parse_options(): |
| 21 | if sys.platform == 'win32': |
Wei-Yin Chen (陳威尹) | 0520349 | 2017-05-11 00:07:53 -0700 | [diff] [blame] | 22 | print('ERROR: This script cannot run on Windows because it uses symlinks.') |
| 23 | sys.exit(1) |
pgervais@chromium.org | f13c205 | 2013-11-15 20:09:23 +0000 | [diff] [blame] | 24 | |
Wei-Yin Chen (陳威尹) | 0520349 | 2017-05-11 00:07:53 -0700 | [diff] [blame] | 25 | parser = argparse.ArgumentParser(description='''\ |
| 26 | Clone an existing gclient directory, taking care of all sub-repositories. |
| 27 | Works similarly to 'git new-workdir'.''') |
| 28 | parser.add_argument('repository', type=os.path.abspath, |
| 29 | help='should contain a .gclient file') |
| 30 | parser.add_argument('new_workdir', help='must not exist') |
Wei-Yin Chen (陳威尹) | 704be87 | 2017-05-11 00:58:26 -0700 | [diff] [blame] | 31 | parser.add_argument('--reflink', action='store_true', default=None, |
| 32 | help='''force to use "cp --reflink" for speed and disk |
| 33 | space. need supported FS like btrfs or ZFS.''') |
| 34 | parser.add_argument('--no-reflink', action='store_false', dest='reflink', |
| 35 | help='''force not to use "cp --reflink" even on supported |
| 36 | FS like btrfs or ZFS.''') |
Wei-Yin Chen (陳威尹) | 0520349 | 2017-05-11 00:07:53 -0700 | [diff] [blame] | 37 | args = parser.parse_args() |
pgervais@chromium.org | f13c205 | 2013-11-15 20:09:23 +0000 | [diff] [blame] | 38 | |
Wei-Yin Chen (陳威尹) | 0520349 | 2017-05-11 00:07:53 -0700 | [diff] [blame] | 39 | if not os.path.exists(args.repository): |
| 40 | parser.error('Repository "%s" does not exist.' % args.repository) |
adam.treat@samsung.com | 62d817c | 2013-11-05 15:18:13 +0000 | [diff] [blame] | 41 | |
Wei-Yin Chen (陳威尹) | 0520349 | 2017-05-11 00:07:53 -0700 | [diff] [blame] | 42 | gclient = os.path.join(args.repository, '.gclient') |
| 43 | if not os.path.exists(gclient): |
| 44 | parser.error('No .gclient file at "%s".' % gclient) |
adam.treat@samsung.com | 62d817c | 2013-11-05 15:18:13 +0000 | [diff] [blame] | 45 | |
Wei-Yin Chen (陳威尹) | 0520349 | 2017-05-11 00:07:53 -0700 | [diff] [blame] | 46 | if os.path.exists(args.new_workdir): |
| 47 | parser.error('New workdir "%s" already exists.' % args.new_workdir) |
adam.treat@samsung.com | 62d817c | 2013-11-05 15:18:13 +0000 | [diff] [blame] | 48 | |
Wei-Yin Chen (陳威尹) | 0520349 | 2017-05-11 00:07:53 -0700 | [diff] [blame] | 49 | return args |
adam.treat@samsung.com | 62d817c | 2013-11-05 15:18:13 +0000 | [diff] [blame] | 50 | |
| 51 | |
Wei-Yin Chen (陳威尹) | 704be87 | 2017-05-11 00:58:26 -0700 | [diff] [blame] | 52 | def support_cow(src, dest): |
| 53 | try: |
| 54 | subprocess.check_output(['cp', '-a', '--reflink', src, dest], |
| 55 | stderr=subprocess.STDOUT) |
| 56 | except subprocess.CalledProcessError: |
| 57 | return False |
| 58 | finally: |
| 59 | os.remove(dest) |
| 60 | return True |
| 61 | |
| 62 | |
pgervais@chromium.org | f13c205 | 2013-11-15 20:09:23 +0000 | [diff] [blame] | 63 | def main(): |
Wei-Yin Chen (陳威尹) | 0520349 | 2017-05-11 00:07:53 -0700 | [diff] [blame] | 64 | args = parse_options() |
adam.treat@samsung.com | 62d817c | 2013-11-05 15:18:13 +0000 | [diff] [blame] | 65 | |
Wei-Yin Chen (陳威尹) | 0520349 | 2017-05-11 00:07:53 -0700 | [diff] [blame] | 66 | gclient = os.path.join(args.repository, '.gclient') |
Wei-Yin Chen (陳威尹) | 704be87 | 2017-05-11 00:58:26 -0700 | [diff] [blame] | 67 | new_gclient = os.path.join(args.new_workdir, '.gclient') |
adam.treat@samsung.com | 62d817c | 2013-11-05 15:18:13 +0000 | [diff] [blame] | 68 | |
Wei-Yin Chen (陳威尹) | 0520349 | 2017-05-11 00:07:53 -0700 | [diff] [blame] | 69 | os.makedirs(args.new_workdir) |
Wei-Yin Chen (陳威尹) | 704be87 | 2017-05-11 00:58:26 -0700 | [diff] [blame] | 70 | if args.reflink is None: |
| 71 | args.reflink = support_cow(gclient, new_gclient) |
| 72 | if args.reflink: |
Wei-Yin Chen (陳威尹) | 56e4ad9 | 2017-05-23 01:05:38 -0700 | [diff] [blame^] | 73 | print('Copy-on-write support is detected.') |
Wei-Yin Chen (陳威尹) | 704be87 | 2017-05-11 00:58:26 -0700 | [diff] [blame] | 74 | os.symlink(gclient, new_gclient) |
adam.treat@samsung.com | 62d817c | 2013-11-05 15:18:13 +0000 | [diff] [blame] | 75 | |
Wei-Yin Chen (陳威尹) | 0520349 | 2017-05-11 00:07:53 -0700 | [diff] [blame] | 76 | for root, dirs, _ in os.walk(args.repository): |
pgervais@chromium.org | f13c205 | 2013-11-15 20:09:23 +0000 | [diff] [blame] | 77 | if '.git' in dirs: |
Wei-Yin Chen (陳威尹) | 0520349 | 2017-05-11 00:07:53 -0700 | [diff] [blame] | 78 | workdir = root.replace(args.repository, args.new_workdir, 1) |
sammc@chromium.org | 900a33f | 2015-09-29 06:57:09 +0000 | [diff] [blame] | 79 | print('Creating: %s' % workdir) |
Wei-Yin Chen (陳威尹) | 704be87 | 2017-05-11 00:58:26 -0700 | [diff] [blame] | 80 | |
| 81 | if args.reflink: |
| 82 | if not os.path.exists(workdir): |
| 83 | print('Copying: %s' % workdir) |
| 84 | subprocess.check_call(['cp', '-a', '--reflink', root, workdir]) |
| 85 | shutil.rmtree(os.path.join(workdir, '.git')) |
| 86 | |
sammc@chromium.org | 900a33f | 2015-09-29 06:57:09 +0000 | [diff] [blame] | 87 | git_common.make_workdir(os.path.join(root, '.git'), |
| 88 | os.path.join(workdir, '.git')) |
Wei-Yin Chen (陳威尹) | 704be87 | 2017-05-11 00:58:26 -0700 | [diff] [blame] | 89 | if args.reflink: |
| 90 | subprocess.check_call(['cp', '-a', '--reflink', |
| 91 | os.path.join(root, '.git', 'index'), |
| 92 | os.path.join(workdir, '.git', 'index')]) |
| 93 | else: |
| 94 | subprocess.check_call(['git', 'checkout', '-f'], cwd=workdir) |
| 95 | |
Wei-Yin Chen (陳威尹) | 56e4ad9 | 2017-05-23 01:05:38 -0700 | [diff] [blame^] | 96 | if args.reflink: |
| 97 | print(textwrap.dedent('''\ |
| 98 | The repo was copied with copy-on-write, and the artifacts were retained. |
| 99 | More details on http://crbug.com/721585. |
adam.treat@samsung.com | 62d817c | 2013-11-05 15:18:13 +0000 | [diff] [blame] | 100 | |
Wei-Yin Chen (陳威尹) | 56e4ad9 | 2017-05-23 01:05:38 -0700 | [diff] [blame^] | 101 | Depending on your usage pattern, you might want to do "gn gen" |
| 102 | on the output directories. More details: http://crbug.com/723856.''')) |
adam.treat@samsung.com | 62d817c | 2013-11-05 15:18:13 +0000 | [diff] [blame] | 103 | |
| 104 | if __name__ == '__main__': |
pgervais@chromium.org | f13c205 | 2013-11-15 20:09:23 +0000 | [diff] [blame] | 105 | sys.exit(main()) |