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) |