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

Side by Side Diff: checkout.py

Issue 2446013002: Continue to the next file after a conflict in apply_patch. (Closed)
Patch Set: address nit Created 4 years, 1 month 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
« 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 # coding=utf8 1 # coding=utf8
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 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 """Manages a project checkout. 5 """Manages a project checkout.
6 6
7 Includes support only for git. 7 Includes support only for git.
8 """ 8 """
9 9
10 import fnmatch 10 import fnmatch
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 for item in stdout: 70 for item in stdout:
71 item = item.strip() 71 item = item.strip()
72 if not item: 72 if not item:
73 continue 73 continue
74 output += ''.join(' %s\n' % line for line in item.splitlines()) 74 output += ''.join(' %s\n' % line for line in item.splitlines())
75 return output 75 return output
76 76
77 77
78 class PatchApplicationFailed(Exception): 78 class PatchApplicationFailed(Exception):
79 """Patch failed to be applied.""" 79 """Patch failed to be applied."""
80 def __init__(self, p, status): 80 def __init__(self, errors, verbose):
81 super(PatchApplicationFailed, self).__init__(p, status) 81 super(PatchApplicationFailed, self).__init__(errors, verbose)
82 self.patch = p 82 self.errors = errors
83 self.status = status 83 self.verbose = verbose
84
85 @property
86 def filename(self):
87 if self.patch:
88 return self.patch.filename
89 84
90 def __str__(self): 85 def __str__(self):
91 out = [] 86 out = []
92 if self.filename: 87 for e in self.errors:
93 out.append('Failed to apply patch for %s:' % self.filename) 88 p, status = e
94 if self.status: 89 if p and p.filename:
95 out.append(self.status) 90 out.append('Failed to apply patch for %s:' % p.filename)
96 if self.patch: 91 if status:
97 out.append('Patch: %s' % self.patch.dump()) 92 out.append(status)
93 if p and self.verbose:
94 out.append('Patch: %s' % p.dump())
98 return '\n'.join(out) 95 return '\n'.join(out)
99 96
100 97
101 class CheckoutBase(object): 98 class CheckoutBase(object):
102 # Set to None to have verbose output. 99 # Set to None to have verbose output.
103 VOID = subprocess2.VOID 100 VOID = subprocess2.VOID
104 101
105 def __init__(self, root_dir, project_name, post_processors): 102 def __init__(self, root_dir, project_name, post_processors):
106 """ 103 """
107 Args: 104 Args:
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 The changes remain staged on the current branch. 241 The changes remain staged on the current branch.
245 """ 242 """
246 post_processors = post_processors or self.post_processors or [] 243 post_processors = post_processors or self.post_processors or []
247 # It this throws, the checkout is corrupted. Maybe worth deleting it and 244 # It this throws, the checkout is corrupted. Maybe worth deleting it and
248 # trying again? 245 # trying again?
249 if self.remote_branch: 246 if self.remote_branch:
250 self._check_call_git( 247 self._check_call_git(
251 ['checkout', '-b', self.working_branch, '-t', self.remote_branch, 248 ['checkout', '-b', self.working_branch, '-t', self.remote_branch,
252 '--quiet']) 249 '--quiet'])
253 250
251 errors = []
254 for index, p in enumerate(patches): 252 for index, p in enumerate(patches):
255 stdout = [] 253 stdout = []
256 try: 254 try:
257 filepath = os.path.join(self.project_path, p.filename) 255 filepath = os.path.join(self.project_path, p.filename)
258 if p.is_delete: 256 if p.is_delete:
259 if (not os.path.exists(filepath) and 257 if (not os.path.exists(filepath) and
260 any(p1.source_filename == p.filename for p1 in patches[0:index])): 258 any(p1.source_filename == p.filename for p1 in patches[0:index])):
261 # The file was already deleted if a prior patch with file rename 259 # The file was already deleted if a prior patch with file rename
262 # was already processed because 'git apply' did it for us. 260 # was already processed because 'git apply' did it for us.
263 pass 261 pass
(...skipping 22 matching lines...) Expand all
286 cmd = ['apply', '--index', '-3', '-p%s' % p.patchlevel] 284 cmd = ['apply', '--index', '-3', '-p%s' % p.patchlevel]
287 if verbose: 285 if verbose:
288 cmd.append('--verbose') 286 cmd.append('--verbose')
289 stdout.append(self._check_output_git(cmd, stdin=p.get(True))) 287 stdout.append(self._check_output_git(cmd, stdin=p.get(True)))
290 for post in post_processors: 288 for post in post_processors:
291 post(self, p) 289 post(self, p)
292 if verbose: 290 if verbose:
293 print p.filename 291 print p.filename
294 print align_stdout(stdout) 292 print align_stdout(stdout)
295 except OSError, e: 293 except OSError, e:
296 raise PatchApplicationFailed(p, '%s%s' % (align_stdout(stdout), e)) 294 errors.append((p, '%s%s' % (align_stdout(stdout), e)))
297 except subprocess.CalledProcessError, e: 295 except subprocess.CalledProcessError, e:
298 raise PatchApplicationFailed( 296 errors.append((p,
299 p,
300 'While running %s;\n%s%s' % ( 297 'While running %s;\n%s%s' % (
301 ' '.join(e.cmd), 298 ' '.join(e.cmd),
302 align_stdout(stdout), 299 align_stdout(stdout),
303 align_stdout([getattr(e, 'stdout', '')]))) 300 align_stdout([getattr(e, 'stdout', '')]))))
301 if errors:
302 raise PatchApplicationFailed(errors, verbose)
304 found_files = self._check_output_git( 303 found_files = self._check_output_git(
305 ['diff', '--ignore-submodules', 304 ['diff', '--ignore-submodules',
306 '--name-only', '--staged']).splitlines(False) 305 '--name-only', '--staged']).splitlines(False)
307 if sorted(patches.filenames) != sorted(found_files): 306 if sorted(patches.filenames) != sorted(found_files):
308 extra_files = sorted(set(found_files) - set(patches.filenames)) 307 extra_files = sorted(set(found_files) - set(patches.filenames))
309 unpatched_files = sorted(set(patches.filenames) - set(found_files)) 308 unpatched_files = sorted(set(patches.filenames) - set(found_files))
310 if extra_files: 309 if extra_files:
311 print 'Found extra files: %r' % (extra_files,) 310 print 'Found extra files: %r' % (extra_files,)
312 if unpatched_files: 311 if unpatched_files:
313 print 'Found unpatched files: %r' % (unpatched_files,) 312 print 'Found unpatched files: %r' % (unpatched_files,)
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 def revisions(self, rev1, rev2): 422 def revisions(self, rev1, rev2):
424 return self.checkout.revisions(rev1, rev2) 423 return self.checkout.revisions(rev1, rev2)
425 424
426 @property 425 @property
427 def project_name(self): 426 def project_name(self):
428 return self.checkout.project_name 427 return self.checkout.project_name
429 428
430 @property 429 @property
431 def project_path(self): 430 def project_path(self):
432 return self.checkout.project_path 431 return self.checkout.project_path
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