Chromium Code Reviews| Index: git-try |
| =================================================================== |
| --- git-try (revision 26769) |
| +++ git-try (working copy) |
| @@ -15,9 +15,9 @@ |
| import trychange |
| -def Backquote(cmd): |
| +def Backquote(cmd, cwd=None): |
| """Like running `cmd` in a shell script.""" |
| - return subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0].strip() |
| + return subprocess.Popen(cmd, cwd=cwd, stdout=subprocess.PIPE).communicate()[0].strip() |
|
M-A Ruel
2009/09/22 01:26:23
80 cols
|
| def GetTryServerConfig(): |
| @@ -37,18 +37,18 @@ |
| return locals |
| -def GetBranchName(): |
| +def GetBranchName(working_dir=None): |
| """Return name of current git branch.""" |
| - branch = Backquote(['git', 'symbolic-ref', 'HEAD']) |
| + branch = Backquote(['git', 'symbolic-ref', 'HEAD'], working_dir) |
| if not branch.startswith('refs/heads/'): |
| raise "Couldn't figure out branch name" |
| branch = branch[len('refs/heads/'):] |
| return branch |
| -def GetPatchName(): |
| +def GetPatchName(working_dir=None): |
| """Construct a name for this patch.""" |
| - short_sha = Backquote(['git', 'rev-parse', '--short=4', 'HEAD']) |
| + short_sha = Backquote(['git', 'rev-parse', '--short=4', 'HEAD'], working_dir) |
| return GetBranchName() + '-' + short_sha |
| @@ -61,35 +61,83 @@ |
| return Backquote(['git', 'config', |
| 'branch.%s.rietveldpatchset' % GetBranchName()]) |
| +def GetSubRepWorkingDir(sub_rep_path): |
| + """Computes the path to the sub repository""" |
| + if sub_rep_path: |
| + root_dir = os.path.abspath(Backquote(['git', 'rev-parse', '--show-cdup'])) |
| + return os.path.join(root_dir, sub_rep_path) |
| + return None |
| -def GetMungedDiff(branch, prefix='src/'): |
| - """Get the diff we'll send to the try server. We munge paths to match svn.""" |
| +def GetMungedDiff(branch, prefix, sub_rep_path): |
| + """Get the diff we'll send to the try server. We munge paths to match svn. |
| + We add the prefix that the try bot is expecting. If sub_rep_path is |
| + provided, diff will be calculated in the sub repository.""" |
| # Make the following changes: |
| # - Prepend "src/" (or some other prefix) to paths as svn is expecting |
| # - In the case of added files, replace /dev/null with the path to the file |
| # being added. |
| + |
| + cwd = GetSubRepWorkingDir(sub_rep_path) |
| + |
| output = [] |
| if not branch: |
| # Try to guess the upstream branch. |
| - branch = Backquote(['git', 'cl', 'upstream']) |
| - diff = subprocess.Popen(['git', 'diff-tree', '-p', '--no-prefix', |
| - branch, 'HEAD'], |
| - stdout=subprocess.PIPE).stdout.readlines() |
| + branch = Backquote(['git', 'cl', 'upstream'], cwd) |
| + command = ['git', 'diff-tree', '-p'] |
| + |
| + new_cwd = None |
| + if not sub_rep_path: |
| + command.extend(['--no-prefix']) |
| + else: |
| + # Append / |
| + sub_rep_path = os.path.join(sub_rep_path, '') |
| + # Add the right prefix |
| + command.extend(['--src-prefix=' + sub_rep_path]) |
| + command.extend(['--dst-prefix=' + sub_rep_path]) |
| + |
| + command.extend([branch, 'HEAD']) |
| + |
| + # Run diff tree |
| + diff = subprocess.Popen(command, |
| + stdout=subprocess.PIPE, |
| + cwd=cwd).stdout.readlines() |
| + # Replace --- /dev/null with --- <new file name> |
| for i in range(len(diff)): |
| line = diff[i] |
| if line.startswith('--- /dev/null'): |
| - line = '--- %s' % prefix + diff[i+1][4:] |
| - elif line.startswith('--- ') or line.startswith('+++ '): |
| - line = line[0:4] + prefix + line[4:] |
| + line = '--- %s' % diff[i+1][4:] |
| output.append(line) |
| + diff = output |
| + # Add root prefix |
| + output = [] |
| + for i in range(len(diff)): |
|
M-A Ruel
2009/09/22 01:26:23
for line in diff:
|
| + line = diff[i] |
| + if line.startswith('--- ') or line.startswith('+++ '): |
| + line = line[0:4] + os.path.join(prefix,line[4:]) |
| + output.append(line) |
| + |
| munged_diff = ''.join(output) |
| if len(munged_diff.strip()) == 0: |
| raise Exception("Patch was empty, did you give the right remote branch?") |
| return munged_diff |
| +def OneRepositoryDiff(diff_file, patch_names, branch, prefix, sub_rep_path): |
| + """Computes a diff for one git repository at a given path against a given |
| + branch. Writes the diff into diff_file and appends a name to the |
| + patch_names list.""" |
| + |
| + diff = GetMungedDiff(branch, prefix, sub_rep_path) |
| + # Write the diff out |
| + diff_file.write(diff) |
| + |
| + # Add patch name to list of patches |
| + patch_name = GetPatchName(GetSubRepWorkingDir(sub_rep_path)) |
| + patch_names.extend([patch_name]) |
| + |
| + |
| def ValidEmail(email): |
| return re.match(r"^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", email) |
| @@ -119,34 +167,64 @@ |
| help="Make the try run use be a clobber build") |
| parser.add_option("-r", "--revision", |
| help="Specify the SVN base revision to use") |
| + parser.add_option("--root", default="src", metavar="PATH", |
| + help="Specify the root prefix that is appended to paths " |
| + "in the patch") |
| + parser.add_option("--dry_run", action="store_true", |
| + help="Print the diff but don't send it to the try bots") |
| + parser.add_option("--sub_rep", nargs=2, action="append", default=[], |
| + metavar="PATH BRANCH", |
| + help="Specify a path to a git sub-repository and a branch " |
| + "to diff with in order to simultanously try changes " |
| + "in multiple git repositories. Option may be " |
| + "specified multiple times.") |
| + parser.add_option("--webkit", metavar="BRANCH", |
| + help="Specify webkit branch. Syntactic sugar for " |
| + "--sub_rep third_party/WebKit/ <branch>") |
| + |
| (options, args) = parser.parse_args(sys.argv) |
| + if options.webkit: |
| + options.sub_rep = ('third_party/WebKit/', options.webkit) |
| + |
| branch = None |
| if len(args) > 1: |
| branch = args[1] |
| + patch_names = [] |
| - patch_name = GetPatchName() |
| - diff = GetMungedDiff(branch) |
| - |
| - # Write the diff out to a temporary file |
| + # Dump all diffs into one diff file. |
| diff_file = tempfile.NamedTemporaryFile() |
| - diff_file.write(diff) |
| + |
| + # Calculate diff for main git repository. |
| + OneRepositoryDiff(diff_file, patch_names, branch, options.root, None) |
| + |
| + # Calculate diff for each extra git repository. |
| + if options.sub_rep: |
|
M-A Ruel
2009/09/22 01:26:23
The condition is unnecessary.
|
| + for path_and_branch in options.sub_rep: |
| + OneRepositoryDiff(diff_file, |
| + patch_names, |
| + path_and_branch[1], |
| + options.root, |
| + path_and_branch[0]) |
| + # Make diff file ready for reading. |
| diff_file.flush() |
| + # Concatenate patch names |
| + # Prepare args for TryChange |
| email = GetEmail() |
| user = email.partition('@')[0] |
| args = [ |
| '-u', user, |
| '-e', email, |
| - '-n', patch_name, |
| - '--diff', diff_file.name, |
| + '-n', '-'.join(patch_names), |
| + '--diff', diff_file.name, |
| ] |
| # Send to try server via HTTP if we can parse the config, otherwise |
| # upload via SVN. |
| config = GetTryServerConfig() |
| if config is not None: |
| - sendmsg = "Sending %s using HTTP..." % patch_name |
| + sendmsg = "Sending %s using HTTP..." % '-'.join(patch_names) |
| args.extend(['--use_http']) |
| if config['try_server_http_host'] is not None: |
| args.extend(['--host', config['try_server_http_host']]) |
| @@ -174,5 +252,9 @@ |
| '--patchset', GetRietveldPatchsetNumber(), |
| ]) |
| + if options.dry_run: |
| + print open(diff_file.name, 'r').read() |
| + exit(0) |
| + |
| print sendmsg |
| TryChange(args=args) |