| 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 |
| 34 from webkitpy.common.checkout.scm.scm import SCM | 35 from webkitpy.common.checkout.scm.scm import SCM |
| 35 from webkitpy.common.memoized import memoized | 36 from webkitpy.common.memoized import memoized |
| 36 from webkitpy.common.system.executive import Executive, ScriptError | 37 from webkitpy.common.system.executive import Executive, ScriptError |
| 37 | 38 |
| 38 _log = logging.getLogger(__name__) | 39 _log = logging.getLogger(__name__) |
| 39 | 40 |
| 40 | 41 |
| 41 class AmbiguousCommitError(Exception): | 42 class AmbiguousCommitError(Exception): |
| 42 | 43 |
| 43 def __init__(self, num_local_commits, has_working_directory_changes): | 44 def __init__(self, num_local_commits, has_working_directory_changes): |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 | 196 |
| 196 def display_name(self): | 197 def display_name(self): |
| 197 return "git" | 198 return "git" |
| 198 | 199 |
| 199 def most_recent_log_matching(self, grep_str, path): | 200 def most_recent_log_matching(self, grep_str, path): |
| 200 # We use '--grep=' + foo rather than '--grep', foo because | 201 # We use '--grep=' + foo rather than '--grep', foo because |
| 201 # git 1.7.0.4 (and earlier) didn't support the separate arg. | 202 # git 1.7.0.4 (and earlier) didn't support the separate arg. |
| 202 return self._run_git(['log', '-1', '--grep=' + grep_str, '--date=iso', s
elf.find_checkout_root(path)]) | 203 return self._run_git(['log', '-1', '--grep=' + grep_str, '--date=iso', s
elf.find_checkout_root(path)]) |
| 203 | 204 |
| 204 def _commit_position_from_git_log(self, git_log): | 205 def _commit_position_from_git_log(self, git_log): |
| 205 match = re.search(r"^\s*Cr-Commit-Position:.*@\{#(?P<commit_position>\d+
)\}", git_log, re.MULTILINE) | 206 match = re.search("^\s*Cr-Commit-Position:.*@\{#(?P<commit_position>\d+)
\}", git_log, re.MULTILINE) |
| 206 if not match: | 207 if not match: |
| 207 return "" | 208 return "" |
| 208 return int(match.group('commit_position')) | 209 return int(match.group('commit_position')) |
| 209 | 210 |
| 210 def commit_position(self, path): | 211 def commit_position(self, path): |
| 211 git_log = self.most_recent_log_matching('Cr-Commit-Position:', path) | 212 git_log = self.most_recent_log_matching('Cr-Commit-Position:', path) |
| 212 return self._commit_position_from_git_log(git_log) | 213 return self._commit_position_from_git_log(git_log) |
| 213 | 214 |
| 214 def _commit_position_regex_for_timestamp(self): | 215 def _commit_position_regex_for_timestamp(self): |
| 215 return 'Cr-Commit-Position:.*@{#%s}' | 216 return 'Cr-Commit-Position:.*@{#%s}' |
| 216 | 217 |
| 217 def timestamp_of_revision(self, path, revision): | 218 def timestamp_of_revision(self, path, revision): |
| 218 git_log = self.most_recent_log_matching(self._commit_position_regex_for_
timestamp() % revision, path) | 219 git_log = self.most_recent_log_matching(self._commit_position_regex_for_
timestamp() % revision, path) |
| 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) | 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) |
| 220 if not match: | 221 if not match: |
| 221 return "" | 222 return "" |
| 222 | 223 |
| 223 # Manually modify the timezone since Git doesn't have an option to show
it in UTC. | 224 # Manually modify the timezone since Git doesn't have an option to show
it in UTC. |
| 224 # Git also truncates milliseconds but we're going to ignore that for now
. | 225 # Git also truncates milliseconds but we're going to ignore that for now
. |
| 225 time_with_timezone = datetime.datetime(int(match.group(1)), int(match.gr
oup(2)), int(match.group(3)), | 226 time_with_timezone = datetime.datetime(int(match.group(1)), int(match.gr
oup(2)), int(match.group(3)), |
| 226 int(match.group(4)), int(match.gr
oup(5)), int(match.group(6)), 0) | 227 int(match.group(4)), int(match.gr
oup(5)), int(match.group(6)), 0) |
| 227 | 228 |
| 228 sign = 1 if match.group(7) == '+' else -1 | 229 sign = 1 if match.group(7) == '+' else -1 |
| 229 time_without_timezone = time_with_timezone - \ | 230 time_without_timezone = time_with_timezone - \ |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 | 278 |
| 278 def _remote_branch_ref(self): | 279 def _remote_branch_ref(self): |
| 279 # Use references so that we can avoid collisions, e.g. we don't want to
operate on refs/heads/trunk if it exists. | 280 # Use references so that we can avoid collisions, e.g. we don't want to
operate on refs/heads/trunk if it exists. |
| 280 remote_master_ref = 'refs/remotes/origin/master' | 281 remote_master_ref = 'refs/remotes/origin/master' |
| 281 if not self._branch_ref_exists(remote_master_ref): | 282 if not self._branch_ref_exists(remote_master_ref): |
| 282 raise ScriptError(message="Can't find a branch to diff against. %s d
oes not exist" % remote_master_ref) | 283 raise ScriptError(message="Can't find a branch to diff against. %s d
oes not exist" % remote_master_ref) |
| 283 return remote_master_ref | 284 return remote_master_ref |
| 284 | 285 |
| 285 def commit_locally_with_message(self, message): | 286 def commit_locally_with_message(self, message): |
| 286 command = ['commit', '--all', '-F', '-'] | 287 command = ['commit', '--all', '-F', '-'] |
| 287 self._run_git(command, input_func=message) | 288 self._run_git(command, input=message) |
| 288 | 289 |
| 289 # These methods are git specific and are meant to provide support for the Gi
t oriented workflow | 290 # These methods are git specific and are meant to provide support for the Gi
t oriented workflow |
| 290 # that Blink is moving towards, hence there are no equivalent methods in the
SVN class. | 291 # that Blink is moving towards, hence there are no equivalent methods in the
SVN class. |
| 291 | 292 |
| 292 def pull(self): | 293 def pull(self): |
| 293 self._run_git(['pull']) | 294 self._run_git(['pull']) |
| 294 | 295 |
| 295 def latest_git_commit(self): | 296 def latest_git_commit(self): |
| 296 return self._run_git(['log', '-1', '--format=%H']).strip() | 297 return self._run_git(['log', '-1', '--format=%H']).strip() |
| 297 | 298 |
| 298 def git_commits_since(self, commit): | 299 def git_commits_since(self, commit): |
| 299 return self._run_git(['log', commit + '..master', '--format=%H', '--reve
rse']).split() | 300 return self._run_git(['log', commit + '..master', '--format=%H', '--reve
rse']).split() |
| 300 | 301 |
| 301 def git_commit_detail(self, commit, log_format=None): | 302 def git_commit_detail(self, commit, format=None): |
| 302 args = ['log', '-1', commit] | 303 args = ['log', '-1', commit] |
| 303 if format: | 304 if format: |
| 304 args.append('--format=' + log_format) | 305 args.append('--format=' + format) |
| 305 return self._run_git(args) | 306 return self._run_git(args) |
| 306 | 307 |
| 307 def affected_files(self, commit): | 308 def affected_files(self, commit): |
| 308 output = self._run_git(['log', '-1', '--format=', '--name-only', commit]
) | 309 output = self._run_git(['log', '-1', '--format=', '--name-only', commit]
) |
| 309 return output.strip().split('\n') | 310 return output.strip().split('\n') |
| 310 | 311 |
| 311 def _branch_tracking_remote_master(self): | 312 def _branch_tracking_remote_master(self): |
| 312 origin_info = self._run_git(['remote', 'show', 'origin', '-n']) | 313 origin_info = self._run_git(['remote', 'show', 'origin', '-n']) |
| 313 match = re.search(r"^\s*(?P<branch_name>\S+)\s+merges with remote master
$", origin_info, re.MULTILINE) | 314 match = re.search("^\s*(?P<branch_name>\S+)\s+merges with remote master$
", origin_info, re.MULTILINE) |
| 314 if not match: | 315 if not match: |
| 315 raise ScriptError(message="Unable to find local branch tracking orig
in/master.") | 316 raise ScriptError(message="Unable to find local branch tracking orig
in/master.") |
| 316 branch = str(match.group("branch_name")) | 317 branch = str(match.group("branch_name")) |
| 317 return self._branch_from_ref(self._run_git(['rev-parse', '--symbolic-ful
l-name', branch]).strip()) | 318 return self._branch_from_ref(self._run_git(['rev-parse', '--symbolic-ful
l-name', branch]).strip()) |
| 318 | 319 |
| 319 def is_cleanly_tracking_remote_master(self): | 320 def is_cleanly_tracking_remote_master(self): |
| 320 if self.has_working_directory_changes(): | 321 if self.has_working_directory_changes(): |
| 321 return False | 322 return False |
| 322 if self.current_branch() != self._branch_tracking_remote_master(): | 323 if self.current_branch() != self._branch_tracking_remote_master(): |
| 323 return False | 324 return False |
| 324 if len(self._local_commits(self._branch_tracking_remote_master())) > 0: | 325 if len(self._local_commits(self._branch_tracking_remote_master())) > 0: |
| 325 return False | 326 return False |
| 326 return True | 327 return True |
| 327 | 328 |
| 328 def ensure_cleanly_tracking_remote_master(self): | 329 def ensure_cleanly_tracking_remote_master(self): |
| 329 self._discard_working_directory_changes() | 330 self._discard_working_directory_changes() |
| 330 self._run_git(['checkout', '-q', self._branch_tracking_remote_master()]) | 331 self._run_git(['checkout', '-q', self._branch_tracking_remote_master()]) |
| 331 self._discard_local_commits() | 332 self._discard_local_commits() |
| 332 | 333 |
| 333 def get_issue_number(self): | 334 def get_issue_number(self): |
| 334 return str(self._run_git(['cl', 'issue']).split()[2]) | 335 return str(self._run_git(['cl', 'issue']).split()[2]) |
| OLD | NEW |