Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(114)

Side by Side Diff: git-try

Issue 212034: I made git-try also find diffs in one extra gip sub-repository... (Closed) Base URL: svn://chrome-svn/chrome/trunk/tools/depot_tools/
Patch Set: '' Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2009 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2009 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 import getpass 6 import getpass
7 import optparse 7 import optparse
8 import os 8 import os
9 import subprocess 9 import subprocess
10 import tempfile 10 import tempfile
11 import traceback 11 import traceback
12 import urllib 12 import urllib
13 import sys 13 import sys
14 import re 14 import re
15 import trychange 15 import trychange
16 16
17 17
18 def Backquote(cmd): 18 def Backquote(cmd, cwd=None):
19 """Like running `cmd` in a shell script.""" 19 """Like running `cmd` in a shell script."""
20 return subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0].strip() 20 return subprocess.Popen(cmd, cwd=cwd, stdout=subprocess.PIPE).communicate()[0] .strip()
M-A Ruel 2009/09/22 01:26:23 80 cols
21 21
22 22
23 def GetTryServerConfig(): 23 def GetTryServerConfig():
24 """Returns the dictionary of try server options or None if they 24 """Returns the dictionary of try server options or None if they
25 cannot be found.""" 25 cannot be found."""
26 script_path = 'tools/tryserver/tryserver.py' 26 script_path = 'tools/tryserver/tryserver.py'
27 root_dir = Backquote(['git', 'rev-parse', '--show-cdup']) 27 root_dir = Backquote(['git', 'rev-parse', '--show-cdup'])
28 try: 28 try:
29 script_file = open(os.path.join(root_dir, script_path)) 29 script_file = open(os.path.join(root_dir, script_path))
30 except IOError: 30 except IOError:
31 return None 31 return None
32 locals = {} 32 locals = {}
33 try: 33 try:
34 exec(script_file, locals) 34 exec(script_file, locals)
35 except Exception, e: 35 except Exception, e:
36 return None 36 return None
37 return locals 37 return locals
38 38
39 39
40 def GetBranchName(): 40 def GetBranchName(working_dir=None):
41 """Return name of current git branch.""" 41 """Return name of current git branch."""
42 branch = Backquote(['git', 'symbolic-ref', 'HEAD']) 42 branch = Backquote(['git', 'symbolic-ref', 'HEAD'], working_dir)
43 if not branch.startswith('refs/heads/'): 43 if not branch.startswith('refs/heads/'):
44 raise "Couldn't figure out branch name" 44 raise "Couldn't figure out branch name"
45 branch = branch[len('refs/heads/'):] 45 branch = branch[len('refs/heads/'):]
46 return branch 46 return branch
47 47
48 48
49 def GetPatchName(): 49 def GetPatchName(working_dir=None):
50 """Construct a name for this patch.""" 50 """Construct a name for this patch."""
51 short_sha = Backquote(['git', 'rev-parse', '--short=4', 'HEAD']) 51 short_sha = Backquote(['git', 'rev-parse', '--short=4', 'HEAD'], working_dir)
52 return GetBranchName() + '-' + short_sha 52 return GetBranchName() + '-' + short_sha
53 53
54 54
55 def GetRietveldIssueNumber(): 55 def GetRietveldIssueNumber():
56 return Backquote(['git', 'config', 56 return Backquote(['git', 'config',
57 'branch.%s.rietveldissue' % GetBranchName()]) 57 'branch.%s.rietveldissue' % GetBranchName()])
58 58
59 59
60 def GetRietveldPatchsetNumber(): 60 def GetRietveldPatchsetNumber():
61 return Backquote(['git', 'config', 61 return Backquote(['git', 'config',
62 'branch.%s.rietveldpatchset' % GetBranchName()]) 62 'branch.%s.rietveldpatchset' % GetBranchName()])
63 63
64 def GetSubRepWorkingDir(sub_rep_path):
65 """Computes the path to the sub repository"""
66 if sub_rep_path:
67 root_dir = os.path.abspath(Backquote(['git', 'rev-parse', '--show-cdup']))
68 return os.path.join(root_dir, sub_rep_path)
69 return None
64 70
65 def GetMungedDiff(branch, prefix='src/'): 71 def GetMungedDiff(branch, prefix, sub_rep_path):
66 """Get the diff we'll send to the try server. We munge paths to match svn.""" 72 """Get the diff we'll send to the try server. We munge paths to match svn.
73 We add the prefix that the try bot is expecting. If sub_rep_path is
74 provided, diff will be calculated in the sub repository."""
67 # Make the following changes: 75 # Make the following changes:
68 # - Prepend "src/" (or some other prefix) to paths as svn is expecting 76 # - Prepend "src/" (or some other prefix) to paths as svn is expecting
69 # - In the case of added files, replace /dev/null with the path to the file 77 # - In the case of added files, replace /dev/null with the path to the file
70 # being added. 78 # being added.
79
80 cwd = GetSubRepWorkingDir(sub_rep_path)
81
71 output = [] 82 output = []
72 if not branch: 83 if not branch:
73 # Try to guess the upstream branch. 84 # Try to guess the upstream branch.
74 branch = Backquote(['git', 'cl', 'upstream']) 85 branch = Backquote(['git', 'cl', 'upstream'], cwd)
75 diff = subprocess.Popen(['git', 'diff-tree', '-p', '--no-prefix', 86 command = ['git', 'diff-tree', '-p']
76 branch, 'HEAD'], 87
77 stdout=subprocess.PIPE).stdout.readlines() 88 new_cwd = None
89 if not sub_rep_path:
90 command.extend(['--no-prefix'])
91 else:
92 # Append /
93 sub_rep_path = os.path.join(sub_rep_path, '')
94 # Add the right prefix
95 command.extend(['--src-prefix=' + sub_rep_path])
96 command.extend(['--dst-prefix=' + sub_rep_path])
97
98 command.extend([branch, 'HEAD'])
99
100 # Run diff tree
101 diff = subprocess.Popen(command,
102 stdout=subprocess.PIPE,
103 cwd=cwd).stdout.readlines()
104 # Replace --- /dev/null with --- <new file name>
78 for i in range(len(diff)): 105 for i in range(len(diff)):
79 line = diff[i] 106 line = diff[i]
80 if line.startswith('--- /dev/null'): 107 if line.startswith('--- /dev/null'):
81 line = '--- %s' % prefix + diff[i+1][4:] 108 line = '--- %s' % diff[i+1][4:]
82 elif line.startswith('--- ') or line.startswith('+++ '): 109 output.append(line)
83 line = line[0:4] + prefix + line[4:] 110 diff = output
111
112 # Add root prefix
113 output = []
114 for i in range(len(diff)):
M-A Ruel 2009/09/22 01:26:23 for line in diff:
115 line = diff[i]
116 if line.startswith('--- ') or line.startswith('+++ '):
117 line = line[0:4] + os.path.join(prefix,line[4:])
84 output.append(line) 118 output.append(line)
85 119
86 munged_diff = ''.join(output) 120 munged_diff = ''.join(output)
87 if len(munged_diff.strip()) == 0: 121 if len(munged_diff.strip()) == 0:
88 raise Exception("Patch was empty, did you give the right remote branch?") 122 raise Exception("Patch was empty, did you give the right remote branch?")
89 123
90 return munged_diff 124 return munged_diff
91 125
126 def OneRepositoryDiff(diff_file, patch_names, branch, prefix, sub_rep_path):
127 """Computes a diff for one git repository at a given path against a given
128 branch. Writes the diff into diff_file and appends a name to the
129 patch_names list."""
130
131 diff = GetMungedDiff(branch, prefix, sub_rep_path)
132
133 # Write the diff out
134 diff_file.write(diff)
135
136 # Add patch name to list of patches
137 patch_name = GetPatchName(GetSubRepWorkingDir(sub_rep_path))
138 patch_names.extend([patch_name])
139
92 140
93 def ValidEmail(email): 141 def ValidEmail(email):
94 return re.match(r"^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", email) 142 return re.match(r"^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", email)
95 143
96 144
97 def GetEmail(): 145 def GetEmail():
98 email = Backquote(['git', 'config', 'user.email']) 146 email = Backquote(['git', 'config', 'user.email'])
99 runmsg = "Try: git config user.email <EMAIL>" 147 runmsg = "Try: git config user.email <EMAIL>"
100 assert ValidEmail(email), "Email '%s' is not valid. %s" % (email, runmsg) 148 assert ValidEmail(email), "Email '%s' is not valid. %s" % (email, runmsg)
101 return email 149 return email
(...skipping 10 matching lines...) Expand all
112 parser = optparse.OptionParser( 160 parser = optparse.OptionParser(
113 usage='git try [options] [branch]', 161 usage='git try [options] [branch]',
114 description='Upload the current diff of branch...HEAD to the try server.') 162 description='Upload the current diff of branch...HEAD to the try server.')
115 parser.add_option("-b", "--bot", 163 parser.add_option("-b", "--bot",
116 help="Force the use of a specific build slave (eg mac, " 164 help="Force the use of a specific build slave (eg mac, "
117 "win, or linux)") 165 "win, or linux)")
118 parser.add_option("-c", "--clobber", action="store_true", 166 parser.add_option("-c", "--clobber", action="store_true",
119 help="Make the try run use be a clobber build") 167 help="Make the try run use be a clobber build")
120 parser.add_option("-r", "--revision", 168 parser.add_option("-r", "--revision",
121 help="Specify the SVN base revision to use") 169 help="Specify the SVN base revision to use")
170 parser.add_option("--root", default="src", metavar="PATH",
171 help="Specify the root prefix that is appended to paths "
172 "in the patch")
173 parser.add_option("--dry_run", action="store_true",
174 help="Print the diff but don't send it to the try bots")
175 parser.add_option("--sub_rep", nargs=2, action="append", default=[],
176 metavar="PATH BRANCH",
177 help="Specify a path to a git sub-repository and a branch "
178 "to diff with in order to simultanously try changes "
179 "in multiple git repositories. Option may be "
180 "specified multiple times.")
181 parser.add_option("--webkit", metavar="BRANCH",
182 help="Specify webkit branch. Syntactic sugar for "
183 "--sub_rep third_party/WebKit/ <branch>")
184
122 (options, args) = parser.parse_args(sys.argv) 185 (options, args) = parser.parse_args(sys.argv)
123 186
187 if options.webkit:
188 options.sub_rep = ('third_party/WebKit/', options.webkit)
189
124 branch = None 190 branch = None
125 if len(args) > 1: 191 if len(args) > 1:
126 branch = args[1] 192 branch = args[1]
193 patch_names = []
127 194
128 patch_name = GetPatchName() 195 # Dump all diffs into one diff file.
129 diff = GetMungedDiff(branch)
130
131 # Write the diff out to a temporary file
132 diff_file = tempfile.NamedTemporaryFile() 196 diff_file = tempfile.NamedTemporaryFile()
133 diff_file.write(diff) 197
198 # Calculate diff for main git repository.
199 OneRepositoryDiff(diff_file, patch_names, branch, options.root, None)
200
201 # Calculate diff for each extra git repository.
202 if options.sub_rep:
M-A Ruel 2009/09/22 01:26:23 The condition is unnecessary.
203 for path_and_branch in options.sub_rep:
204 OneRepositoryDiff(diff_file,
205 patch_names,
206 path_and_branch[1],
207 options.root,
208 path_and_branch[0])
209 # Make diff file ready for reading.
134 diff_file.flush() 210 diff_file.flush()
135 211
212 # Concatenate patch names
213 # Prepare args for TryChange
136 email = GetEmail() 214 email = GetEmail()
137 user = email.partition('@')[0] 215 user = email.partition('@')[0]
138 args = [ 216 args = [
139 '-u', user, 217 '-u', user,
140 '-e', email, 218 '-e', email,
141 '-n', patch_name, 219 '-n', '-'.join(patch_names),
142 '--diff', diff_file.name, 220 '--diff', diff_file.name,
143 ] 221 ]
144 222
145 # Send to try server via HTTP if we can parse the config, otherwise 223 # Send to try server via HTTP if we can parse the config, otherwise
146 # upload via SVN. 224 # upload via SVN.
147 config = GetTryServerConfig() 225 config = GetTryServerConfig()
148 if config is not None: 226 if config is not None:
149 sendmsg = "Sending %s using HTTP..." % patch_name 227 sendmsg = "Sending %s using HTTP..." % '-'.join(patch_names)
150 args.extend(['--use_http']) 228 args.extend(['--use_http'])
151 if config['try_server_http_host'] is not None: 229 if config['try_server_http_host'] is not None:
152 args.extend(['--host', config['try_server_http_host']]) 230 args.extend(['--host', config['try_server_http_host']])
153 if config['try_server_http_port'] is not None: 231 if config['try_server_http_port'] is not None:
154 args.extend(['--port', config['try_server_http_port']]) 232 args.extend(['--port', config['try_server_http_port']])
155 233
156 else: 234 else:
157 print "Could not get server config -- if you're within Google, " 235 print "Could not get server config -- if you're within Google, "
158 print "do you have have src-internal checked out?" 236 print "do you have have src-internal checked out?"
159 sendmsg = "Sending %s using SVN..." % patch_name 237 sendmsg = "Sending %s using SVN..." % patch_name
160 args.extend([ 238 args.extend([
161 '--use_svn', '--svn_repo', 239 '--use_svn', '--svn_repo',
162 'svn://svn.chromium.org/chrome-try/try', 240 'svn://svn.chromium.org/chrome-try/try',
163 ]) 241 ])
164 242
165 if options.bot: 243 if options.bot:
166 args.extend(['--bot', options.bot]) 244 args.extend(['--bot', options.bot])
167 if options.clobber: 245 if options.clobber:
168 args.append('--clobber') 246 args.append('--clobber')
169 if options.revision: 247 if options.revision:
170 args.extend(['-r', options.revision]) 248 args.extend(['-r', options.revision])
171 if GetRietveldPatchsetNumber(): 249 if GetRietveldPatchsetNumber():
172 args.extend([ 250 args.extend([
173 '--issue', GetRietveldIssueNumber(), 251 '--issue', GetRietveldIssueNumber(),
174 '--patchset', GetRietveldPatchsetNumber(), 252 '--patchset', GetRietveldPatchsetNumber(),
175 ]) 253 ])
176 254
255 if options.dry_run:
256 print open(diff_file.name, 'r').read()
257 exit(0)
258
177 print sendmsg 259 print sendmsg
178 TryChange(args=args) 260 TryChange(args=args)
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698