Show More
@@ -35,6 +35,7 b' import urllib' | |||||
35 | import urlobject |
|
35 | import urlobject | |
36 | import uuid |
|
36 | import uuid | |
37 | import getpass |
|
37 | import getpass | |
|
38 | from functools import update_wrapper, partial | |||
38 |
|
39 | |||
39 | import pygments.lexers |
|
40 | import pygments.lexers | |
40 | import sqlalchemy |
|
41 | import sqlalchemy | |
@@ -1027,3 +1028,43 b' def parse_byte_string(size_str):' | |||||
1027 | _parts = match.groups() |
|
1028 | _parts = match.groups() | |
1028 | num, type_ = _parts |
|
1029 | num, type_ = _parts | |
1029 | return long(num) * {'mb': 1024*1024, 'kb': 1024}[type_.lower()] |
|
1030 | return long(num) * {'mb': 1024*1024, 'kb': 1024}[type_.lower()] | |
|
1031 | ||||
|
1032 | ||||
|
1033 | class CachedProperty(object): | |||
|
1034 | """ | |||
|
1035 | Lazy Attributes. With option to invalidate the cache by running a method | |||
|
1036 | ||||
|
1037 | class Foo(): | |||
|
1038 | ||||
|
1039 | @CachedProperty | |||
|
1040 | def heavy_func(): | |||
|
1041 | return 'super-calculation' | |||
|
1042 | ||||
|
1043 | foo = Foo() | |||
|
1044 | foo.heavy_func() # first computions | |||
|
1045 | foo.heavy_func() # fetch from cache | |||
|
1046 | foo._invalidate_prop_cache('heavy_func') | |||
|
1047 | # at this point calling foo.heavy_func() will be re-computed | |||
|
1048 | """ | |||
|
1049 | ||||
|
1050 | def __init__(self, func, func_name=None): | |||
|
1051 | ||||
|
1052 | if func_name is None: | |||
|
1053 | func_name = func.__name__ | |||
|
1054 | self.data = (func, func_name) | |||
|
1055 | update_wrapper(self, func) | |||
|
1056 | ||||
|
1057 | def __get__(self, inst, class_): | |||
|
1058 | if inst is None: | |||
|
1059 | return self | |||
|
1060 | ||||
|
1061 | func, func_name = self.data | |||
|
1062 | value = func(inst) | |||
|
1063 | inst.__dict__[func_name] = value | |||
|
1064 | if '_invalidate_prop_cache' not in inst.__dict__: | |||
|
1065 | inst.__dict__['_invalidate_prop_cache'] = partial( | |||
|
1066 | self._invalidate_prop_cache, inst) | |||
|
1067 | return value | |||
|
1068 | ||||
|
1069 | def _invalidate_prop_cache(self, inst, name): | |||
|
1070 | inst.__dict__.pop(name, None) |
@@ -33,12 +33,12 b' import collections' | |||||
33 | import warnings |
|
33 | import warnings | |
34 |
|
34 | |||
35 | from zope.cachedescriptors.property import Lazy as LazyProperty |
|
35 | from zope.cachedescriptors.property import Lazy as LazyProperty | |
36 | from zope.cachedescriptors.property import CachedProperty |
|
|||
37 |
|
36 | |||
38 | from pyramid import compat |
|
37 | from pyramid import compat | |
39 |
|
38 | |||
|
39 | import rhodecode | |||
40 | from rhodecode.translation import lazy_ugettext |
|
40 | from rhodecode.translation import lazy_ugettext | |
41 | from rhodecode.lib.utils2 import safe_str, safe_unicode |
|
41 | from rhodecode.lib.utils2 import safe_str, safe_unicode, CachedProperty | |
42 | from rhodecode.lib.vcs import connection |
|
42 | from rhodecode.lib.vcs import connection | |
43 | from rhodecode.lib.vcs.utils import author_name, author_email |
|
43 | from rhodecode.lib.vcs.utils import author_name, author_email | |
44 | from rhodecode.lib.vcs.conf import settings |
|
44 | from rhodecode.lib.vcs.conf import settings | |
@@ -264,7 +264,9 b' class BaseRepository(object):' | |||||
264 | EMPTY_COMMIT_ID = '0' * 40 |
|
264 | EMPTY_COMMIT_ID = '0' * 40 | |
265 |
|
265 | |||
266 | path = None |
|
266 | path = None | |
267 | _commit_ids_ver = 0 |
|
267 | ||
|
268 | _is_empty = None | |||
|
269 | _commit_ids = {} | |||
268 |
|
270 | |||
269 | def __init__(self, repo_path, config=None, create=False, **kwargs): |
|
271 | def __init__(self, repo_path, config=None, create=False, **kwargs): | |
270 | """ |
|
272 | """ | |
@@ -386,8 +388,23 b' class BaseRepository(object):' | |||||
386 | commit = self.get_commit(commit_id) |
|
388 | commit = self.get_commit(commit_id) | |
387 | return commit.size |
|
389 | return commit.size | |
388 |
|
390 | |||
|
391 | def _check_for_empty(self): | |||
|
392 | no_commits = len(self._commit_ids) == 0 | |||
|
393 | if no_commits: | |||
|
394 | # check on remote to be sure | |||
|
395 | return self._remote.is_empty() | |||
|
396 | else: | |||
|
397 | return False | |||
|
398 | ||||
389 | def is_empty(self): |
|
399 | def is_empty(self): | |
390 | return self._remote.is_empty() |
|
400 | if rhodecode.is_test: | |
|
401 | return self._check_for_empty() | |||
|
402 | ||||
|
403 | if self._is_empty is None: | |||
|
404 | # cache empty for production, but not tests | |||
|
405 | self._is_empty = self._check_for_empty() | |||
|
406 | ||||
|
407 | return self._is_empty | |||
391 |
|
408 | |||
392 | @staticmethod |
|
409 | @staticmethod | |
393 | def check_url(url, config): |
|
410 | def check_url(url, config): | |
@@ -408,14 +425,15 b' class BaseRepository(object):' | |||||
408 | # COMMITS |
|
425 | # COMMITS | |
409 | # ========================================================================== |
|
426 | # ========================================================================== | |
410 |
|
427 | |||
411 |
@CachedProperty |
|
428 | @CachedProperty | |
412 | def commit_ids(self): |
|
429 | def commit_ids(self): | |
413 | raise NotImplementedError |
|
430 | raise NotImplementedError | |
414 |
|
431 | |||
415 | def append_commit_id(self, commit_id): |
|
432 | def append_commit_id(self, commit_id): | |
416 | if commit_id not in self.commit_ids: |
|
433 | if commit_id not in self.commit_ids: | |
417 | self._rebuild_cache(self.commit_ids + [commit_id]) |
|
434 | self._rebuild_cache(self.commit_ids + [commit_id]) | |
418 | self._commit_ids_ver = time.time() |
|
435 | # clear cache | |
|
436 | self._invalidate_prop_cache('commit_ids') | |||
419 |
|
437 | |||
420 | def get_commit(self, commit_id=None, commit_idx=None, pre_load=None, translate_tag=None): |
|
438 | def get_commit(self, commit_id=None, commit_idx=None, pre_load=None, translate_tag=None): | |
421 | """ |
|
439 | """ |
@@ -46,12 +46,6 b' class GitCommit(base.BaseCommit):' | |||||
46 | """ |
|
46 | """ | |
47 | Represents state of the repository at single commit id. |
|
47 | Represents state of the repository at single commit id. | |
48 | """ |
|
48 | """ | |
49 | _author_property = 'author' |
|
|||
50 | _committer_property = 'committer' |
|
|||
51 | _date_property = 'commit_time' |
|
|||
52 | _date_tz_property = 'commit_timezone' |
|
|||
53 | _message_property = 'message' |
|
|||
54 | _parents_property = 'parents' |
|
|||
55 |
|
49 | |||
56 | _filter_pre_load = [ |
|
50 | _filter_pre_load = [ | |
57 | # done through a more complex tree walk on parents |
|
51 | # done through a more complex tree walk on parents | |
@@ -124,23 +118,19 b' class GitCommit(base.BaseCommit):' | |||||
124 |
|
118 | |||
125 | @LazyProperty |
|
119 | @LazyProperty | |
126 | def message(self): |
|
120 | def message(self): | |
127 | return safe_unicode( |
|
121 | return safe_unicode(self._remote.message(self.id)) | |
128 | self._remote.commit_attribute(self.id, self._message_property)) |
|
|||
129 |
|
122 | |||
130 | @LazyProperty |
|
123 | @LazyProperty | |
131 | def committer(self): |
|
124 | def committer(self): | |
132 | return safe_unicode( |
|
125 | return safe_unicode(self._remote.author(self.id)) | |
133 | self._remote.commit_attribute(self.id, self._committer_property)) |
|
|||
134 |
|
126 | |||
135 | @LazyProperty |
|
127 | @LazyProperty | |
136 | def author(self): |
|
128 | def author(self): | |
137 | return safe_unicode( |
|
129 | return safe_unicode(self._remote.author(self.id)) | |
138 | self._remote.commit_attribute(self.id, self._author_property)) |
|
|||
139 |
|
130 | |||
140 | @LazyProperty |
|
131 | @LazyProperty | |
141 | def date(self): |
|
132 | def date(self): | |
142 |
unix_ts, tz = self._remote. |
|
133 | unix_ts, tz = self._remote.date(self.raw_id) | |
143 | self.raw_id, self._date_property, self._date_tz_property) |
|
|||
144 | return utcdate_fromtimestamp(unix_ts, tz) |
|
134 | return utcdate_fromtimestamp(unix_ts, tz) | |
145 |
|
135 | |||
146 | @LazyProperty |
|
136 | @LazyProperty | |
@@ -158,13 +148,23 b' class GitCommit(base.BaseCommit):' | |||||
158 | return tags |
|
148 | return tags | |
159 |
|
149 | |||
160 | @LazyProperty |
|
150 | @LazyProperty | |
161 | def branch(self): |
|
151 | def commit_branches(self): | |
|
152 | branches = [] | |||
162 | for name, commit_id in self.repository.branches.iteritems(): |
|
153 | for name, commit_id in self.repository.branches.iteritems(): | |
163 | if commit_id == self.raw_id: |
|
154 | if commit_id == self.raw_id: | |
164 |
|
|
155 | branches.append(name) | |
|
156 | return branches | |||
|
157 | ||||
|
158 | @LazyProperty | |||
|
159 | def branch(self): | |||
|
160 | # actually commit can have multiple branches | |||
|
161 | branches = self.commit_branches | |||
|
162 | if branches: | |||
|
163 | return branches[0] | |||
|
164 | ||||
165 | return None |
|
165 | return None | |
166 |
|
166 | |||
167 | def _get_id_for_path(self, path): |
|
167 | def _get_tree_id_for_path(self, path): | |
168 | path = safe_str(path) |
|
168 | path = safe_str(path) | |
169 | if path in self._paths: |
|
169 | if path in self._paths: | |
170 | return self._paths[path] |
|
170 | return self._paths[path] | |
@@ -177,56 +177,26 b' class GitCommit(base.BaseCommit):' | |||||
177 | self._paths[''] = data |
|
177 | self._paths[''] = data | |
178 | return data |
|
178 | return data | |
179 |
|
179 | |||
180 | parts = path.split('/') |
|
180 | tree_id, tree_type, tree_mode = \ | |
181 | dirs, name = parts[:-1], parts[-1] |
|
181 | self._remote.tree_and_type_for_path(self.raw_id, path) | |
182 | cur_dir = '' |
|
182 | if tree_id is None: | |
183 |
|
183 | raise self.no_node_at_path(path) | ||
184 | # initially extract things from root dir |
|
|||
185 | tree_items = self._remote.tree_items(tree_id) |
|
|||
186 | self._process_tree_items(tree_items, cur_dir) |
|
|||
187 |
|
184 | |||
188 | for dir in dirs: |
|
185 | self._paths[path] = [tree_id, tree_type] | |
189 | if cur_dir: |
|
186 | self._stat_modes[path] = tree_mode | |
190 | cur_dir = '/'.join((cur_dir, dir)) |
|
|||
191 | else: |
|
|||
192 | cur_dir = dir |
|
|||
193 | dir_id = None |
|
|||
194 | for item, stat_, id_, type_ in tree_items: |
|
|||
195 | if item == dir: |
|
|||
196 | dir_id = id_ |
|
|||
197 | break |
|
|||
198 | if dir_id: |
|
|||
199 | if type_ != "tree": |
|
|||
200 | raise CommitError('%s is not a directory' % cur_dir) |
|
|||
201 | # update tree |
|
|||
202 | tree_items = self._remote.tree_items(dir_id) |
|
|||
203 | else: |
|
|||
204 | raise CommitError('%s have not been found' % cur_dir) |
|
|||
205 |
|
||||
206 | # cache all items from the given traversed tree |
|
|||
207 | self._process_tree_items(tree_items, cur_dir) |
|
|||
208 |
|
187 | |||
209 | if path not in self._paths: |
|
188 | if path not in self._paths: | |
210 | raise self.no_node_at_path(path) |
|
189 | raise self.no_node_at_path(path) | |
211 |
|
190 | |||
212 | return self._paths[path] |
|
191 | return self._paths[path] | |
213 |
|
192 | |||
214 | def _process_tree_items(self, items, cur_dir): |
|
|||
215 | for item, stat_, id_, type_ in items: |
|
|||
216 | if cur_dir: |
|
|||
217 | name = '/'.join((cur_dir, item)) |
|
|||
218 | else: |
|
|||
219 | name = item |
|
|||
220 | self._paths[name] = [id_, type_] |
|
|||
221 | self._stat_modes[name] = stat_ |
|
|||
222 |
|
||||
223 | def _get_kind(self, path): |
|
193 | def _get_kind(self, path): | |
224 |
|
|
194 | tree_id, type_ = self._get_tree_id_for_path(path) | |
225 | if type_ == 'blob': |
|
195 | if type_ == 'blob': | |
226 | return NodeKind.FILE |
|
196 | return NodeKind.FILE | |
227 | elif type_ == 'tree': |
|
197 | elif type_ == 'tree': | |
228 | return NodeKind.DIR |
|
198 | return NodeKind.DIR | |
229 | elif type == 'link': |
|
199 | elif type_ == 'link': | |
230 | return NodeKind.SUBMODULE |
|
200 | return NodeKind.SUBMODULE | |
231 | return None |
|
201 | return None | |
232 |
|
202 | |||
@@ -245,8 +215,7 b' class GitCommit(base.BaseCommit):' | |||||
245 | """ |
|
215 | """ | |
246 | Returns list of parent commits. |
|
216 | Returns list of parent commits. | |
247 | """ |
|
217 | """ | |
248 |
parent_ids = self._remote. |
|
218 | parent_ids = self._remote.parents(self.id) | |
249 | self.id, self._parents_property) |
|
|||
250 | return self._make_commits(parent_ids) |
|
219 | return self._make_commits(parent_ids) | |
251 |
|
220 | |||
252 | @LazyProperty |
|
221 | @LazyProperty | |
@@ -266,11 +235,11 b' class GitCommit(base.BaseCommit):' | |||||
266 | child_ids.extend(found_ids) |
|
235 | child_ids.extend(found_ids) | |
267 | return self._make_commits(child_ids) |
|
236 | return self._make_commits(child_ids) | |
268 |
|
237 | |||
269 |
def _make_commits(self, commit_ids |
|
238 | def _make_commits(self, commit_ids): | |
270 | return [ |
|
239 | def commit_maker(_commit_id): | |
271 |
self.repository.get_commit(commit_id=commit_id |
|
240 | return self.repository.get_commit(commit_id=commit_id) | |
272 | translate_tag=False) |
|
241 | ||
273 |
|
|
242 | return [commit_maker(commit_id) for commit_id in commit_ids] | |
274 |
|
243 | |||
275 | def get_file_mode(self, path): |
|
244 | def get_file_mode(self, path): | |
276 | """ |
|
245 | """ | |
@@ -278,7 +247,7 b' class GitCommit(base.BaseCommit):' | |||||
278 | """ |
|
247 | """ | |
279 | path = safe_str(path) |
|
248 | path = safe_str(path) | |
280 | # ensure path is traversed |
|
249 | # ensure path is traversed | |
281 | self._get_id_for_path(path) |
|
250 | self._get_tree_id_for_path(path) | |
282 | return self._stat_modes[path] |
|
251 | return self._stat_modes[path] | |
283 |
|
252 | |||
284 | def is_link(self, path): |
|
253 | def is_link(self, path): | |
@@ -288,15 +257,15 b' class GitCommit(base.BaseCommit):' | |||||
288 | """ |
|
257 | """ | |
289 | Returns content of the file at given `path`. |
|
258 | Returns content of the file at given `path`. | |
290 | """ |
|
259 | """ | |
291 |
id |
|
260 | tree_id, _ = self._get_tree_id_for_path(path) | |
292 |
return self._remote.blob_as_pretty_string(id |
|
261 | return self._remote.blob_as_pretty_string(tree_id) | |
293 |
|
262 | |||
294 | def get_file_size(self, path): |
|
263 | def get_file_size(self, path): | |
295 | """ |
|
264 | """ | |
296 | Returns size of the file at given `path`. |
|
265 | Returns size of the file at given `path`. | |
297 | """ |
|
266 | """ | |
298 |
id |
|
267 | tree_id, _ = self._get_tree_id_for_path(path) | |
299 |
return self._remote.blob_raw_length(id |
|
268 | return self._remote.blob_raw_length(tree_id) | |
300 |
|
269 | |||
301 | def get_path_history(self, path, limit=None, pre_load=None): |
|
270 | def get_path_history(self, path, limit=None, pre_load=None): | |
302 | """ |
|
271 | """ | |
@@ -350,20 +319,23 b' class GitCommit(base.BaseCommit):' | |||||
350 | line) |
|
319 | line) | |
351 |
|
320 | |||
352 | def get_nodes(self, path): |
|
321 | def get_nodes(self, path): | |
|
322 | ||||
353 | if self._get_kind(path) != NodeKind.DIR: |
|
323 | if self._get_kind(path) != NodeKind.DIR: | |
354 | raise CommitError( |
|
324 | raise CommitError( | |
355 | "Directory does not exist for commit %s at '%s'" % (self.raw_id, path)) |
|
325 | "Directory does not exist for commit %s at '%s'" % (self.raw_id, path)) | |
356 | path = self._fix_path(path) |
|
326 | path = self._fix_path(path) | |
357 | id_, _ = self._get_id_for_path(path) |
|
327 | ||
358 |
tree_id = self._ |
|
328 | tree_id, _ = self._get_tree_id_for_path(path) | |
|
329 | ||||
359 | dirnodes = [] |
|
330 | dirnodes = [] | |
360 | filenodes = [] |
|
331 | filenodes = [] | |
361 | alias = self.repository.alias |
|
332 | ||
|
333 | # extracted tree ID gives us our files... | |||
362 | for name, stat_, id_, type_ in self._remote.tree_items(tree_id): |
|
334 | for name, stat_, id_, type_ in self._remote.tree_items(tree_id): | |
363 | if type_ == 'link': |
|
335 | if type_ == 'link': | |
364 | url = self._get_submodule_url('/'.join((path, name))) |
|
336 | url = self._get_submodule_url('/'.join((path, name))) | |
365 | dirnodes.append(SubModuleNode( |
|
337 | dirnodes.append(SubModuleNode( | |
366 | name, url=url, commit=id_, alias=alias)) |
|
338 | name, url=url, commit=id_, alias=self.repository.alias)) | |
367 | continue |
|
339 | continue | |
368 |
|
340 | |||
369 | if path != '': |
|
341 | if path != '': | |
@@ -394,7 +366,7 b' class GitCommit(base.BaseCommit):' | |||||
394 | path = self._fix_path(path) |
|
366 | path = self._fix_path(path) | |
395 | if path not in self.nodes: |
|
367 | if path not in self.nodes: | |
396 | try: |
|
368 | try: | |
397 |
id |
|
369 | tree_id, type_ = self._get_tree_id_for_path(path) | |
398 | except CommitError: |
|
370 | except CommitError: | |
399 | raise NodeDoesNotExistError( |
|
371 | raise NodeDoesNotExistError( | |
400 | "Cannot find one of parents' directories for a given " |
|
372 | "Cannot find one of parents' directories for a given " | |
@@ -402,7 +374,7 b' class GitCommit(base.BaseCommit):' | |||||
402 |
|
374 | |||
403 | if type_ == 'link': |
|
375 | if type_ == 'link': | |
404 | url = self._get_submodule_url(path) |
|
376 | url = self._get_submodule_url(path) | |
405 |
node = SubModuleNode(path, url=url, commit=id |
|
377 | node = SubModuleNode(path, url=url, commit=tree_id, | |
406 | alias=self.repository.alias) |
|
378 | alias=self.repository.alias) | |
407 | elif type_ == 'tree': |
|
379 | elif type_ == 'tree': | |
408 | if path == '': |
|
380 | if path == '': | |
@@ -411,16 +383,18 b' class GitCommit(base.BaseCommit):' | |||||
411 | node = DirNode(path, commit=self) |
|
383 | node = DirNode(path, commit=self) | |
412 | elif type_ == 'blob': |
|
384 | elif type_ == 'blob': | |
413 | node = FileNode(path, commit=self, pre_load=pre_load) |
|
385 | node = FileNode(path, commit=self, pre_load=pre_load) | |
|
386 | self._stat_modes[path] = node.mode | |||
414 | else: |
|
387 | else: | |
415 | raise self.no_node_at_path(path) |
|
388 | raise self.no_node_at_path(path) | |
416 |
|
389 | |||
417 | # cache node |
|
390 | # cache node | |
418 | self.nodes[path] = node |
|
391 | self.nodes[path] = node | |
|
392 | ||||
419 | return self.nodes[path] |
|
393 | return self.nodes[path] | |
420 |
|
394 | |||
421 | def get_largefile_node(self, path): |
|
395 | def get_largefile_node(self, path): | |
422 |
id |
|
396 | tree_id, _ = self._get_tree_id_for_path(path) | |
423 |
pointer_spec = self._remote.is_large_file(id |
|
397 | pointer_spec = self._remote.is_large_file(tree_id) | |
424 |
|
398 | |||
425 | if pointer_spec: |
|
399 | if pointer_spec: | |
426 | # content of that file regular FileNode is the hash of largefile |
|
400 | # content of that file regular FileNode is the hash of largefile |
@@ -25,15 +25,14 b' GIT repository module' | |||||
25 | import logging |
|
25 | import logging | |
26 | import os |
|
26 | import os | |
27 | import re |
|
27 | import re | |
28 | import time |
|
|||
29 |
|
28 | |||
30 | from zope.cachedescriptors.property import Lazy as LazyProperty |
|
29 | from zope.cachedescriptors.property import Lazy as LazyProperty | |
31 | from zope.cachedescriptors.property import CachedProperty |
|
|||
32 |
|
30 | |||
33 | from rhodecode.lib.compat import OrderedDict |
|
31 | from rhodecode.lib.compat import OrderedDict | |
34 | from rhodecode.lib.datelib import ( |
|
32 | from rhodecode.lib.datelib import ( | |
35 | utcdate_fromtimestamp, makedate, date_astimestamp) |
|
33 | utcdate_fromtimestamp, makedate, date_astimestamp) | |
36 | from rhodecode.lib.utils import safe_unicode, safe_str |
|
34 | from rhodecode.lib.utils import safe_unicode, safe_str | |
|
35 | from rhodecode.lib.utils2 import CachedProperty | |||
37 | from rhodecode.lib.vcs import connection, path as vcspath |
|
36 | from rhodecode.lib.vcs import connection, path as vcspath | |
38 | from rhodecode.lib.vcs.backends.base import ( |
|
37 | from rhodecode.lib.vcs.backends.base import ( | |
39 | BaseRepository, CollectionGenerator, Config, MergeResponse, |
|
38 | BaseRepository, CollectionGenerator, Config, MergeResponse, | |
@@ -71,9 +70,6 b' class GitRepository(BaseRepository):' | |||||
71 | # caches |
|
70 | # caches | |
72 | self._commit_ids = {} |
|
71 | self._commit_ids = {} | |
73 |
|
72 | |||
74 | # dependent that trigger re-computation of commit_ids |
|
|||
75 | self._commit_ids_ver = 0 |
|
|||
76 |
|
||||
77 | @LazyProperty |
|
73 | @LazyProperty | |
78 | def _remote(self): |
|
74 | def _remote(self): | |
79 | return connection.Git(self.path, self.config, with_wire=self.with_wire) |
|
75 | return connection.Git(self.path, self.config, with_wire=self.with_wire) | |
@@ -86,7 +82,7 b' class GitRepository(BaseRepository):' | |||||
86 | def head(self): |
|
82 | def head(self): | |
87 | return self._remote.head() |
|
83 | return self._remote.head() | |
88 |
|
84 | |||
89 |
@CachedProperty |
|
85 | @CachedProperty | |
90 | def commit_ids(self): |
|
86 | def commit_ids(self): | |
91 | """ |
|
87 | """ | |
92 | Returns list of commit ids, in ascending order. Being lazy |
|
88 | Returns list of commit ids, in ascending order. Being lazy | |
@@ -190,12 +186,16 b' class GitRepository(BaseRepository):' | |||||
190 | except OSError as err: |
|
186 | except OSError as err: | |
191 | raise RepositoryError(err) |
|
187 | raise RepositoryError(err) | |
192 |
|
188 | |||
193 |
def _get_all_commit_ids(self |
|
189 | def _get_all_commit_ids(self): | |
|
190 | return self._remote.get_all_commit_ids() | |||
|
191 | ||||
|
192 | def _get_commit_ids(self, filters=None): | |||
194 | # we must check if this repo is not empty, since later command |
|
193 | # we must check if this repo is not empty, since later command | |
195 | # fails if it is. And it's cheaper to ask than throw the subprocess |
|
194 | # fails if it is. And it's cheaper to ask than throw the subprocess | |
196 | # errors |
|
195 | # errors | |
197 |
|
196 | |||
198 | head = self._remote.head(show_exc=False) |
|
197 | head = self._remote.head(show_exc=False) | |
|
198 | ||||
199 | if not head: |
|
199 | if not head: | |
200 | return [] |
|
200 | return [] | |
201 |
|
201 | |||
@@ -208,7 +208,7 b' class GitRepository(BaseRepository):' | |||||
208 | if filters.get('until'): |
|
208 | if filters.get('until'): | |
209 | extra_filter.append('--until=%s' % (filters['until'])) |
|
209 | extra_filter.append('--until=%s' % (filters['until'])) | |
210 | if filters.get('branch_name'): |
|
210 | if filters.get('branch_name'): | |
211 |
rev_filter = [ |
|
211 | rev_filter = [] | |
212 | extra_filter.append(filters['branch_name']) |
|
212 | extra_filter.append(filters['branch_name']) | |
213 | rev_filter.extend(extra_filter) |
|
213 | rev_filter.extend(extra_filter) | |
214 |
|
214 | |||
@@ -233,6 +233,8 b' class GitRepository(BaseRepository):' | |||||
233 |
|
233 | |||
234 | if commit_id_or_idx in (None, '', 'tip', 'HEAD', 'head', -1): |
|
234 | if commit_id_or_idx in (None, '', 'tip', 'HEAD', 'head', -1): | |
235 | return self.commit_ids[-1] |
|
235 | return self.commit_ids[-1] | |
|
236 | commit_missing_err = "Commit {} does not exist for `{}`".format( | |||
|
237 | *map(safe_str, [commit_id_or_idx, self.name])) | |||
236 |
|
238 | |||
237 | is_bstr = isinstance(commit_id_or_idx, (str, unicode)) |
|
239 | is_bstr = isinstance(commit_id_or_idx, (str, unicode)) | |
238 | if ((is_bstr and commit_id_or_idx.isdigit() and len(commit_id_or_idx) < 12) |
|
240 | if ((is_bstr and commit_id_or_idx.isdigit() and len(commit_id_or_idx) < 12) | |
@@ -240,30 +242,15 b' class GitRepository(BaseRepository):' | |||||
240 | try: |
|
242 | try: | |
241 | commit_id_or_idx = self.commit_ids[int(commit_id_or_idx)] |
|
243 | commit_id_or_idx = self.commit_ids[int(commit_id_or_idx)] | |
242 | except Exception: |
|
244 | except Exception: | |
243 | msg = "Commit {} does not exist for `{}`".format(commit_id_or_idx, self.name) |
|
245 | raise CommitDoesNotExistError(commit_missing_err) | |
244 | raise CommitDoesNotExistError(msg) |
|
|||
245 |
|
246 | |||
246 | elif is_bstr: |
|
247 | elif is_bstr: | |
247 | # check full path ref, eg. refs/heads/master |
|
248 | # Need to call remote to translate id for tagging scenario | |
248 | ref_id = self._refs.get(commit_id_or_idx) |
|
249 | try: | |
249 | if ref_id: |
|
250 | remote_data = self._remote.get_object(commit_id_or_idx) | |
250 | return ref_id |
|
251 | commit_id_or_idx = remote_data["commit_id"] | |
251 |
|
252 | except (CommitDoesNotExistError,): | ||
252 | # check branch name |
|
253 | raise CommitDoesNotExistError(commit_missing_err) | |
253 | branch_ids = self.branches.values() |
|
|||
254 | ref_id = self._refs.get('refs/heads/%s' % commit_id_or_idx) |
|
|||
255 | if ref_id: |
|
|||
256 | return ref_id |
|
|||
257 |
|
||||
258 | # check tag name |
|
|||
259 | ref_id = self._refs.get('refs/tags/%s' % commit_id_or_idx) |
|
|||
260 | if ref_id: |
|
|||
261 | return ref_id |
|
|||
262 |
|
||||
263 | if (not SHA_PATTERN.match(commit_id_or_idx) or |
|
|||
264 | commit_id_or_idx not in self.commit_ids): |
|
|||
265 | msg = "Commit {} does not exist for `{}`".format(commit_id_or_idx, self.name) |
|
|||
266 | raise CommitDoesNotExistError(msg) |
|
|||
267 |
|
254 | |||
268 | # Ensure we return full id |
|
255 | # Ensure we return full id | |
269 | if not SHA_PATTERN.match(str(commit_id_or_idx)): |
|
256 | if not SHA_PATTERN.match(str(commit_id_or_idx)): | |
@@ -327,32 +314,31 b' class GitRepository(BaseRepository):' | |||||
327 | def _get_branches(self): |
|
314 | def _get_branches(self): | |
328 | return self._get_refs_entries(prefix='refs/heads/', strip_prefix=True) |
|
315 | return self._get_refs_entries(prefix='refs/heads/', strip_prefix=True) | |
329 |
|
316 | |||
330 |
@ |
|
317 | @CachedProperty | |
331 | def branches(self): |
|
318 | def branches(self): | |
332 | return self._get_branches() |
|
319 | return self._get_branches() | |
333 |
|
320 | |||
334 |
@ |
|
321 | @CachedProperty | |
335 | def branches_closed(self): |
|
322 | def branches_closed(self): | |
336 | return {} |
|
323 | return {} | |
337 |
|
324 | |||
338 |
@ |
|
325 | @CachedProperty | |
339 | def bookmarks(self): |
|
326 | def bookmarks(self): | |
340 | return {} |
|
327 | return {} | |
341 |
|
328 | |||
342 |
@ |
|
329 | @CachedProperty | |
343 | def branches_all(self): |
|
330 | def branches_all(self): | |
344 | all_branches = {} |
|
331 | all_branches = {} | |
345 | all_branches.update(self.branches) |
|
332 | all_branches.update(self.branches) | |
346 | all_branches.update(self.branches_closed) |
|
333 | all_branches.update(self.branches_closed) | |
347 | return all_branches |
|
334 | return all_branches | |
348 |
|
335 | |||
349 |
@ |
|
336 | @CachedProperty | |
350 | def tags(self): |
|
337 | def tags(self): | |
351 | return self._get_tags() |
|
338 | return self._get_tags() | |
352 |
|
339 | |||
353 | def _get_tags(self): |
|
340 | def _get_tags(self): | |
354 | return self._get_refs_entries( |
|
341 | return self._get_refs_entries(prefix='refs/tags/', strip_prefix=True, reverse=True) | |
355 | prefix='refs/tags/', strip_prefix=True, reverse=True) |
|
|||
356 |
|
342 | |||
357 | def tag(self, name, user, commit_id=None, message=None, date=None, |
|
343 | def tag(self, name, user, commit_id=None, message=None, date=None, | |
358 | **kwargs): |
|
344 | **kwargs): | |
@@ -368,15 +354,17 b' class GitRepository(BaseRepository):' | |||||
368 |
|
354 | |||
369 | :raises TagAlreadyExistError: if tag with same name already exists |
|
355 | :raises TagAlreadyExistError: if tag with same name already exists | |
370 | """ |
|
356 | """ | |
|
357 | print self._refs | |||
371 | if name in self.tags: |
|
358 | if name in self.tags: | |
372 | raise TagAlreadyExistError("Tag %s already exists" % name) |
|
359 | raise TagAlreadyExistError("Tag %s already exists" % name) | |
373 | commit = self.get_commit(commit_id=commit_id) |
|
360 | commit = self.get_commit(commit_id=commit_id) | |
374 | message = message or "Added tag %s for commit %s" % ( |
|
361 | message = message or "Added tag %s for commit %s" % (name, commit.raw_id) | |
375 | name, commit.raw_id) |
|
362 | ||
376 |
self._remote.set_refs('refs/tags/%s' % name, commit._ |
|
363 | self._remote.set_refs('refs/tags/%s' % name, commit.raw_id) | |
377 |
|
364 | |||
378 | self._refs = self._get_refs() |
|
365 | self._invalidate_prop_cache('tags') | |
379 | self.tags = self._get_tags() |
|
366 | self._invalidate_prop_cache('_refs') | |
|
367 | ||||
380 | return commit |
|
368 | return commit | |
381 |
|
369 | |||
382 | def remove_tag(self, name, user, message=None, date=None): |
|
370 | def remove_tag(self, name, user, message=None, date=None): | |
@@ -392,19 +380,15 b' class GitRepository(BaseRepository):' | |||||
392 | """ |
|
380 | """ | |
393 | if name not in self.tags: |
|
381 | if name not in self.tags: | |
394 | raise TagDoesNotExistError("Tag %s does not exist" % name) |
|
382 | raise TagDoesNotExistError("Tag %s does not exist" % name) | |
395 | tagpath = vcspath.join( |
|
383 | ||
396 |
|
|
384 | self._remote.tag_remove(name) | |
397 | try: |
|
385 | self._invalidate_prop_cache('tags') | |
398 | os.remove(tagpath) |
|
386 | self._invalidate_prop_cache('_refs') | |
399 | self._refs = self._get_refs() |
|
|||
400 | self.tags = self._get_tags() |
|
|||
401 | except OSError as e: |
|
|||
402 | raise RepositoryError(e.strerror) |
|
|||
403 |
|
387 | |||
404 | def _get_refs(self): |
|
388 | def _get_refs(self): | |
405 | return self._remote.get_refs() |
|
389 | return self._remote.get_refs() | |
406 |
|
390 | |||
407 |
@ |
|
391 | @CachedProperty | |
408 | def _refs(self): |
|
392 | def _refs(self): | |
409 | return self._get_refs() |
|
393 | return self._get_refs() | |
410 |
|
394 | |||
@@ -455,18 +439,13 b' class GitRepository(BaseRepository):' | |||||
455 | else: |
|
439 | else: | |
456 | commit_id = "tip" |
|
440 | commit_id = "tip" | |
457 |
|
441 | |||
458 | commit_id = self._lookup_commit(commit_id) |
|
|||
459 | remote_idx = None |
|
|||
460 | if translate_tag: |
|
442 | if translate_tag: | |
461 | # Need to call remote to translate id for tagging scenario |
|
443 | commit_id = self._lookup_commit(commit_id) | |
462 | remote_data = self._remote.get_object(commit_id) |
|
|||
463 | commit_id = remote_data["commit_id"] |
|
|||
464 | remote_idx = remote_data["idx"] |
|
|||
465 |
|
444 | |||
466 | try: |
|
445 | try: | |
467 | idx = self._commit_ids[commit_id] |
|
446 | idx = self._commit_ids[commit_id] | |
468 | except KeyError: |
|
447 | except KeyError: | |
469 |
idx = |
|
448 | idx = -1 | |
470 |
|
449 | |||
471 | return GitCommit(self, commit_id, idx, pre_load=pre_load) |
|
450 | return GitCommit(self, commit_id, idx, pre_load=pre_load) | |
472 |
|
451 | |||
@@ -539,14 +518,8 b' class GitRepository(BaseRepository):' | |||||
539 | 'start': start_pos, |
|
518 | 'start': start_pos, | |
540 | 'end': end_pos, |
|
519 | 'end': end_pos, | |
541 | } |
|
520 | } | |
542 |
commit_ids = self._get_ |
|
521 | commit_ids = self._get_commit_ids(filters=revfilters) | |
543 |
|
522 | |||
544 | # pure python stuff, it's slow due to walker walking whole repo |
|
|||
545 | # def get_revs(walker): |
|
|||
546 | # for walker_entry in walker: |
|
|||
547 | # yield walker_entry.commit.id |
|
|||
548 | # revfilters = {} |
|
|||
549 | # commit_ids = list(reversed(list(get_revs(self._repo.get_walker(**revfilters))))) |
|
|||
550 | else: |
|
523 | else: | |
551 | commit_ids = self.commit_ids |
|
524 | commit_ids = self.commit_ids | |
552 |
|
525 | |||
@@ -613,8 +586,11 b' class GitRepository(BaseRepository):' | |||||
613 | commit = commit.parents[0] |
|
586 | commit = commit.parents[0] | |
614 | self._remote.set_refs('refs/heads/%s' % branch_name, commit.raw_id) |
|
587 | self._remote.set_refs('refs/heads/%s' % branch_name, commit.raw_id) | |
615 |
|
588 | |||
616 | self._commit_ids_ver = time.time() |
|
589 | # clear cached properties | |
617 | # we updated _commit_ids_ver so accessing self.commit_ids will re-compute it |
|
590 | self._invalidate_prop_cache('commit_ids') | |
|
591 | self._invalidate_prop_cache('_refs') | |||
|
592 | self._invalidate_prop_cache('branches') | |||
|
593 | ||||
618 | return len(self.commit_ids) |
|
594 | return len(self.commit_ids) | |
619 |
|
595 | |||
620 | def get_common_ancestor(self, commit_id1, commit_id2, repo2): |
|
596 | def get_common_ancestor(self, commit_id1, commit_id2, repo2): | |
@@ -697,9 +673,11 b' class GitRepository(BaseRepository):' | |||||
697 |
|
673 | |||
698 | def set_refs(self, ref_name, commit_id): |
|
674 | def set_refs(self, ref_name, commit_id): | |
699 | self._remote.set_refs(ref_name, commit_id) |
|
675 | self._remote.set_refs(ref_name, commit_id) | |
|
676 | self._invalidate_prop_cache('_refs') | |||
700 |
|
677 | |||
701 | def remove_ref(self, ref_name): |
|
678 | def remove_ref(self, ref_name): | |
702 | self._remote.remove_ref(ref_name) |
|
679 | self._remote.remove_ref(ref_name) | |
|
680 | self._invalidate_prop_cache('_refs') | |||
703 |
|
681 | |||
704 | def _update_server_info(self): |
|
682 | def _update_server_info(self): | |
705 | """ |
|
683 | """ | |
@@ -744,6 +722,12 b' class GitRepository(BaseRepository):' | |||||
744 | cmd.append(branch_name) |
|
722 | cmd.append(branch_name) | |
745 | self.run_git_command(cmd, fail_on_stderr=False) |
|
723 | self.run_git_command(cmd, fail_on_stderr=False) | |
746 |
|
724 | |||
|
725 | def _create_branch(self, branch_name, commit_id): | |||
|
726 | """ | |||
|
727 | creates a branch in a GIT repo | |||
|
728 | """ | |||
|
729 | self._remote.create_branch(branch_name, commit_id) | |||
|
730 | ||||
747 | def _identify(self): |
|
731 | def _identify(self): | |
748 | """ |
|
732 | """ | |
749 | Return the current state of the working directory. |
|
733 | Return the current state of the working directory. |
@@ -299,10 +299,11 b' class MercurialCommit(base.BaseCommit):' | |||||
299 | loc = vals[0] |
|
299 | loc = vals[0] | |
300 | commit = vals[1] |
|
300 | commit = vals[1] | |
301 | dirnodes.append(SubModuleNode(k, url=loc, commit=commit, alias=alias)) |
|
301 | dirnodes.append(SubModuleNode(k, url=loc, commit=commit, alias=alias)) | |
|
302 | ||||
302 | nodes = dirnodes + filenodes |
|
303 | nodes = dirnodes + filenodes | |
303 | # cache nodes |
|
|||
304 | for node in nodes: |
|
304 | for node in nodes: | |
305 | self.nodes[node.path] = node |
|
305 | if node.path not in self.nodes: | |
|
306 | self.nodes[node.path] = node | |||
306 | nodes.sort() |
|
307 | nodes.sort() | |
307 |
|
308 | |||
308 | return nodes |
|
309 | return nodes |
@@ -24,16 +24,15 b' HG repository module' | |||||
24 | import os |
|
24 | import os | |
25 | import logging |
|
25 | import logging | |
26 | import binascii |
|
26 | import binascii | |
27 | import time |
|
|||
28 | import urllib |
|
27 | import urllib | |
29 |
|
28 | |||
30 | from zope.cachedescriptors.property import Lazy as LazyProperty |
|
29 | from zope.cachedescriptors.property import Lazy as LazyProperty | |
31 | from zope.cachedescriptors.property import CachedProperty |
|
|||
32 |
|
30 | |||
33 | from rhodecode.lib.compat import OrderedDict |
|
31 | from rhodecode.lib.compat import OrderedDict | |
34 | from rhodecode.lib.datelib import ( |
|
32 | from rhodecode.lib.datelib import ( | |
35 | date_to_timestamp_plus_offset, utcdate_fromtimestamp, makedate) |
|
33 | date_to_timestamp_plus_offset, utcdate_fromtimestamp, makedate) | |
36 | from rhodecode.lib.utils import safe_unicode, safe_str |
|
34 | from rhodecode.lib.utils import safe_unicode, safe_str | |
|
35 | from rhodecode.lib.utils2 import CachedProperty | |||
37 | from rhodecode.lib.vcs import connection, exceptions |
|
36 | from rhodecode.lib.vcs import connection, exceptions | |
38 | from rhodecode.lib.vcs.backends.base import ( |
|
37 | from rhodecode.lib.vcs.backends.base import ( | |
39 | BaseRepository, CollectionGenerator, Config, MergeResponse, |
|
38 | BaseRepository, CollectionGenerator, Config, MergeResponse, | |
@@ -87,14 +86,11 b' class MercurialRepository(BaseRepository' | |||||
87 | # caches |
|
86 | # caches | |
88 | self._commit_ids = {} |
|
87 | self._commit_ids = {} | |
89 |
|
88 | |||
90 | # dependent that trigger re-computation of commit_ids |
|
|||
91 | self._commit_ids_ver = 0 |
|
|||
92 |
|
||||
93 | @LazyProperty |
|
89 | @LazyProperty | |
94 | def _remote(self): |
|
90 | def _remote(self): | |
95 | return connection.Hg(self.path, self.config, with_wire=self.with_wire) |
|
91 | return connection.Hg(self.path, self.config, with_wire=self.with_wire) | |
96 |
|
92 | |||
97 |
@CachedProperty |
|
93 | @CachedProperty | |
98 | def commit_ids(self): |
|
94 | def commit_ids(self): | |
99 | """ |
|
95 | """ | |
100 | Returns list of commit ids, in ascending order. Being lazy |
|
96 | Returns list of commit ids, in ascending order. Being lazy | |
@@ -108,15 +104,15 b' class MercurialRepository(BaseRepository' | |||||
108 | self._commit_ids = dict((commit_id, index) |
|
104 | self._commit_ids = dict((commit_id, index) | |
109 | for index, commit_id in enumerate(commit_ids)) |
|
105 | for index, commit_id in enumerate(commit_ids)) | |
110 |
|
106 | |||
111 |
@ |
|
107 | @CachedProperty | |
112 | def branches(self): |
|
108 | def branches(self): | |
113 | return self._get_branches() |
|
109 | return self._get_branches() | |
114 |
|
110 | |||
115 |
@ |
|
111 | @CachedProperty | |
116 | def branches_closed(self): |
|
112 | def branches_closed(self): | |
117 | return self._get_branches(active=False, closed=True) |
|
113 | return self._get_branches(active=False, closed=True) | |
118 |
|
114 | |||
119 |
@ |
|
115 | @CachedProperty | |
120 | def branches_all(self): |
|
116 | def branches_all(self): | |
121 | all_branches = {} |
|
117 | all_branches = {} | |
122 | all_branches.update(self.branches) |
|
118 | all_branches.update(self.branches) | |
@@ -143,7 +139,7 b' class MercurialRepository(BaseRepository' | |||||
143 |
|
139 | |||
144 | return OrderedDict(sorted(_branches, key=get_name, reverse=False)) |
|
140 | return OrderedDict(sorted(_branches, key=get_name, reverse=False)) | |
145 |
|
141 | |||
146 |
@ |
|
142 | @CachedProperty | |
147 | def tags(self): |
|
143 | def tags(self): | |
148 | """ |
|
144 | """ | |
149 | Gets tags for this repository |
|
145 | Gets tags for this repository | |
@@ -276,8 +272,9 b' class MercurialRepository(BaseRepository' | |||||
276 | self._remote.strip(commit_id, update=False, backup="none") |
|
272 | self._remote.strip(commit_id, update=False, backup="none") | |
277 |
|
273 | |||
278 | self._remote.invalidate_vcs_cache() |
|
274 | self._remote.invalidate_vcs_cache() | |
279 | self._commit_ids_ver = time.time() |
|
275 | # clear cache | |
280 | # we updated _commit_ids_ver so accessing self.commit_ids will re-compute it |
|
276 | self._invalidate_prop_cache('commit_ids') | |
|
277 | ||||
281 | return len(self.commit_ids) |
|
278 | return len(self.commit_ids) | |
282 |
|
279 | |||
283 | def verify(self): |
|
280 | def verify(self): |
@@ -27,11 +27,11 b' import os' | |||||
27 | import urllib |
|
27 | import urllib | |
28 |
|
28 | |||
29 | from zope.cachedescriptors.property import Lazy as LazyProperty |
|
29 | from zope.cachedescriptors.property import Lazy as LazyProperty | |
30 | from zope.cachedescriptors.property import CachedProperty |
|
|||
31 |
|
30 | |||
32 | from rhodecode.lib.compat import OrderedDict |
|
31 | from rhodecode.lib.compat import OrderedDict | |
33 | from rhodecode.lib.datelib import date_astimestamp |
|
32 | from rhodecode.lib.datelib import date_astimestamp | |
34 | from rhodecode.lib.utils import safe_str, safe_unicode |
|
33 | from rhodecode.lib.utils import safe_str, safe_unicode | |
|
34 | from rhodecode.lib.utils2 import CachedProperty | |||
35 | from rhodecode.lib.vcs import connection, path as vcspath |
|
35 | from rhodecode.lib.vcs import connection, path as vcspath | |
36 | from rhodecode.lib.vcs.backends import base |
|
36 | from rhodecode.lib.vcs.backends import base | |
37 | from rhodecode.lib.vcs.backends.svn.commit import ( |
|
37 | from rhodecode.lib.vcs.backends.svn.commit import ( | |
@@ -76,8 +76,9 b' class SubversionRepository(base.BaseRepo' | |||||
76 |
|
76 | |||
77 | self._init_repo(create, src_url) |
|
77 | self._init_repo(create, src_url) | |
78 |
|
78 | |||
79 | # dependent that trigger re-computation of commit_ids |
|
79 | # caches | |
80 |
self._commit_ids |
|
80 | self._commit_ids = {} | |
|
81 | ||||
81 |
|
82 | |||
82 | @LazyProperty |
|
83 | @LazyProperty | |
83 | def _remote(self): |
|
84 | def _remote(self): | |
@@ -97,7 +98,7 b' class SubversionRepository(base.BaseRepo' | |||||
97 | else: |
|
98 | else: | |
98 | self._check_path() |
|
99 | self._check_path() | |
99 |
|
100 | |||
100 |
@CachedProperty |
|
101 | @CachedProperty | |
101 | def commit_ids(self): |
|
102 | def commit_ids(self): | |
102 | head = self._remote.lookup(None) |
|
103 | head = self._remote.lookup(None) | |
103 | return [str(r) for r in xrange(1, head + 1)] |
|
104 | return [str(r) for r in xrange(1, head + 1)] |
@@ -46,6 +46,7 b' class TestGitRepository(object):' | |||||
46 | @pytest.fixture(autouse=True) |
|
46 | @pytest.fixture(autouse=True) | |
47 | def prepare(self, request, baseapp): |
|
47 | def prepare(self, request, baseapp): | |
48 | self.repo = GitRepository(TEST_GIT_REPO, bare=True) |
|
48 | self.repo = GitRepository(TEST_GIT_REPO, bare=True) | |
|
49 | self.repo.count() | |||
49 |
|
50 | |||
50 | def get_clone_repo(self, tmp_path_factory): |
|
51 | def get_clone_repo(self, tmp_path_factory): | |
51 | """ |
|
52 | """ | |
@@ -1242,7 +1243,7 b' class TestGetSubmoduleUrl(object):' | |||||
1242 | commit = GitCommit(repository=repository, raw_id='abcdef12', idx=1) |
|
1243 | commit = GitCommit(repository=repository, raw_id='abcdef12', idx=1) | |
1243 | submodule_url = 'https://code.rhodecode.com/dulwich' |
|
1244 | submodule_url = 'https://code.rhodecode.com/dulwich' | |
1244 | get_id_patch = mock.patch.object( |
|
1245 | get_id_patch = mock.patch.object( | |
1245 | commit, '_get_id_for_path', return_value=(1, 'link')) |
|
1246 | commit, '_get_tree_id_for_path', return_value=(1, 'link')) | |
1246 | get_submodule_patch = mock.patch.object( |
|
1247 | get_submodule_patch = mock.patch.object( | |
1247 | commit, '_get_submodule_url', return_value=submodule_url) |
|
1248 | commit, '_get_submodule_url', return_value=submodule_url) | |
1248 |
|
1249 | |||
@@ -1262,7 +1263,7 b' class TestGetSubmoduleUrl(object):' | |||||
1262 | commit = GitCommit(repository=repository, raw_id='abcdef12', idx=1) |
|
1263 | commit = GitCommit(repository=repository, raw_id='abcdef12', idx=1) | |
1263 | submodule_url = 'https://code.rhodecode.com/dulwich' |
|
1264 | submodule_url = 'https://code.rhodecode.com/dulwich' | |
1264 | get_id_patch = mock.patch.object( |
|
1265 | get_id_patch = mock.patch.object( | |
1265 | commit, '_get_id_for_path', return_value=(1, 'tree')) |
|
1266 | commit, '_get_tree_id_for_path', return_value=(1, 'tree')) | |
1266 | get_submodule_patch = mock.patch.object( |
|
1267 | get_submodule_patch = mock.patch.object( | |
1267 | commit, '_get_submodule_url', return_value=submodule_url) |
|
1268 | commit, '_get_submodule_url', return_value=submodule_url) | |
1268 |
|
1269 |
@@ -88,8 +88,6 b' class TestInMemoryCommit(BackendTestMixi' | |||||
88 |
|
88 | |||
89 | @pytest.mark.backends("git") |
|
89 | @pytest.mark.backends("git") | |
90 | def test_add_on_branch_git(self, nodes): |
|
90 | def test_add_on_branch_git(self, nodes): | |
91 | self.repo._checkout('stable', create=True) |
|
|||
92 |
|
||||
93 | for node in nodes: |
|
91 | for node in nodes: | |
94 | self.imc.add(node) |
|
92 | self.imc.add(node) | |
95 | self.commit(branch=u'stable') |
|
93 | self.commit(branch=u'stable') |
General Comments 0
You need to be logged in to leave comments.
Login now