| OLD | NEW |
| 1 # Copyright (c) 2009, 2010, 2011 Google Inc. All rights reserved. | 1 # Copyright (c) 2009, 2010, 2011 Google Inc. All rights reserved. |
| 2 # Copyright (c) 2009 Apple Inc. All rights reserved. | 2 # Copyright (c) 2009 Apple Inc. All rights reserved. |
| 3 # | 3 # |
| 4 # Redistribution and use in source and binary forms, with or without | 4 # Redistribution and use in source and binary forms, with or without |
| 5 # modification, are permitted provided that the following conditions are | 5 # modification, are permitted provided that the following conditions are |
| 6 # met: | 6 # met: |
| 7 # | 7 # |
| 8 # * Redistributions of source code must retain the above copyright | 8 # * Redistributions of source code must retain the above copyright |
| 9 # notice, this list of conditions and the following disclaimer. | 9 # notice, this list of conditions and the following disclaimer. |
| 10 # * Redistributions in binary form must reproduce the above | 10 # * Redistributions in binary form must reproduce the above |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 | 29 |
| 30 import datetime | 30 import datetime |
| 31 import logging | 31 import logging |
| 32 import re | 32 import re |
| 33 | 33 |
| 34 import webkitpy.common.config | |
| 35 from webkitpy.common.checkout.scm.scm import SCM | 34 from webkitpy.common.checkout.scm.scm import SCM |
| 36 from webkitpy.common.memoized import memoized | 35 from webkitpy.common.memoized import memoized |
| 37 from webkitpy.common.system.executive import Executive, ScriptError | 36 from webkitpy.common.system.executive import Executive, ScriptError |
| 38 | 37 |
| 39 _log = logging.getLogger(__name__) | 38 _log = logging.getLogger(__name__) |
| 40 | 39 |
| 41 | 40 |
| 42 class AmbiguousCommitError(Exception): | 41 class AmbiguousCommitError(Exception): |
| 43 | 42 |
| 44 def __init__(self, num_local_commits, has_working_directory_changes): | 43 def __init__(self, num_local_commits, has_working_directory_changes): |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 | 195 |
| 197 def display_name(self): | 196 def display_name(self): |
| 198 return "git" | 197 return "git" |
| 199 | 198 |
| 200 def most_recent_log_matching(self, grep_str, path): | 199 def most_recent_log_matching(self, grep_str, path): |
| 201 # We use '--grep=' + foo rather than '--grep', foo because | 200 # We use '--grep=' + foo rather than '--grep', foo because |
| 202 # git 1.7.0.4 (and earlier) didn't support the separate arg. | 201 # git 1.7.0.4 (and earlier) didn't support the separate arg. |
| 203 return self._run_git(['log', '-1', '--grep=' + grep_str, '--date=iso', s
elf.find_checkout_root(path)]) | 202 return self._run_git(['log', '-1', '--grep=' + grep_str, '--date=iso', s
elf.find_checkout_root(path)]) |
| 204 | 203 |
| 205 def _commit_position_from_git_log(self, git_log): | 204 def _commit_position_from_git_log(self, git_log): |
| 206 match = re.search("^\s*Cr-Commit-Position:.*@\{#(?P<commit_position>\d+)
\}", git_log, re.MULTILINE) | 205 match = re.search(r"^\s*Cr-Commit-Position:.*@\{#(?P<commit_position>\d+
)\}", git_log, re.MULTILINE) |
| 207 if not match: | 206 if not match: |
| 208 return "" | 207 return "" |
| 209 return int(match.group('commit_position')) | 208 return int(match.group('commit_position')) |
| 210 | 209 |
| 211 def commit_position(self, path): | 210 def commit_position(self, path): |
| 212 git_log = self.most_recent_log_matching('Cr-Commit-Position:', path) | 211 git_log = self.most_recent_log_matching('Cr-Commit-Position:', path) |
| 213 return self._commit_position_from_git_log(git_log) | 212 return self._commit_position_from_git_log(git_log) |
| 214 | 213 |
| 215 def _commit_position_regex_for_timestamp(self): | 214 def _commit_position_regex_for_timestamp(self): |
| 216 return 'Cr-Commit-Position:.*@{#%s}' | 215 return 'Cr-Commit-Position:.*@{#%s}' |
| 217 | 216 |
| 218 def timestamp_of_revision(self, path, revision): | 217 def timestamp_of_revision(self, path, revision): |
| 219 git_log = self.most_recent_log_matching(self._commit_position_regex_for_
timestamp() % revision, path) | 218 git_log = self.most_recent_log_matching(self._commit_position_regex_for_
timestamp() % revision, path) |
| 220 match = re.search("^Date:\s*(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{
2}) ([+-])(\d{2})(\d{2})$", git_log, re.MULTILINE) | 219 match = re.search(r"^Date:\s*(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d
{2}) ([+-])(\d{2})(\d{2})$", git_log, re.MULTILINE) |
| 221 if not match: | 220 if not match: |
| 222 return "" | 221 return "" |
| 223 | 222 |
| 224 # Manually modify the timezone since Git doesn't have an option to show
it in UTC. | 223 # Manually modify the timezone since Git doesn't have an option to show
it in UTC. |
| 225 # Git also truncates milliseconds but we're going to ignore that for now
. | 224 # Git also truncates milliseconds but we're going to ignore that for now
. |
| 226 time_with_timezone = datetime.datetime(int(match.group(1)), int(match.gr
oup(2)), int(match.group(3)), | 225 time_with_timezone = datetime.datetime(int(match.group(1)), int(match.gr
oup(2)), int(match.group(3)), |
| 227 int(match.group(4)), int(match.gr
oup(5)), int(match.group(6)), 0) | 226 int(match.group(4)), int(match.gr
oup(5)), int(match.group(6)), 0) |
| 228 | 227 |
| 229 sign = 1 if match.group(7) == '+' else -1 | 228 sign = 1 if match.group(7) == '+' else -1 |
| 230 time_without_timezone = time_with_timezone - \ | 229 time_without_timezone = time_with_timezone - \ |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 | 277 |
| 279 def _remote_branch_ref(self): | 278 def _remote_branch_ref(self): |
| 280 # Use references so that we can avoid collisions, e.g. we don't want to
operate on refs/heads/trunk if it exists. | 279 # Use references so that we can avoid collisions, e.g. we don't want to
operate on refs/heads/trunk if it exists. |
| 281 remote_master_ref = 'refs/remotes/origin/master' | 280 remote_master_ref = 'refs/remotes/origin/master' |
| 282 if not self._branch_ref_exists(remote_master_ref): | 281 if not self._branch_ref_exists(remote_master_ref): |
| 283 raise ScriptError(message="Can't find a branch to diff against. %s d
oes not exist" % remote_master_ref) | 282 raise ScriptError(message="Can't find a branch to diff against. %s d
oes not exist" % remote_master_ref) |
| 284 return remote_master_ref | 283 return remote_master_ref |
| 285 | 284 |
| 286 def commit_locally_with_message(self, message): | 285 def commit_locally_with_message(self, message): |
| 287 command = ['commit', '--all', '-F', '-'] | 286 command = ['commit', '--all', '-F', '-'] |
| 288 self._run_git(command, input=message) | 287 self._run_git(command, input_func=message) |
| 289 | 288 |
| 290 # These methods are git specific and are meant to provide support for the Gi
t oriented workflow | 289 # These methods are git specific and are meant to provide support for the Gi
t oriented workflow |
| 291 # that Blink is moving towards, hence there are no equivalent methods in the
SVN class. | 290 # that Blink is moving towards, hence there are no equivalent methods in the
SVN class. |
| 292 | 291 |
| 293 def pull(self): | 292 def pull(self): |
| 294 self._run_git(['pull']) | 293 self._run_git(['pull']) |
| 295 | 294 |
| 296 def latest_git_commit(self): | 295 def latest_git_commit(self): |
| 297 return self._run_git(['log', '-1', '--format=%H']).strip() | 296 return self._run_git(['log', '-1', '--format=%H']).strip() |
| 298 | 297 |
| 299 def git_commits_since(self, commit): | 298 def git_commits_since(self, commit): |
| 300 return self._run_git(['log', commit + '..master', '--format=%H', '--reve
rse']).split() | 299 return self._run_git(['log', commit + '..master', '--format=%H', '--reve
rse']).split() |
| 301 | 300 |
| 302 def git_commit_detail(self, commit, format=None): | 301 def git_commit_detail(self, commit, log_format=None): |
| 303 args = ['log', '-1', commit] | 302 args = ['log', '-1', commit] |
| 304 if format: | 303 if format: |
| 305 args.append('--format=' + format) | 304 args.append('--format=' + log_format) |
| 306 return self._run_git(args) | 305 return self._run_git(args) |
| 307 | 306 |
| 308 def affected_files(self, commit): | 307 def affected_files(self, commit): |
| 309 output = self._run_git(['log', '-1', '--format=', '--name-only', commit]
) | 308 output = self._run_git(['log', '-1', '--format=', '--name-only', commit]
) |
| 310 return output.strip().split('\n') | 309 return output.strip().split('\n') |
| 311 | 310 |
| 312 def _branch_tracking_remote_master(self): | 311 def _branch_tracking_remote_master(self): |
| 313 origin_info = self._run_git(['remote', 'show', 'origin', '-n']) | 312 origin_info = self._run_git(['remote', 'show', 'origin', '-n']) |
| 314 match = re.search("^\s*(?P<branch_name>\S+)\s+merges with remote master$
", origin_info, re.MULTILINE) | 313 match = re.search(r"^\s*(?P<branch_name>\S+)\s+merges with remote master
$", origin_info, re.MULTILINE) |
| 315 if not match: | 314 if not match: |
| 316 raise ScriptError(message="Unable to find local branch tracking orig
in/master.") | 315 raise ScriptError(message="Unable to find local branch tracking orig
in/master.") |
| 317 branch = str(match.group("branch_name")) | 316 branch = str(match.group("branch_name")) |
| 318 return self._branch_from_ref(self._run_git(['rev-parse', '--symbolic-ful
l-name', branch]).strip()) | 317 return self._branch_from_ref(self._run_git(['rev-parse', '--symbolic-ful
l-name', branch]).strip()) |
| 319 | 318 |
| 320 def is_cleanly_tracking_remote_master(self): | 319 def is_cleanly_tracking_remote_master(self): |
| 321 if self.has_working_directory_changes(): | 320 if self.has_working_directory_changes(): |
| 322 return False | 321 return False |
| 323 if self.current_branch() != self._branch_tracking_remote_master(): | 322 if self.current_branch() != self._branch_tracking_remote_master(): |
| 324 return False | 323 return False |
| 325 if len(self._local_commits(self._branch_tracking_remote_master())) > 0: | 324 if len(self._local_commits(self._branch_tracking_remote_master())) > 0: |
| 326 return False | 325 return False |
| 327 return True | 326 return True |
| 328 | 327 |
| 329 def ensure_cleanly_tracking_remote_master(self): | 328 def ensure_cleanly_tracking_remote_master(self): |
| 330 self._discard_working_directory_changes() | 329 self._discard_working_directory_changes() |
| 331 self._run_git(['checkout', '-q', self._branch_tracking_remote_master()]) | 330 self._run_git(['checkout', '-q', self._branch_tracking_remote_master()]) |
| 332 self._discard_local_commits() | 331 self._discard_local_commits() |
| 333 | 332 |
| 334 def get_issue_number(self): | 333 def get_issue_number(self): |
| 335 return str(self._run_git(['cl', 'issue']).split()[2]) | 334 return str(self._run_git(['cl', 'issue']).split()[2]) |
| OLD | NEW |