OLD | NEW |
1 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """SCM-specific utility classes.""" | 5 """SCM-specific utility classes.""" |
6 | 6 |
7 import cStringIO | 7 import cStringIO |
8 import glob | 8 import glob |
9 import logging | 9 import logging |
10 import os | 10 import os |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 GIT.Capture(['config', '--get-regexp', r'^svn-remote\.'], cwd=cwd) | 137 GIT.Capture(['config', '--get-regexp', r'^svn-remote\.'], cwd=cwd) |
138 return True | 138 return True |
139 except gclient_utils.CheckCallError: | 139 except gclient_utils.CheckCallError: |
140 return False | 140 return False |
141 | 141 |
142 @staticmethod | 142 @staticmethod |
143 def GetSVNBranch(cwd): | 143 def GetSVNBranch(cwd): |
144 """Returns the svn branch name if found.""" | 144 """Returns the svn branch name if found.""" |
145 # Try to figure out which remote branch we're based on. | 145 # Try to figure out which remote branch we're based on. |
146 # Strategy: | 146 # Strategy: |
147 # 1) find all git-svn branches and note their svn URLs. | 147 # 1) iterate through our branch history and find the svn URL. |
148 # 2) iterate through our branch history and match up the URLs. | 148 # 2) find the svn-remote that fetches from the URL. |
149 | 149 |
150 # regexp matching the git-svn line that contains the URL. | 150 # regexp matching the git-svn line that contains the URL. |
151 git_svn_re = re.compile(r'^\s*git-svn-id: (\S+)@', re.MULTILINE) | 151 git_svn_re = re.compile(r'^\s*git-svn-id: (\S+)@', re.MULTILINE) |
152 | 152 |
153 # Get the refname and svn url for all refs/remotes/*. | 153 # We don't want to go through all of history, so read a line from the |
154 remotes = GIT.Capture( | 154 # pipe at a time. |
155 ['for-each-ref', '--format=%(refname)', 'refs/remotes'], | 155 # The -100 is an arbitrary limit so we don't search forever. |
156 cwd=cwd).splitlines() | 156 cmd = ['git', 'log', '-100', '--pretty=medium'] |
157 svn_refs = {} | 157 proc = gclient_utils.Popen(cmd, stdout=subprocess.PIPE) |
158 for ref in remotes: | 158 for line in proc.stdout: |
159 match = git_svn_re.search( | 159 match = git_svn_re.match(line) |
160 GIT.Capture(['cat-file', '-p', ref], cwd=cwd)) | 160 if match: |
161 # Prefer origin/HEAD over all others. | 161 url = match.group(1) |
162 if match and (match.group(1) not in svn_refs or | 162 proc.stdout.close() # Cut pipe. |
163 ref == "refs/remotes/origin/HEAD"): | 163 break |
164 svn_refs[match.group(1)] = ref | |
165 | 164 |
166 svn_branch = '' | 165 if url: |
167 if len(svn_refs) == 1: | 166 svn_remote_re = re.compile(r'^svn-remote\.([^.]+)\.url (.*)$') |
168 # Only one svn branch exists -- seems like a good candidate. | 167 remotes = GIT.Capture(['config', '--get-regexp', |
169 svn_branch = svn_refs.values()[0] | 168 r'^svn-remote\..*\.url'], cwd=cwd).splitlines() |
170 elif len(svn_refs) > 1: | 169 for remote in remotes: |
171 # We have more than one remote branch available. We don't | 170 match = svn_remote_re.match(remote) |
172 # want to go through all of history, so read a line from the | |
173 # pipe at a time. | |
174 # The -100 is an arbitrary limit so we don't search forever. | |
175 cmd = ['git', 'log', '-100', '--pretty=medium'] | |
176 proc = gclient_utils.Popen(cmd, stdout=subprocess.PIPE, cwd=cwd) | |
177 for line in proc.stdout: | |
178 match = git_svn_re.match(line) | |
179 if match: | 171 if match: |
180 url = match.group(1) | 172 remote = match.group(1) |
181 if url in svn_refs: | 173 base_url = match.group(2) |
182 svn_branch = svn_refs[url] | 174 fetch_spec = GIT.Capture( |
183 proc.stdout.close() # Cut pipe. | 175 ['config', 'svn-remote.%s.fetch' % remote], |
184 break | 176 cwd=cwd).strip().split(':') |
185 return svn_branch | 177 if fetch_spec[0]: |
| 178 full_url = base_url + '/' + fetch_spec[0] |
| 179 else: |
| 180 full_url = base_url |
| 181 if full_url == url: |
| 182 return fetch_spec[1] |
186 | 183 |
187 @staticmethod | 184 @staticmethod |
188 def FetchUpstreamTuple(cwd): | 185 def FetchUpstreamTuple(cwd): |
189 """Returns a tuple containg remote and remote ref, | 186 """Returns a tuple containg remote and remote ref, |
190 e.g. 'origin', 'refs/heads/master' | 187 e.g. 'origin', 'refs/heads/master' |
191 Tries to be intelligent and understand git-svn. | 188 Tries to be intelligent and understand git-svn. |
192 """ | 189 """ |
193 remote = '.' | 190 remote = '.' |
194 branch = GIT.GetBranch(cwd) | 191 branch = GIT.GetBranch(cwd) |
195 try: | 192 try: |
196 upstream_branch = GIT.Capture( | 193 upstream_branch = GIT.Capture( |
197 ['config', 'branch.%s.merge' % branch], cwd=cwd).strip() | 194 ['config', 'branch.%s.merge' % branch], cwd=cwd).strip() |
198 except gclient_utils.Error: | 195 except gclient_utils.Error: |
199 upstream_branch = None | 196 upstream_branch = None |
200 if upstream_branch: | 197 if upstream_branch: |
201 try: | 198 try: |
202 remote = GIT.Capture( | 199 remote = GIT.Capture( |
203 ['config', 'branch.%s.remote' % branch], cwd=cwd).strip() | 200 ['config', 'branch.%s.remote' % branch], cwd=cwd).strip() |
204 except gclient_utils.Error: | 201 except gclient_utils.Error: |
205 pass | 202 pass |
206 else: | 203 else: |
207 # Fall back on trying a git-svn upstream branch. | 204 try: |
208 if GIT.IsGitSvn(cwd): | 205 upstream_branch = GIT.Capture( |
209 upstream_branch = GIT.GetSVNBranch(cwd) | 206 ['config', 'rietveld.upstream-branch'], cwd=cwd).strip() |
| 207 except gclient_utils.Error: |
| 208 upstream_branch = None |
| 209 if upstream_branch: |
| 210 try: |
| 211 remote = GIT.Capture( |
| 212 ['config', 'rietveld.upstream-remote'], cwd=cwd).strip() |
| 213 except gclient_utils.Error: |
| 214 pass |
210 else: | 215 else: |
211 # Else, try to guess the origin remote. | 216 # Fall back on trying a git-svn upstream branch. |
212 remote_branches = GIT.Capture(['branch', '-r'], cwd=cwd).split() | 217 if GIT.IsGitSvn(cwd): |
213 if 'origin/master' in remote_branches: | 218 upstream_branch = GIT.GetSVNBranch(cwd) |
214 # Fall back on origin/master if it exits. | |
215 remote = 'origin' | |
216 upstream_branch = 'refs/heads/master' | |
217 elif 'origin/trunk' in remote_branches: | |
218 # Fall back on origin/trunk if it exists. Generally a shared | |
219 # git-svn clone | |
220 remote = 'origin' | |
221 upstream_branch = 'refs/heads/trunk' | |
222 else: | 219 else: |
223 # Give up. | 220 # Else, try to guess the origin remote. |
224 remote = None | 221 remote_branches = GIT.Capture(['branch', '-r'], cwd=cwd).split() |
225 upstream_branch = None | 222 if 'origin/master' in remote_branches: |
| 223 # Fall back on origin/master if it exits. |
| 224 remote = 'origin' |
| 225 upstream_branch = 'refs/heads/master' |
| 226 elif 'origin/trunk' in remote_branches: |
| 227 # Fall back on origin/trunk if it exists. Generally a shared |
| 228 # git-svn clone |
| 229 remote = 'origin' |
| 230 upstream_branch = 'refs/heads/trunk' |
| 231 else: |
| 232 # Give up. |
| 233 remote = None |
| 234 upstream_branch = None |
226 return remote, upstream_branch | 235 return remote, upstream_branch |
227 | 236 |
228 @staticmethod | 237 @staticmethod |
229 def GetUpstreamBranch(cwd): | 238 def GetUpstreamBranch(cwd): |
230 """Gets the current branch's upstream branch.""" | 239 """Gets the current branch's upstream branch.""" |
231 remote, upstream_branch = GIT.FetchUpstreamTuple(cwd) | 240 remote, upstream_branch = GIT.FetchUpstreamTuple(cwd) |
232 if remote != '.' and upstream_branch: | 241 if remote != '.' and upstream_branch: |
233 upstream_branch = upstream_branch.replace('heads', 'remotes/' + remote) | 242 upstream_branch = upstream_branch.replace('heads', 'remotes/' + remote) |
234 return upstream_branch | 243 return upstream_branch |
235 | 244 |
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
880 elif os.path.isfile(file_path) or os.path.islink(file_path): | 889 elif os.path.isfile(file_path) or os.path.islink(file_path): |
881 logging.info('os.remove(%s)' % file_path) | 890 logging.info('os.remove(%s)' % file_path) |
882 os.remove(file_path) | 891 os.remove(file_path) |
883 elif os.path.isdir(file_path): | 892 elif os.path.isdir(file_path): |
884 logging.info('gclient_utils.RemoveDirectory(%s)' % file_path) | 893 logging.info('gclient_utils.RemoveDirectory(%s)' % file_path) |
885 gclient_utils.RemoveDirectory(file_path) | 894 gclient_utils.RemoveDirectory(file_path) |
886 else: | 895 else: |
887 logging.critical( | 896 logging.critical( |
888 ('No idea what is %s.\nYou just found a bug in gclient' | 897 ('No idea what is %s.\nYou just found a bug in gclient' |
889 ', please ping maruel@chromium.org ASAP!') % file_path) | 898 ', please ping maruel@chromium.org ASAP!') % file_path) |
OLD | NEW |