| OLD | NEW |
| 1 # coding=utf8 | 1 # coding=utf8 |
| 2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2010 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 for svn, git-svn and git. | 7 Includes support for svn, git-svn and git. |
| 8 """ | 8 """ |
| 9 | 9 |
| 10 import logging | 10 import logging |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 if self.working_branch in branches: | 258 if self.working_branch in branches: |
| 259 self._call_git(['branch', '-D', self.working_branch]) | 259 self._call_git(['branch', '-D', self.working_branch]) |
| 260 | 260 |
| 261 def apply_patch(self, patch_data): | 261 def apply_patch(self, patch_data): |
| 262 """Applies a patch on 'working_branch'.""" | 262 """Applies a patch on 'working_branch'.""" |
| 263 try: | 263 try: |
| 264 self._check_call_git( | 264 self._check_call_git( |
| 265 ['checkout', '-b', self.working_branch, | 265 ['checkout', '-b', self.working_branch, |
| 266 '%s/%s' % (self.remote, self.remote_branch)]) | 266 '%s/%s' % (self.remote, self.remote_branch)]) |
| 267 self._check_call_git(['apply', '--index', '-p0'], stdin=patch_data) | 267 self._check_call_git(['apply', '--index', '-p0'], stdin=patch_data) |
| 268 self._check_call_git(['commit', '-m', 'Committed patch']) | 268 cmd = ['commit', '-m', 'Committed patch', '--quiet'] |
| 269 self._check_call_git(cmd) |
| 270 commit_user = getattr(self, 'commit_user', None) |
| 271 if commit_user: |
| 272 try: |
| 273 # Try to patch the author with commit_user since it may differ. |
| 274 self._check_call_git(cmd + ['--author=%s' % commit_user]) |
| 275 except subprocess.CalledProcessError, e: |
| 276 if e.returncode != 128: |
| 277 raise |
| 269 return self._check_capture_git(['diff', 'master', | 278 return self._check_capture_git(['diff', 'master', |
| 270 '--name-only']).splitlines(False) | 279 '--name-only']).splitlines(False) |
| 271 except subprocess.CalledProcessError, e: | 280 except subprocess.CalledProcessError, e: |
| 272 if e.returncode == 1: | 281 if e.returncode == 1: |
| 273 return False | 282 return False |
| 274 raise | 283 raise |
| 275 | 284 |
| 276 def commit(self, commit_message, user): | 285 def commit(self, commit_message, user): |
| 277 """Updates the commit message. | 286 """Updates the commit message and user if possible. |
| 278 | 287 |
| 279 Subclass needs to dcommit or push.""" | 288 Subclass needs to dcommit or push. |
| 280 self._check_call_git(['commit', '--amend', '-m', commit_message]) | 289 """ |
| 290 # Do it in two calls to ease exception management. |
| 291 cmd = ['commit', '--amend', '-m', commit_message, '--quiet'] |
| 292 self._check_call_git(cmd) |
| 293 try: |
| 294 # git-svn will allow faking the author only if the user already exists in |
| 295 # the logs. |
| 296 # Provide -m again otherwise git will start a text editor. |
| 297 self._check_call_git(cmd + ['--author=%s' % user]) |
| 298 except subprocess.CalledProcessError, e: |
| 299 if e.returncode != 128: |
| 300 raise |
| 281 | 301 |
| 282 def _check_call_git(self, args, **kwargs): | 302 def _check_call_git(self, args, **kwargs): |
| 283 kwargs.setdefault('cwd', self.project_path) | 303 kwargs.setdefault('cwd', self.project_path) |
| 284 return subprocess2.check_call(['git'] + args, **kwargs) | 304 return subprocess2.check_call(['git'] + args, **kwargs) |
| 285 | 305 |
| 286 def _call_git(self, args, **kwargs): | 306 def _call_git(self, args, **kwargs): |
| 287 """Like check_call but doesn't throw on failure.""" | 307 """Like check_call but doesn't throw on failure.""" |
| 288 kwargs.setdefault('cwd', self.project_path) | 308 kwargs.setdefault('cwd', self.project_path) |
| 289 return subprocess2.call(['git'] + args, **kwargs) | 309 return subprocess2.call(['git'] + args, **kwargs) |
| 290 | 310 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 return int(self._git_svn_info('revision')) | 362 return int(self._git_svn_info('revision')) |
| 343 | 363 |
| 344 def _git_svn_info(self, key): | 364 def _git_svn_info(self, key): |
| 345 """Calls git svn info. This doesn't support nor need --config-dir.""" | 365 """Calls git svn info. This doesn't support nor need --config-dir.""" |
| 346 return self._parse_svn_info( | 366 return self._parse_svn_info( |
| 347 self._check_capture_git(['svn', 'info']), key) | 367 self._check_capture_git(['svn', 'info']), key) |
| 348 | 368 |
| 349 def commit(self, commit_message, user): | 369 def commit(self, commit_message, user): |
| 350 """Commits a patch.""" | 370 """Commits a patch.""" |
| 351 logging.info('Committing patch for %s' % user) | 371 logging.info('Committing patch for %s' % user) |
| 352 # Fix the commit message. | 372 # Fix the commit message and author. |
| 353 super(GitSvnCheckoutBase, self).commit(commit_message, user) | 373 super(GitSvnCheckoutBase, self).commit(commit_message, user) |
| 354 # Commit with git svn dcommit, then use svn directly to update the | 374 # Commit with git svn dcommit, then use svn directly to update the |
| 355 # committer on the revision. | 375 # committer on the revision. |
| 356 self._check_call_git_svn(['dcommit', '--rmdir', '--find-copies-harder']) | 376 self._check_call_git_svn(['dcommit', '--rmdir', '--find-copies-harder']) |
| 357 revision = int(self._git_svn_info('revision')) | 377 revision = int(self._git_svn_info('revision')) |
| 358 # Fix the committer. | 378 # Fix the committer. |
| 359 self._update_committer(revision, user) | 379 self._update_committer(revision, user) |
| 360 return revision | 380 return revision |
| 361 | 381 |
| 362 def _cache_svn_auth(self): | 382 def _cache_svn_auth(self): |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 user, message)) | 481 user, message)) |
| 462 return 'FAKE' | 482 return 'FAKE' |
| 463 | 483 |
| 464 @property | 484 @property |
| 465 def project_name(self): | 485 def project_name(self): |
| 466 return self.checkout.project_name | 486 return self.checkout.project_name |
| 467 | 487 |
| 468 @property | 488 @property |
| 469 def project_path(self): | 489 def project_path(self): |
| 470 return self.checkout.project_path | 490 return self.checkout.project_path |
| OLD | NEW |