OLD | NEW |
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 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 import itertools | 5 import itertools |
6 import re | 6 import re |
7 | 7 |
8 from recipe_engine import recipe_api | 8 from recipe_engine import recipe_api |
9 | 9 |
10 class GitApi(recipe_api.RecipeApi): | 10 class GitApi(recipe_api.RecipeApi): |
11 _GIT_HASH_RE = re.compile('[0-9a-f]{40}', re.IGNORECASE) | 11 _GIT_HASH_RE = re.compile('[0-9a-f]{40}', re.IGNORECASE) |
12 | 12 |
13 def __init__(self, *args, **kwargs): | 13 def __init__(self, *args, **kwargs): |
14 super(GitApi, self).__init__(*args, **kwargs) | 14 super(GitApi, self).__init__(*args, **kwargs) |
15 self.initialized_win_git = False | 15 self.initialized_win_git = False |
16 | 16 |
17 def __call__(self, *args, **kwargs): | 17 def __call__(self, *args, **kwargs): |
18 """Return a git command step.""" | 18 """Return a git command step.""" |
19 name = kwargs.pop('name', 'git '+args[0]) | 19 name = kwargs.pop('name', 'git ' + args[0]) |
20 infra_step = kwargs.pop('infra_step', True) | 20 infra_step = kwargs.pop('infra_step', True) |
21 if 'cwd' not in kwargs: | 21 if 'cwd' not in kwargs: |
22 kwargs.setdefault('cwd', self.m.path['checkout']) | 22 kwargs.setdefault('cwd', self.m.path['checkout']) |
23 git_cmd = ['git'] | 23 git_cmd = ['git'] |
24 if self.m.platform.is_win: | 24 if self.m.platform.is_win: |
25 self.ensure_win_git_tooling() | 25 self.ensure_win_git_tooling() |
26 git_cmd = [self.package_repo_resource('git.bat')] | 26 git_cmd = [self.package_repo_resource('git.bat')] |
27 options = kwargs.pop('git_config_options', {}) | 27 options = kwargs.pop('git_config_options', {}) |
28 for k, v in sorted(options.iteritems()): | 28 for k, v in sorted(options.iteritems()): |
29 git_cmd.extend(['-c', '%s=%s' % (k, v)]) | 29 git_cmd.extend(['-c', '%s=%s' % (k, v)]) |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 if can_fail_build: | 126 if can_fail_build: |
127 raise recipe_api.InfraFailure('count-objects failed: %s' % ex) | 127 raise recipe_api.InfraFailure('count-objects failed: %s' % ex) |
128 return None | 128 return None |
129 | 129 |
130 def checkout(self, url, ref=None, dir_path=None, recursive=False, | 130 def checkout(self, url, ref=None, dir_path=None, recursive=False, |
131 submodules=True, submodule_update_force=False, | 131 submodules=True, submodule_update_force=False, |
132 keep_paths=None, step_suffix=None, | 132 keep_paths=None, step_suffix=None, |
133 curl_trace_file=None, can_fail_build=True, | 133 curl_trace_file=None, can_fail_build=True, |
134 set_got_revision=False, remote_name=None, | 134 set_got_revision=False, remote_name=None, |
135 display_fetch_size=None, file_name=None, | 135 display_fetch_size=None, file_name=None, |
136 submodule_update_recursive=True): | 136 submodule_update_recursive=True, |
137 """Returns an iterable of steps to perform a full git checkout. | 137 use_git_cache=False): |
| 138 """Performs a full git checkout and returns sha1 of checked out revision. |
| 139 |
138 Args: | 140 Args: |
139 url (str): url of remote repo to use as upstream | 141 url (str): url of remote repo to use as upstream |
140 ref (str): ref to fetch and check out | 142 ref (str): ref to fetch and check out |
141 dir_path (Path): optional directory to clone into | 143 dir_path (Path): optional directory to clone into |
142 recursive (bool): whether to recursively fetch submodules or not | 144 recursive (bool): whether to recursively fetch submodules or not |
143 submodules (bool): whether to sync and update submodules or not | 145 submodules (bool): whether to sync and update submodules or not |
144 submodule_update_force (bool): whether to update submodules with --force | 146 submodule_update_force (bool): whether to update submodules with --force |
145 keep_paths (iterable of strings): paths to ignore during git-clean; | 147 keep_paths (iterable of strings): paths to ignore during git-clean; |
146 paths are gitignore-style patterns relative to checkout_path. | 148 paths are gitignore-style patterns relative to checkout_path. |
147 step_suffix (str): suffix to add to a each step name | 149 step_suffix (str): suffix to add to a each step name |
148 curl_trace_file (Path): if not None, dump GIT_CURL_VERBOSE=1 trace to that | 150 curl_trace_file (Path): if not None, dump GIT_CURL_VERBOSE=1 trace to that |
149 file. Useful for debugging git issue reproducible only on bots. It has | 151 file. Useful for debugging git issue reproducible only on bots. It has |
150 a side effect of all stderr output of 'git fetch' going to that file. | 152 a side effect of all stderr output of 'git fetch' going to that file. |
151 can_fail_build (bool): if False, ignore errors during fetch or checkout. | 153 can_fail_build (bool): if False, ignore errors during fetch or checkout. |
152 set_got_revision (bool): if True, resolves HEAD and sets got_revision | 154 set_got_revision (bool): if True, resolves HEAD and sets got_revision |
153 property. | 155 property. |
154 remote_name (str): name of the git remote to use | 156 remote_name (str): name of the git remote to use |
155 display_fetch_size (bool): if True, run `git count-objects` before and | 157 display_fetch_size (bool): if True, run `git count-objects` before and |
156 after fetch and display delta. Adds two more steps. Defaults to False. | 158 after fetch and display delta. Adds two more steps. Defaults to False. |
157 file_name (str): optional path to a single file to checkout. | 159 file_name (str): optional path to a single file to checkout. |
158 submodule_update_recursive (bool): if True, updates submodules | 160 submodule_update_recursive (bool): if True, updates submodules |
159 recursively. | 161 recursively. |
| 162 use_git_cache (bool): if True, git cache will be used for this checkout. |
| 163 WARNING, this is EXPERIMENTAL!!! This wasn't tested with: |
| 164 * submodules |
| 165 * since origin url is modified |
| 166 to a local path, may cause problem with scripts that do |
| 167 "git fetch origin" or "git push origin". |
| 168 * arbitrary refs such refs/whatever/not-fetched-by-default-to-cache |
160 | 169 |
161 Returns: If the checkout was successful, this returns the commit hash of | 170 Returns: If the checkout was successful, this returns the commit hash of |
162 the checked-out-repo. Otherwise this returns None. | 171 the checked-out-repo. Otherwise this returns None. |
163 """ | 172 """ |
164 retVal = None | 173 retVal = None |
165 | 174 |
166 # TODO(robertocn): Break this function and refactor calls to it. | 175 # TODO(robertocn): Break this function and refactor calls to it. |
167 # The problem is that there are way too many unrealated use cases for | 176 # The problem is that there are way too many unrealated use cases for |
168 # it, and the function's signature is getting unwieldy and its body | 177 # it, and the function's signature is getting unwieldy and its body |
169 # unreadable. | 178 # unreadable. |
(...skipping 22 matching lines...) Expand all Loading... |
192 self.ensure_win_git_tooling() | 201 self.ensure_win_git_tooling() |
193 git_setup_args += [ | 202 git_setup_args += [ |
194 '--git_cmd_path', self.package_repo_resource('git.bat')] | 203 '--git_cmd_path', self.package_repo_resource('git.bat')] |
195 | 204 |
196 step_suffix = '' if step_suffix is None else ' (%s)' % step_suffix | 205 step_suffix = '' if step_suffix is None else ' (%s)' % step_suffix |
197 self.m.python( | 206 self.m.python( |
198 'git setup%s' % step_suffix, | 207 'git setup%s' % step_suffix, |
199 self.resource('git_setup.py'), | 208 self.resource('git_setup.py'), |
200 git_setup_args) | 209 git_setup_args) |
201 | 210 |
| 211 if use_git_cache: |
| 212 self('retry', 'cache', 'fetch', '-c', self.m.path['git_cache'], |
| 213 cwd=dir_path, |
| 214 name='fetch cache', |
| 215 can_fail_build=can_fail_build) |
| 216 |
202 # There are five kinds of refs we can be handed: | 217 # There are five kinds of refs we can be handed: |
203 # 0) None. In this case, we default to properties['branch']. | 218 # 0) None. In this case, we default to properties['branch']. |
204 # 1) A 40-character SHA1 hash. | 219 # 1) A 40-character SHA1 hash. |
205 # 2) A fully-qualifed arbitrary ref, e.g. 'refs/foo/bar/baz'. | 220 # 2) A fully-qualifed arbitrary ref, e.g. 'refs/foo/bar/baz'. |
206 # 3) A fully qualified branch name, e.g. 'refs/heads/master'. | 221 # 3) A fully qualified branch name, e.g. 'refs/heads/master'. |
207 # Chop off 'refs/heads' and now it matches case (4). | 222 # Chop off 'refs/heads' and now it matches case (4). |
208 # 4) A branch name, e.g. 'master'. | 223 # 4) A branch name, e.g. 'master'. |
209 # Note that 'FETCH_HEAD' can be many things (and therefore not a valid | 224 # Note that 'FETCH_HEAD' can be many things (and therefore not a valid |
210 # checkout target) if many refs are fetched, but we only explicitly fetch | 225 # checkout target) if many refs are fetched, but we only explicitly fetch |
211 # one ref here, so this is safe. | 226 # one ref here, so this is safe. |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 | 384 |
370 Args: | 385 Args: |
371 bundle_path (Path): The path of the output bundle. | 386 bundle_path (Path): The path of the output bundle. |
372 refs (list): The list of refs to include in the bundle. If None, all | 387 refs (list): The list of refs to include in the bundle. If None, all |
373 refs in the Git checkout will be bundled. | 388 refs in the Git checkout will be bundled. |
374 kwargs: Forwarded to '__call__'. | 389 kwargs: Forwarded to '__call__'. |
375 """ | 390 """ |
376 if not rev_list_args: | 391 if not rev_list_args: |
377 rev_list_args = ['--all'] | 392 rev_list_args = ['--all'] |
378 self('bundle', 'create', bundle_path, *rev_list_args, **kwargs) | 393 self('bundle', 'create', bundle_path, *rev_list_args, **kwargs) |
OLD | NEW |