| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 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 | 5 |
| 6 # Copyright (C) 2008 Evan Martin <martine@danga.com> | 6 # Copyright (C) 2008 Evan Martin <martine@danga.com> |
| 7 | 7 |
| 8 """A git-command for integrating reviews on Rietveld and Gerrit.""" | 8 """A git-command for integrating reviews on Rietveld and Gerrit.""" |
| 9 | 9 |
| 10 from __future__ import print_function | 10 from __future__ import print_function |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 return e.stdout | 107 return e.stdout |
| 108 | 108 |
| 109 | 109 |
| 110 def RunGit(args, **kwargs): | 110 def RunGit(args, **kwargs): |
| 111 """Returns stdout.""" | 111 """Returns stdout.""" |
| 112 return RunCommand(['git'] + args, **kwargs) | 112 return RunCommand(['git'] + args, **kwargs) |
| 113 | 113 |
| 114 | 114 |
| 115 def RunGitWithCode(args, suppress_stderr=False): | 115 def RunGitWithCode(args, suppress_stderr=False): |
| 116 """Returns return code and stdout.""" | 116 """Returns return code and stdout.""" |
| 117 if suppress_stderr: |
| 118 stderr = subprocess2.VOID |
| 119 else: |
| 120 stderr = sys.stderr |
| 117 try: | 121 try: |
| 118 if suppress_stderr: | 122 (out, _), code = subprocess2.communicate(['git'] + args, |
| 119 stderr = subprocess2.VOID | 123 env=GetNoGitPagerEnv(), |
| 120 else: | 124 stdout=subprocess2.PIPE, |
| 121 stderr = sys.stderr | 125 stderr=stderr) |
| 122 out, code = subprocess2.communicate(['git'] + args, | 126 return code, out |
| 123 env=GetNoGitPagerEnv(), | 127 except subprocess2.CalledProcessError as e: |
| 124 stdout=subprocess2.PIPE, | 128 logging.debug('Failed running %s', args) |
| 125 stderr=stderr) | 129 return e.returncode, e.stdout |
| 126 return code, out[0] | |
| 127 except ValueError: | |
| 128 # When the subprocess fails, it returns None. That triggers a ValueError | |
| 129 # when trying to unpack the return value into (out, code). | |
| 130 return 1, '' | |
| 131 | 130 |
| 132 | 131 |
| 133 def RunGitSilent(args): | 132 def RunGitSilent(args): |
| 134 """Returns stdout, suppresses stderr and ignores the return code.""" | 133 """Returns stdout, suppresses stderr and ignores the return code.""" |
| 135 return RunGitWithCode(args, suppress_stderr=True)[1] | 134 return RunGitWithCode(args, suppress_stderr=True)[1] |
| 136 | 135 |
| 137 | 136 |
| 138 def IsGitVersionAtLeast(min_version): | 137 def IsGitVersionAtLeast(min_version): |
| 139 prefix = 'git version ' | 138 prefix = 'git version ' |
| 140 version = RunGit(['--version']).strip() | 139 version = RunGit(['--version']).strip() |
| 141 return (version.startswith(prefix) and | 140 return (version.startswith(prefix) and |
| 142 LooseVersion(version[len(prefix):]) >= LooseVersion(min_version)) | 141 LooseVersion(version[len(prefix):]) >= LooseVersion(min_version)) |
| 143 | 142 |
| 144 | 143 |
| 145 def BranchExists(branch): | 144 def BranchExists(branch): |
| 146 """Return True if specified branch exists.""" | 145 """Return True if specified branch exists.""" |
| 147 code, _ = RunGitWithCode(['rev-parse', '--verify', branch], | 146 code, _ = RunGitWithCode(['rev-parse', '--verify', branch], |
| 148 suppress_stderr=True) | 147 suppress_stderr=True) |
| 149 return not code | 148 return not code |
| 150 | 149 |
| 151 | 150 |
| 152 def ask_for_data(prompt): | 151 def ask_for_data(prompt): |
| 153 try: | 152 try: |
| 154 return raw_input(prompt) | 153 return raw_input(prompt) |
| 155 except KeyboardInterrupt: | 154 except KeyboardInterrupt: |
| 156 # Hide the exception. | 155 # Hide the exception. |
| 157 sys.exit(1) | 156 sys.exit(1) |
| 158 | 157 |
| 159 | 158 |
| 160 def git_set_branch_value(key, value): | 159 def _git_branch_config_key(branch, setting): |
| 161 branch = GetCurrentBranch() | 160 """Helper method to return Git config key for a branch.""" |
| 162 if not branch: | 161 assert branch |
| 163 return | 162 return 'branch.%s.%s' % (branch, setting) |
| 164 | |
| 165 cmd = ['config'] | |
| 166 if isinstance(value, int): | |
| 167 cmd.append('--int') | |
| 168 git_key = 'branch.%s.%s' % (branch, key) | |
| 169 RunGit(cmd + [git_key, str(value)]) | |
| 170 | 163 |
| 171 | 164 |
| 172 def git_get_branch_default(key, default): | 165 def _git_get_branch_config_value(setting, default=None, value_type=str, |
| 173 branch = GetCurrentBranch() | 166 branch=False): |
| 174 if branch: | 167 assert value_type in (int, str, bool) |
| 175 git_key = 'branch.%s.%s' % (branch, key) | 168 if branch is False: # Distinguishing default arg value from None. |
| 176 (_, stdout) = RunGitWithCode(['config', '--int', '--get', git_key]) | 169 branch = GetCurrentBranch() |
| 177 try: | 170 |
| 178 return int(stdout.strip()) | 171 if not branch: |
| 179 except ValueError: | 172 return default |
| 180 pass | 173 |
| 174 args = ['config'] |
| 175 if value_type == int: |
| 176 args.append('--int') |
| 177 elif value_type == bool: |
| 178 args.append('--bool') |
| 179 args.append(_git_branch_config_key(branch, setting)) |
| 180 code, out = RunGitWithCode(args) |
| 181 if code == 0: |
| 182 value = out.strip() |
| 183 if value_type == int: |
| 184 return int(value) |
| 185 if value_type == bool: |
| 186 return bool(value.lower() == 'true') |
| 187 return value |
| 181 return default | 188 return default |
| 182 | 189 |
| 183 | 190 |
| 191 def _git_unset_branch_config_value(setting, branch=None, **kwargs): |
| 192 if not branch: |
| 193 branch = GetCurrentBranch() |
| 194 assert branch |
| 195 RunGit(['config', '--unset', _git_branch_config_key(branch, setting)], |
| 196 **kwargs) |
| 197 |
| 198 |
| 199 def _git_set_branch_config_value(setting, value, branch=None): |
| 200 if not branch: |
| 201 branch = GetCurrentBranch() |
| 202 assert branch |
| 203 args = ['config'] |
| 204 # Check for boolean first, becuase bool is int, but int is not bool. |
| 205 if isinstance(value, bool): |
| 206 args.append('--bool') |
| 207 value = str(value).lower() |
| 208 elif isinstance(value, int): |
| 209 args.append('--int') |
| 210 value = str(value) |
| 211 else: |
| 212 value = str(value) |
| 213 args.extend([_git_branch_config_key(branch, setting), value]) |
| 214 RunGit(args) |
| 215 |
| 216 |
| 184 def add_git_similarity(parser): | 217 def add_git_similarity(parser): |
| 185 parser.add_option( | 218 parser.add_option( |
| 186 '--similarity', metavar='SIM', type='int', action='store', | 219 '--similarity', metavar='SIM', type=int, action='store', |
| 187 help='Sets the percentage that a pair of files need to match in order to' | 220 help='Sets the percentage that a pair of files need to match in order to' |
| 188 ' be considered copies (default 50)') | 221 ' be considered copies (default 50)') |
| 189 parser.add_option( | 222 parser.add_option( |
| 190 '--find-copies', action='store_true', | 223 '--find-copies', action='store_true', |
| 191 help='Allows git to look for copies.') | 224 help='Allows git to look for copies.') |
| 192 parser.add_option( | 225 parser.add_option( |
| 193 '--no-find-copies', action='store_false', dest='find_copies', | 226 '--no-find-copies', action='store_false', dest='find_copies', |
| 194 help='Disallows git from looking for copies.') | 227 help='Disallows git from looking for copies.') |
| 195 | 228 |
| 196 old_parser_args = parser.parse_args | 229 old_parser_args = parser.parse_args |
| 197 def Parse(args): | 230 def Parse(args): |
| 198 options, args = old_parser_args(args) | 231 options, args = old_parser_args(args) |
| 199 | 232 |
| 200 if options.similarity is None: | 233 if options.similarity is None: |
| 201 options.similarity = git_get_branch_default('git-cl-similarity', 50) | 234 options.similarity = _git_get_branch_config_value( |
| 235 'git-cl-similarity', default=50, value_type=int) |
| 202 else: | 236 else: |
| 203 print('Note: Saving similarity of %d%% in git config.' | 237 print('Note: Saving similarity of %d%% in git config.' |
| 204 % options.similarity) | 238 % options.similarity) |
| 205 git_set_branch_value('git-cl-similarity', options.similarity) | 239 _git_set_branch_config_value('git-cl-similarity', options.similarity) |
| 206 | 240 |
| 207 options.similarity = max(0, min(options.similarity, 100)) | 241 options.similarity = max(0, min(options.similarity, 100)) |
| 208 | 242 |
| 209 if options.find_copies is None: | 243 if options.find_copies is None: |
| 210 options.find_copies = bool( | 244 options.find_copies = _git_get_branch_config_value( |
| 211 git_get_branch_default('git-find-copies', True)) | 245 'git-find-copies', default=True, value_type=bool) |
| 212 else: | 246 else: |
| 213 git_set_branch_value('git-find-copies', int(options.find_copies)) | 247 _git_set_branch_config_value('git-find-copies', bool(options.find_copies)) |
| 214 | 248 |
| 215 print('Using %d%% similarity for rename/copy detection. ' | 249 print('Using %d%% similarity for rename/copy detection. ' |
| 216 'Override with --similarity.' % options.similarity) | 250 'Override with --similarity.' % options.similarity) |
| 217 | 251 |
| 218 return options, args | 252 return options, args |
| 219 parser.parse_args = Parse | 253 parser.parse_args = Parse |
| 220 | 254 |
| 221 | 255 |
| 222 def _get_properties_from_options(options): | 256 def _get_properties_from_options(options): |
| 223 properties = dict(x.split('=', 1) for x in options.properties) | 257 properties = dict(x.split('=', 1) for x in options.properties) |
| (...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 899 | 933 |
| 900 class Changelist(object): | 934 class Changelist(object): |
| 901 """Changelist works with one changelist in local branch. | 935 """Changelist works with one changelist in local branch. |
| 902 | 936 |
| 903 Supports two codereview backends: Rietveld or Gerrit, selected at object | 937 Supports two codereview backends: Rietveld or Gerrit, selected at object |
| 904 creation. | 938 creation. |
| 905 | 939 |
| 906 Notes: | 940 Notes: |
| 907 * Not safe for concurrent multi-{thread,process} use. | 941 * Not safe for concurrent multi-{thread,process} use. |
| 908 * Caches values from current branch. Therefore, re-use after branch change | 942 * Caches values from current branch. Therefore, re-use after branch change |
| 909 with care. | 943 with great care. |
| 910 """ | 944 """ |
| 911 | 945 |
| 912 def __init__(self, branchref=None, issue=None, codereview=None, **kwargs): | 946 def __init__(self, branchref=None, issue=None, codereview=None, **kwargs): |
| 913 """Create a new ChangeList instance. | 947 """Create a new ChangeList instance. |
| 914 | 948 |
| 915 If issue is given, the codereview must be given too. | 949 If issue is given, the codereview must be given too. |
| 916 | 950 |
| 917 If `codereview` is given, it must be 'rietveld' or 'gerrit'. | 951 If `codereview` is given, it must be 'rietveld' or 'gerrit'. |
| 918 Otherwise, it's decided based on current configuration of the local branch, | 952 Otherwise, it's decided based on current configuration of the local branch, |
| 919 with default being 'rietveld' for backwards compatibility. | 953 with default being 'rietveld' for backwards compatibility. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 959 cls = _CODEREVIEW_IMPLEMENTATIONS[codereview] | 993 cls = _CODEREVIEW_IMPLEMENTATIONS[codereview] |
| 960 self._codereview = codereview | 994 self._codereview = codereview |
| 961 self._codereview_impl = cls(self, **kwargs) | 995 self._codereview_impl = cls(self, **kwargs) |
| 962 return | 996 return |
| 963 | 997 |
| 964 # Automatic selection based on issue number set for a current branch. | 998 # Automatic selection based on issue number set for a current branch. |
| 965 # Rietveld takes precedence over Gerrit. | 999 # Rietveld takes precedence over Gerrit. |
| 966 assert not self.issue | 1000 assert not self.issue |
| 967 # Whether we find issue or not, we are doing the lookup. | 1001 # Whether we find issue or not, we are doing the lookup. |
| 968 self.lookedup_issue = True | 1002 self.lookedup_issue = True |
| 969 for codereview, cls in _CODEREVIEW_IMPLEMENTATIONS.iteritems(): | 1003 if self.GetBranch(): |
| 970 setting = cls.IssueSetting(self.GetBranch()) | 1004 for codereview, cls in _CODEREVIEW_IMPLEMENTATIONS.iteritems(): |
| 971 issue = RunGit(['config', setting], error_ok=True).strip() | 1005 issue = _git_get_branch_config_value( |
| 972 if issue: | 1006 cls.IssueSettingSuffix(), value_type=int, branch=self.GetBranch()) |
| 973 self._codereview = codereview | 1007 if issue: |
| 974 self._codereview_impl = cls(self, **kwargs) | 1008 self._codereview = codereview |
| 975 self.issue = int(issue) | 1009 self._codereview_impl = cls(self, **kwargs) |
| 976 return | 1010 self.issue = int(issue) |
| 1011 return |
| 977 | 1012 |
| 978 # No issue is set for this branch, so decide based on repo-wide settings. | 1013 # No issue is set for this branch, so decide based on repo-wide settings. |
| 979 return self._load_codereview_impl( | 1014 return self._load_codereview_impl( |
| 980 codereview='gerrit' if settings.GetIsGerrit() else 'rietveld', | 1015 codereview='gerrit' if settings.GetIsGerrit() else 'rietveld', |
| 981 **kwargs) | 1016 **kwargs) |
| 982 | 1017 |
| 983 def IsGerrit(self): | 1018 def IsGerrit(self): |
| 984 return self._codereview == 'gerrit' | 1019 return self._codereview == 'gerrit' |
| 985 | 1020 |
| 986 def GetCCList(self): | 1021 def GetCCList(self): |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1018 | 1053 |
| 1019 def GetBranchRef(self): | 1054 def GetBranchRef(self): |
| 1020 """Returns the full branch name, e.g. 'refs/heads/master'.""" | 1055 """Returns the full branch name, e.g. 'refs/heads/master'.""" |
| 1021 self.GetBranch() # Poke the lazy loader. | 1056 self.GetBranch() # Poke the lazy loader. |
| 1022 return self.branchref | 1057 return self.branchref |
| 1023 | 1058 |
| 1024 def ClearBranch(self): | 1059 def ClearBranch(self): |
| 1025 """Clears cached branch data of this object.""" | 1060 """Clears cached branch data of this object.""" |
| 1026 self.branch = self.branchref = None | 1061 self.branch = self.branchref = None |
| 1027 | 1062 |
| 1063 def _GitGetBranchConfigValue(self, setting, default=None, **kwargs): |
| 1064 kwargs['branch'] = self.GetBranch() |
| 1065 return _git_get_branch_config_value(setting, default, **kwargs) |
| 1066 |
| 1067 def _GitSetBranchConfigValue(self, setting, value, **kwargs): |
| 1068 assert self.GetBranch() |
| 1069 kwargs['branch'] = self.GetBranch() |
| 1070 return _git_set_branch_config_value(setting, value, **kwargs) |
| 1071 |
| 1072 def _GitUnsetBranchConfigValue(self, setting, **kwargs): |
| 1073 assert self.GetBranch() |
| 1074 kwargs['branch'] = self.GetBranch() |
| 1075 return _git_unset_branch_config_value(setting, **kwargs) |
| 1076 |
| 1028 @staticmethod | 1077 @staticmethod |
| 1029 def FetchUpstreamTuple(branch): | 1078 def FetchUpstreamTuple(branch): |
| 1030 """Returns a tuple containing remote and remote ref, | 1079 """Returns a tuple containing remote and remote ref, |
| 1031 e.g. 'origin', 'refs/heads/master' | 1080 e.g. 'origin', 'refs/heads/master' |
| 1032 """ | 1081 """ |
| 1033 remote = '.' | 1082 remote = '.' |
| 1034 upstream_branch = RunGit(['config', 'branch.%s.merge' % branch], | 1083 upstream_branch = _git_get_branch_config_value('merge', branch=branch) |
| 1035 error_ok=True).strip() | 1084 |
| 1036 if upstream_branch: | 1085 if upstream_branch: |
| 1037 remote = RunGit(['config', 'branch.%s.remote' % branch]).strip() | 1086 remote = _git_get_branch_config_value('remote', branch=branch) |
| 1038 else: | 1087 else: |
| 1039 upstream_branch = RunGit(['config', 'rietveld.upstream-branch'], | 1088 upstream_branch = RunGit(['config', 'rietveld.upstream-branch'], |
| 1040 error_ok=True).strip() | 1089 error_ok=True).strip() |
| 1041 if upstream_branch: | 1090 if upstream_branch: |
| 1042 remote = RunGit(['config', 'rietveld.upstream-remote']).strip() | 1091 remote = RunGit(['config', 'rietveld.upstream-remote']).strip() |
| 1043 else: | 1092 else: |
| 1044 # Fall back on trying a git-svn upstream branch. | 1093 # Fall back on trying a git-svn upstream branch. |
| 1045 if settings.GetIsGitSvn(): | 1094 if settings.GetIsGitSvn(): |
| 1046 upstream_branch = settings.GetSVNBranch() | 1095 upstream_branch = settings.GetSVNBranch() |
| 1047 else: | 1096 else: |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1161 len(common_commits), remote_branch, upstream_git_obj), | 1210 len(common_commits), remote_branch, upstream_git_obj), |
| 1162 file=sys.stderr) | 1211 file=sys.stderr) |
| 1163 return False | 1212 return False |
| 1164 return True | 1213 return True |
| 1165 | 1214 |
| 1166 def GetGitBaseUrlFromConfig(self): | 1215 def GetGitBaseUrlFromConfig(self): |
| 1167 """Return the configured base URL from branch.<branchname>.baseurl. | 1216 """Return the configured base URL from branch.<branchname>.baseurl. |
| 1168 | 1217 |
| 1169 Returns None if it is not set. | 1218 Returns None if it is not set. |
| 1170 """ | 1219 """ |
| 1171 return RunGit(['config', 'branch.%s.base-url' % self.GetBranch()], | 1220 return self._GitGetBranchConfigValue('base-url') |
| 1172 error_ok=True).strip() | |
| 1173 | 1221 |
| 1174 def GetGitSvnRemoteUrl(self): | 1222 def GetGitSvnRemoteUrl(self): |
| 1175 """Return the configured git-svn remote URL parsed from git svn info. | 1223 """Return the configured git-svn remote URL parsed from git svn info. |
| 1176 | 1224 |
| 1177 Returns None if it is not set. | 1225 Returns None if it is not set. |
| 1178 """ | 1226 """ |
| 1179 # URL is dependent on the current directory. | 1227 # URL is dependent on the current directory. |
| 1180 data = RunGit(['svn', 'info'], cwd=settings.GetRoot()) | 1228 data = RunGit(['svn', 'info'], cwd=settings.GetRoot()) |
| 1181 if data: | 1229 if data: |
| 1182 keys = dict(line.split(': ', 1) for line in data.splitlines() | 1230 keys = dict(line.split(': ', 1) for line in data.splitlines() |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1195 # If URL is pointing to a local directory, it is probably a git cache. | 1243 # If URL is pointing to a local directory, it is probably a git cache. |
| 1196 if os.path.isdir(url): | 1244 if os.path.isdir(url): |
| 1197 url = RunGit(['config', 'remote.%s.url' % remote], | 1245 url = RunGit(['config', 'remote.%s.url' % remote], |
| 1198 error_ok=True, | 1246 error_ok=True, |
| 1199 cwd=url).strip() | 1247 cwd=url).strip() |
| 1200 return url | 1248 return url |
| 1201 | 1249 |
| 1202 def GetIssue(self): | 1250 def GetIssue(self): |
| 1203 """Returns the issue number as a int or None if not set.""" | 1251 """Returns the issue number as a int or None if not set.""" |
| 1204 if self.issue is None and not self.lookedup_issue: | 1252 if self.issue is None and not self.lookedup_issue: |
| 1205 issue = RunGit(['config', | 1253 self.issue = self._GitGetBranchConfigValue( |
| 1206 self._codereview_impl.IssueSetting(self.GetBranch())], | 1254 self._codereview_impl.IssueSettingSuffix(), value_type=int) |
| 1207 error_ok=True).strip() | |
| 1208 self.issue = int(issue) or None if issue else None | |
| 1209 self.lookedup_issue = True | 1255 self.lookedup_issue = True |
| 1210 return self.issue | 1256 return self.issue |
| 1211 | 1257 |
| 1212 def GetIssueURL(self): | 1258 def GetIssueURL(self): |
| 1213 """Get the URL for a particular issue.""" | 1259 """Get the URL for a particular issue.""" |
| 1214 issue = self.GetIssue() | 1260 issue = self.GetIssue() |
| 1215 if not issue: | 1261 if not issue: |
| 1216 return None | 1262 return None |
| 1217 return '%s/%s' % (self._codereview_impl.GetCodereviewServer(), issue) | 1263 return '%s/%s' % (self._codereview_impl.GetCodereviewServer(), issue) |
| 1218 | 1264 |
| 1219 def GetDescription(self, pretty=False): | 1265 def GetDescription(self, pretty=False): |
| 1220 if not self.has_description: | 1266 if not self.has_description: |
| 1221 if self.GetIssue(): | 1267 if self.GetIssue(): |
| 1222 self.description = self._codereview_impl.FetchDescription() | 1268 self.description = self._codereview_impl.FetchDescription() |
| 1223 self.has_description = True | 1269 self.has_description = True |
| 1224 if pretty: | 1270 if pretty: |
| 1225 wrapper = textwrap.TextWrapper() | 1271 wrapper = textwrap.TextWrapper() |
| 1226 wrapper.initial_indent = wrapper.subsequent_indent = ' ' | 1272 wrapper.initial_indent = wrapper.subsequent_indent = ' ' |
| 1227 return wrapper.fill(self.description) | 1273 return wrapper.fill(self.description) |
| 1228 return self.description | 1274 return self.description |
| 1229 | 1275 |
| 1230 def GetPatchset(self): | 1276 def GetPatchset(self): |
| 1231 """Returns the patchset number as a int or None if not set.""" | 1277 """Returns the patchset number as a int or None if not set.""" |
| 1232 if self.patchset is None and not self.lookedup_patchset: | 1278 if self.patchset is None and not self.lookedup_patchset: |
| 1233 patchset = RunGit(['config', self._codereview_impl.PatchsetSetting()], | 1279 self.patchset = self._GitGetBranchConfigValue( |
| 1234 error_ok=True).strip() | 1280 self._codereview_impl.PatchsetSettingSuffix(), value_type=int) |
| 1235 self.patchset = int(patchset) or None if patchset else None | |
| 1236 self.lookedup_patchset = True | 1281 self.lookedup_patchset = True |
| 1237 return self.patchset | 1282 return self.patchset |
| 1238 | 1283 |
| 1239 def SetPatchset(self, patchset): | 1284 def SetPatchset(self, patchset): |
| 1240 """Set this branch's patchset. If patchset=0, clears the patchset.""" | 1285 """Set this branch's patchset. If patchset=0, clears the patchset.""" |
| 1241 patchset_setting = self._codereview_impl.PatchsetSetting() | 1286 assert self.GetBranch() |
| 1242 if patchset: | 1287 if patchset: |
| 1243 RunGit(['config', patchset_setting, str(patchset)]) | 1288 patchset = int(patchset) |
| 1289 self._GitSetBranchConfigValue( |
| 1290 self._codereview_impl.PatchsetSettingSuffix(), patchset) |
| 1244 self.patchset = patchset | 1291 self.patchset = patchset |
| 1245 else: | 1292 else: |
| 1246 RunGit(['config', '--unset', patchset_setting], | 1293 self._GitUnsetBranchConfigValue( |
| 1247 stderr=subprocess2.PIPE, error_ok=True) | 1294 self._codereview_impl.PatchsetSettingSuffix()) |
| 1248 self.patchset = None | 1295 self.patchset = None |
| 1249 | 1296 |
| 1250 def SetIssue(self, issue=None): | 1297 def SetIssue(self, issue=None): |
| 1251 """Set this branch's issue. If issue isn't given, clears the issue.""" | 1298 """Set this branch's issue. If issue isn't given, clears the issue.""" |
| 1252 issue_setting = self._codereview_impl.IssueSetting(self.GetBranch()) | 1299 assert self.GetBranch() |
| 1253 codereview_setting = self._codereview_impl.GetCodereviewServerSetting() | |
| 1254 if issue: | 1300 if issue: |
| 1301 issue = int(issue) |
| 1302 self._GitSetBranchConfigValue( |
| 1303 self._codereview_impl.IssueSettingSuffix(), issue) |
| 1255 self.issue = issue | 1304 self.issue = issue |
| 1256 RunGit(['config', issue_setting, str(issue)]) | |
| 1257 codereview_server = self._codereview_impl.GetCodereviewServer() | 1305 codereview_server = self._codereview_impl.GetCodereviewServer() |
| 1258 if codereview_server: | 1306 if codereview_server: |
| 1259 RunGit(['config', codereview_setting, codereview_server]) | 1307 self._GitSetBranchConfigValue( |
| 1308 self._codereview_impl.CodereviewServerSettingSuffix(), |
| 1309 codereview_server) |
| 1260 else: | 1310 else: |
| 1261 # Reset it regardless. It doesn't hurt. | 1311 # Reset all of these just to be clean. |
| 1262 config_settings = [issue_setting, self._codereview_impl.PatchsetSetting()] | 1312 reset_suffixes = [ |
| 1263 for prop in (['last-upload-hash'] + | 1313 'last-upload-hash', |
| 1264 self._codereview_impl._PostUnsetIssueProperties()): | 1314 self._codereview_impl.IssueSettingSuffix(), |
| 1265 config_settings.append('branch.%s.%s' % (self.GetBranch(), prop)) | 1315 self._codereview_impl.PatchsetSettingSuffix(), |
| 1266 for setting in config_settings: | 1316 self._codereview_impl.CodereviewServerSettingSuffix(), |
| 1267 RunGit(['config', '--unset', setting], error_ok=True) | 1317 ] + self._PostUnsetIssueProperties() |
| 1318 for prop in reset_suffixes: |
| 1319 self._GitUnsetBranchConfigValue(prop, error_ok=True) |
| 1268 self.issue = None | 1320 self.issue = None |
| 1269 self.patchset = None | 1321 self.patchset = None |
| 1270 | 1322 |
| 1271 def GetChange(self, upstream_branch, author): | 1323 def GetChange(self, upstream_branch, author): |
| 1272 if not self.GitSanityChecks(upstream_branch): | 1324 if not self.GitSanityChecks(upstream_branch): |
| 1273 DieWithError('\nGit sanity check failure') | 1325 DieWithError('\nGit sanity check failure') |
| 1274 | 1326 |
| 1275 root = settings.GetRelativeRoot() | 1327 root = settings.GetRelativeRoot() |
| 1276 if not root: | 1328 if not root: |
| 1277 root = '.' | 1329 root = '.' |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1401 ask_for_data('About to upload; enter to confirm.') | 1453 ask_for_data('About to upload; enter to confirm.') |
| 1402 | 1454 |
| 1403 print_stats(options.similarity, options.find_copies, git_diff_args) | 1455 print_stats(options.similarity, options.find_copies, git_diff_args) |
| 1404 ret = self.CMDUploadChange(options, git_diff_args, change) | 1456 ret = self.CMDUploadChange(options, git_diff_args, change) |
| 1405 if not ret: | 1457 if not ret: |
| 1406 if options.use_commit_queue: | 1458 if options.use_commit_queue: |
| 1407 self.SetCQState(_CQState.COMMIT) | 1459 self.SetCQState(_CQState.COMMIT) |
| 1408 elif options.cq_dry_run: | 1460 elif options.cq_dry_run: |
| 1409 self.SetCQState(_CQState.DRY_RUN) | 1461 self.SetCQState(_CQState.DRY_RUN) |
| 1410 | 1462 |
| 1411 git_set_branch_value('last-upload-hash', | 1463 _git_set_branch_config_value('last-upload-hash', |
| 1412 RunGit(['rev-parse', 'HEAD']).strip()) | 1464 RunGit(['rev-parse', 'HEAD']).strip()) |
| 1413 # Run post upload hooks, if specified. | 1465 # Run post upload hooks, if specified. |
| 1414 if settings.GetRunPostUploadHook(): | 1466 if settings.GetRunPostUploadHook(): |
| 1415 presubmit_support.DoPostUploadExecuter( | 1467 presubmit_support.DoPostUploadExecuter( |
| 1416 change, | 1468 change, |
| 1417 self, | 1469 self, |
| 1418 settings.GetRoot(), | 1470 settings.GetRoot(), |
| 1419 options.verbose, | 1471 options.verbose, |
| 1420 sys.stdout) | 1472 sys.stdout) |
| 1421 | 1473 |
| 1422 # Upload all dependencies if specified. | 1474 # Upload all dependencies if specified. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1489 raise NotImplementedError() | 1541 raise NotImplementedError() |
| 1490 | 1542 |
| 1491 def GetCodereviewServer(self): | 1543 def GetCodereviewServer(self): |
| 1492 """Returns server URL without end slash, like "https://codereview.com".""" | 1544 """Returns server URL without end slash, like "https://codereview.com".""" |
| 1493 raise NotImplementedError() | 1545 raise NotImplementedError() |
| 1494 | 1546 |
| 1495 def FetchDescription(self): | 1547 def FetchDescription(self): |
| 1496 """Fetches and returns description from the codereview server.""" | 1548 """Fetches and returns description from the codereview server.""" |
| 1497 raise NotImplementedError() | 1549 raise NotImplementedError() |
| 1498 | 1550 |
| 1499 def GetCodereviewServerSetting(self): | 1551 @classmethod |
| 1500 """Returns git config setting for the codereview server.""" | 1552 def IssueSettingSuffix(cls): |
| 1553 """Returns branch setting storing issue number.""" |
| 1501 raise NotImplementedError() | 1554 raise NotImplementedError() |
| 1502 | 1555 |
| 1503 @classmethod | 1556 @classmethod |
| 1504 def IssueSetting(cls, branch): | 1557 def PatchsetSettingSuffix(cls): |
| 1505 return 'branch.%s.%s' % (branch, cls.IssueSettingSuffix()) | 1558 """Returns branch setting storing patchset number.""" |
| 1559 raise NotImplementedError() |
| 1506 | 1560 |
| 1507 @classmethod | 1561 @classmethod |
| 1508 def IssueSettingSuffix(cls): | 1562 def CodereviewServerSettingSuffix(cls): |
| 1509 """Returns name of git config setting which stores issue number for a given | 1563 """Returns branch setting storing codereview server.""" |
| 1510 branch.""" | |
| 1511 raise NotImplementedError() | |
| 1512 | |
| 1513 def PatchsetSetting(self): | |
| 1514 """Returns name of git config setting which stores issue number.""" | |
| 1515 raise NotImplementedError() | 1564 raise NotImplementedError() |
| 1516 | 1565 |
| 1517 def _PostUnsetIssueProperties(self): | 1566 def _PostUnsetIssueProperties(self): |
| 1518 """Which branch-specific properties to erase when unsettin issue.""" | 1567 """Which branch-specific properties to erase when unsettin issue.""" |
| 1519 raise NotImplementedError() | 1568 return [] |
| 1520 | 1569 |
| 1521 def GetRieveldObjForPresubmit(self): | 1570 def GetRieveldObjForPresubmit(self): |
| 1522 # This is an unfortunate Rietveld-embeddedness in presubmit. | 1571 # This is an unfortunate Rietveld-embeddedness in presubmit. |
| 1523 # For non-Rietveld codereviews, this probably should return a dummy object. | 1572 # For non-Rietveld codereviews, this probably should return a dummy object. |
| 1524 raise NotImplementedError() | 1573 raise NotImplementedError() |
| 1525 | 1574 |
| 1526 def GetGerritObjForPresubmit(self): | 1575 def GetGerritObjForPresubmit(self): |
| 1527 # None is valid return value, otherwise presubmit_support.GerritAccessor. | 1576 # None is valid return value, otherwise presubmit_support.GerritAccessor. |
| 1528 return None | 1577 return None |
| 1529 | 1578 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1596 self._rietveld_server = rietveld_server | 1645 self._rietveld_server = rietveld_server |
| 1597 self._auth_config = auth_config | 1646 self._auth_config = auth_config |
| 1598 self._props = None | 1647 self._props = None |
| 1599 self._rpc_server = None | 1648 self._rpc_server = None |
| 1600 | 1649 |
| 1601 def GetCodereviewServer(self): | 1650 def GetCodereviewServer(self): |
| 1602 if not self._rietveld_server: | 1651 if not self._rietveld_server: |
| 1603 # If we're on a branch then get the server potentially associated | 1652 # If we're on a branch then get the server potentially associated |
| 1604 # with that branch. | 1653 # with that branch. |
| 1605 if self.GetIssue(): | 1654 if self.GetIssue(): |
| 1606 rietveld_server_setting = self.GetCodereviewServerSetting() | 1655 self._rietveld_server = gclient_utils.UpgradeToHttps( |
| 1607 if rietveld_server_setting: | 1656 self._GitGetBranchConfigValue(self.CodereviewServerSettingSuffix())) |
| 1608 self._rietveld_server = gclient_utils.UpgradeToHttps(RunGit( | |
| 1609 ['config', rietveld_server_setting], error_ok=True).strip()) | |
| 1610 if not self._rietveld_server: | 1657 if not self._rietveld_server: |
| 1611 self._rietveld_server = settings.GetDefaultServerUrl() | 1658 self._rietveld_server = settings.GetDefaultServerUrl() |
| 1612 return self._rietveld_server | 1659 return self._rietveld_server |
| 1613 | 1660 |
| 1614 def EnsureAuthenticated(self, force): | 1661 def EnsureAuthenticated(self, force): |
| 1615 """Best effort check that user is authenticated with Rietveld server.""" | 1662 """Best effort check that user is authenticated with Rietveld server.""" |
| 1616 if self._auth_config.use_oauth2: | 1663 if self._auth_config.use_oauth2: |
| 1617 authenticator = auth.get_authenticator_for_host( | 1664 authenticator = auth.get_authenticator_for_host( |
| 1618 self.GetCodereviewServer(), self._auth_config) | 1665 self.GetCodereviewServer(), self._auth_config) |
| 1619 if not authenticator.has_cached_credentials(): | 1666 if not authenticator.has_cached_credentials(): |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1756 if not self._rpc_server: | 1803 if not self._rpc_server: |
| 1757 self._rpc_server = rietveld.CachingRietveld( | 1804 self._rpc_server = rietveld.CachingRietveld( |
| 1758 self.GetCodereviewServer(), | 1805 self.GetCodereviewServer(), |
| 1759 self._auth_config or auth.make_auth_config()) | 1806 self._auth_config or auth.make_auth_config()) |
| 1760 return self._rpc_server | 1807 return self._rpc_server |
| 1761 | 1808 |
| 1762 @classmethod | 1809 @classmethod |
| 1763 def IssueSettingSuffix(cls): | 1810 def IssueSettingSuffix(cls): |
| 1764 return 'rietveldissue' | 1811 return 'rietveldissue' |
| 1765 | 1812 |
| 1766 def PatchsetSetting(self): | 1813 @classmethod |
| 1767 """Return the git setting that stores this change's most recent patchset.""" | 1814 def PatchsetSettingSuffix(cls): |
| 1768 return 'branch.%s.rietveldpatchset' % self.GetBranch() | 1815 return 'rietveldpatchset' |
| 1769 | 1816 |
| 1770 def GetCodereviewServerSetting(self): | 1817 @classmethod |
| 1771 """Returns the git setting that stores this change's rietveld server.""" | 1818 def CodereviewServerSettingSuffix(cls): |
| 1772 branch = self.GetBranch() | 1819 return 'rietveldserver' |
| 1773 if branch: | |
| 1774 return 'branch.%s.rietveldserver' % branch | |
| 1775 return None | |
| 1776 | |
| 1777 def _PostUnsetIssueProperties(self): | |
| 1778 """Which branch-specific properties to erase when unsetting issue.""" | |
| 1779 return ['rietveldserver'] | |
| 1780 | 1820 |
| 1781 def GetRieveldObjForPresubmit(self): | 1821 def GetRieveldObjForPresubmit(self): |
| 1782 return self.RpcServer() | 1822 return self.RpcServer() |
| 1783 | 1823 |
| 1784 def SetCQState(self, new_state): | 1824 def SetCQState(self, new_state): |
| 1785 props = self.GetIssueProperties() | 1825 props = self.GetIssueProperties() |
| 1786 if props.get('private'): | 1826 if props.get('private'): |
| 1787 DieWithError('Cannot set-commit on private issue') | 1827 DieWithError('Cannot set-commit on private issue') |
| 1788 | 1828 |
| 1789 if new_state == _CQState.COMMIT: | 1829 if new_state == _CQState.COMMIT: |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2063 | 2103 |
| 2064 def _GetGitHost(self): | 2104 def _GetGitHost(self): |
| 2065 """Returns git host to be used when uploading change to Gerrit.""" | 2105 """Returns git host to be used when uploading change to Gerrit.""" |
| 2066 return urlparse.urlparse(self.GetRemoteUrl()).netloc | 2106 return urlparse.urlparse(self.GetRemoteUrl()).netloc |
| 2067 | 2107 |
| 2068 def GetCodereviewServer(self): | 2108 def GetCodereviewServer(self): |
| 2069 if not self._gerrit_server: | 2109 if not self._gerrit_server: |
| 2070 # If we're on a branch then get the server potentially associated | 2110 # If we're on a branch then get the server potentially associated |
| 2071 # with that branch. | 2111 # with that branch. |
| 2072 if self.GetIssue(): | 2112 if self.GetIssue(): |
| 2073 gerrit_server_setting = self.GetCodereviewServerSetting() | 2113 self._gerrit_server = self._GitGetBranchConfigValue( |
| 2074 if gerrit_server_setting: | 2114 self.CodereviewServerSettingSuffix()) |
| 2075 self._gerrit_server = RunGit(['config', gerrit_server_setting], | 2115 if self._gerrit_server: |
| 2076 error_ok=True).strip() | 2116 self._gerrit_host = urlparse.urlparse(self._gerrit_server).netloc |
| 2077 if self._gerrit_server: | |
| 2078 self._gerrit_host = urlparse.urlparse(self._gerrit_server).netloc | |
| 2079 if not self._gerrit_server: | 2117 if not self._gerrit_server: |
| 2080 # We assume repo to be hosted on Gerrit, and hence Gerrit server | 2118 # We assume repo to be hosted on Gerrit, and hence Gerrit server |
| 2081 # has "-review" suffix for lowest level subdomain. | 2119 # has "-review" suffix for lowest level subdomain. |
| 2082 parts = self._GetGitHost().split('.') | 2120 parts = self._GetGitHost().split('.') |
| 2083 parts[0] = parts[0] + '-review' | 2121 parts[0] = parts[0] + '-review' |
| 2084 self._gerrit_host = '.'.join(parts) | 2122 self._gerrit_host = '.'.join(parts) |
| 2085 self._gerrit_server = 'https://%s' % self._gerrit_host | 2123 self._gerrit_server = 'https://%s' % self._gerrit_host |
| 2086 return self._gerrit_server | 2124 return self._gerrit_server |
| 2087 | 2125 |
| 2088 @classmethod | 2126 @classmethod |
| 2089 def IssueSettingSuffix(cls): | 2127 def IssueSettingSuffix(cls): |
| 2090 return 'gerritissue' | 2128 return 'gerritissue' |
| 2091 | 2129 |
| 2130 @classmethod |
| 2131 def PatchsetSettingSuffix(cls): |
| 2132 return 'gerritpatchset' |
| 2133 |
| 2134 @classmethod |
| 2135 def CodereviewServerSettingSuffix(cls): |
| 2136 return 'gerritserver' |
| 2137 |
| 2092 def EnsureAuthenticated(self, force): | 2138 def EnsureAuthenticated(self, force): |
| 2093 """Best effort check that user is authenticated with Gerrit server.""" | 2139 """Best effort check that user is authenticated with Gerrit server.""" |
| 2094 if settings.GetGerritSkipEnsureAuthenticated(): | 2140 if settings.GetGerritSkipEnsureAuthenticated(): |
| 2095 # For projects with unusual authentication schemes. | 2141 # For projects with unusual authentication schemes. |
| 2096 # See http://crbug.com/603378. | 2142 # See http://crbug.com/603378. |
| 2097 return | 2143 return |
| 2098 # Lazy-loader to identify Gerrit and Git hosts. | 2144 # Lazy-loader to identify Gerrit and Git hosts. |
| 2099 if gerrit_util.GceAuthenticator.is_gce(): | 2145 if gerrit_util.GceAuthenticator.is_gce(): |
| 2100 return | 2146 return |
| 2101 self.GetCodereviewServer() | 2147 self.GetCodereviewServer() |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2127 [] if git_auth else [git_host]) | 2173 [] if git_auth else [git_host]) |
| 2128 DieWithError('Credentials for the following hosts are required:\n' | 2174 DieWithError('Credentials for the following hosts are required:\n' |
| 2129 ' %s\n' | 2175 ' %s\n' |
| 2130 'These are read from %s (or legacy %s)\n' | 2176 'These are read from %s (or legacy %s)\n' |
| 2131 '%s' % ( | 2177 '%s' % ( |
| 2132 '\n '.join(missing), | 2178 '\n '.join(missing), |
| 2133 cookie_auth.get_gitcookies_path(), | 2179 cookie_auth.get_gitcookies_path(), |
| 2134 cookie_auth.get_netrc_path(), | 2180 cookie_auth.get_netrc_path(), |
| 2135 cookie_auth.get_new_password_message(git_host))) | 2181 cookie_auth.get_new_password_message(git_host))) |
| 2136 | 2182 |
| 2137 | |
| 2138 def PatchsetSetting(self): | |
| 2139 """Return the git setting that stores this change's most recent patchset.""" | |
| 2140 return 'branch.%s.gerritpatchset' % self.GetBranch() | |
| 2141 | |
| 2142 def GetCodereviewServerSetting(self): | |
| 2143 """Returns the git setting that stores this change's Gerrit server.""" | |
| 2144 branch = self.GetBranch() | |
| 2145 if branch: | |
| 2146 return 'branch.%s.gerritserver' % branch | |
| 2147 return None | |
| 2148 | |
| 2149 def _PostUnsetIssueProperties(self): | 2183 def _PostUnsetIssueProperties(self): |
| 2150 """Which branch-specific properties to erase when unsetting issue.""" | 2184 """Which branch-specific properties to erase when unsetting issue.""" |
| 2151 return [ | 2185 return ['gerritsquashhash'] |
| 2152 'gerritserver', | |
| 2153 'gerritsquashhash', | |
| 2154 ] | |
| 2155 | 2186 |
| 2156 def GetRieveldObjForPresubmit(self): | 2187 def GetRieveldObjForPresubmit(self): |
| 2157 class ThisIsNotRietveldIssue(object): | 2188 class ThisIsNotRietveldIssue(object): |
| 2158 def __nonzero__(self): | 2189 def __nonzero__(self): |
| 2159 # This is a hack to make presubmit_support think that rietveld is not | 2190 # This is a hack to make presubmit_support think that rietveld is not |
| 2160 # defined, yet still ensure that calls directly result in a decent | 2191 # defined, yet still ensure that calls directly result in a decent |
| 2161 # exception message below. | 2192 # exception message below. |
| 2162 return False | 2193 return False |
| 2163 | 2194 |
| 2164 def __getattr__(self, attr): | 2195 def __getattr__(self, attr): |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2267 return 1 | 2298 return 1 |
| 2268 detail = self._GetChangeDetail(['CURRENT_REVISION', 'LABELS']) | 2299 detail = self._GetChangeDetail(['CURRENT_REVISION', 'LABELS']) |
| 2269 if u'Commit-Queue' in detail.get('labels', {}): | 2300 if u'Commit-Queue' in detail.get('labels', {}): |
| 2270 if not force: | 2301 if not force: |
| 2271 ask_for_data('\nIt seems this repository has a Commit Queue, ' | 2302 ask_for_data('\nIt seems this repository has a Commit Queue, ' |
| 2272 'which can test and land changes for you. ' | 2303 'which can test and land changes for you. ' |
| 2273 'Are you sure you wish to bypass it?\n' | 2304 'Are you sure you wish to bypass it?\n' |
| 2274 'Press Enter to continue, Ctrl+C to abort.') | 2305 'Press Enter to continue, Ctrl+C to abort.') |
| 2275 | 2306 |
| 2276 differs = True | 2307 differs = True |
| 2277 last_upload = RunGit(['config', | 2308 last_upload = RunGit(['config', self._GitBranchSetting('gerritsquashhash')], |
| 2278 'branch.%s.gerritsquashhash' % self.GetBranch()], | |
| 2279 error_ok=True).strip() | 2309 error_ok=True).strip() |
| 2280 # Note: git diff outputs nothing if there is no diff. | 2310 # Note: git diff outputs nothing if there is no diff. |
| 2281 if not last_upload or RunGit(['diff', last_upload]).strip(): | 2311 if not last_upload or RunGit(['diff', last_upload]).strip(): |
| 2282 print('WARNING: some changes from local branch haven\'t been uploaded') | 2312 print('WARNING: some changes from local branch haven\'t been uploaded') |
| 2283 else: | 2313 else: |
| 2284 if detail['current_revision'] == last_upload: | 2314 if detail['current_revision'] == last_upload: |
| 2285 differs = False | 2315 differs = False |
| 2286 else: | 2316 else: |
| 2287 print('WARNING: local branch contents differ from latest uploaded ' | 2317 print('WARNING: local branch contents differ from latest uploaded ' |
| 2288 'patchset') | 2318 'patchset') |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2571 if options.squash: | 2601 if options.squash: |
| 2572 regex = re.compile(r'remote:\s+https?://[\w\-\.\/]*/(\d+)\s.*') | 2602 regex = re.compile(r'remote:\s+https?://[\w\-\.\/]*/(\d+)\s.*') |
| 2573 change_numbers = [m.group(1) | 2603 change_numbers = [m.group(1) |
| 2574 for m in map(regex.match, push_stdout.splitlines()) | 2604 for m in map(regex.match, push_stdout.splitlines()) |
| 2575 if m] | 2605 if m] |
| 2576 if len(change_numbers) != 1: | 2606 if len(change_numbers) != 1: |
| 2577 DieWithError( | 2607 DieWithError( |
| 2578 ('Created|Updated %d issues on Gerrit, but only 1 expected.\n' | 2608 ('Created|Updated %d issues on Gerrit, but only 1 expected.\n' |
| 2579 'Change-Id: %s') % (len(change_numbers), change_id)) | 2609 'Change-Id: %s') % (len(change_numbers), change_id)) |
| 2580 self.SetIssue(change_numbers[0]) | 2610 self.SetIssue(change_numbers[0]) |
| 2581 RunGit(['config', 'branch.%s.gerritsquashhash' % self.GetBranch(), | 2611 self._GitSetBranchConfigValue('gerritsquashhash', ref_to_push) |
| 2582 ref_to_push]) | |
| 2583 return 0 | 2612 return 0 |
| 2584 | 2613 |
| 2585 def _AddChangeIdToCommitMessage(self, options, args): | 2614 def _AddChangeIdToCommitMessage(self, options, args): |
| 2586 """Re-commits using the current message, assumes the commit hook is in | 2615 """Re-commits using the current message, assumes the commit hook is in |
| 2587 place. | 2616 place. |
| 2588 """ | 2617 """ |
| 2589 log_desc = options.message or CreateDescriptionFromLog(args) | 2618 log_desc = options.message or CreateDescriptionFromLog(args) |
| 2590 git_command = ['commit', '--amend', '-m', log_desc] | 2619 git_command = ['commit', '--amend', '-m', log_desc] |
| 2591 RunGit(git_command) | 2620 RunGit(git_command) |
| 2592 new_log_desc = CreateDescriptionFromLog(args) | 2621 new_log_desc = CreateDescriptionFromLog(args) |
| (...skipping 2560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5153 if __name__ == '__main__': | 5182 if __name__ == '__main__': |
| 5154 # These affect sys.stdout so do it outside of main() to simplify mocks in | 5183 # These affect sys.stdout so do it outside of main() to simplify mocks in |
| 5155 # unit testing. | 5184 # unit testing. |
| 5156 fix_encoding.fix_encoding() | 5185 fix_encoding.fix_encoding() |
| 5157 setup_color.init() | 5186 setup_color.init() |
| 5158 try: | 5187 try: |
| 5159 sys.exit(main(sys.argv[1:])) | 5188 sys.exit(main(sys.argv[1:])) |
| 5160 except KeyboardInterrupt: | 5189 except KeyboardInterrupt: |
| 5161 sys.stderr.write('interrupted\n') | 5190 sys.stderr.write('interrupted\n') |
| 5162 sys.exit(1) | 5191 sys.exit(1) |
| OLD | NEW |