Merge lp:~jelmer/brz-git/remote-test-improvements into lp:brz-git

Proposed by Jelmer Vernooij
Status: Merged
Approved by: Jelmer Vernooij
Approved revision: 1877
Merge reported by: The Breezy Bot
Merged at revision: not available
Proposed branch: lp:~jelmer/brz-git/remote-test-improvements
Merge into: lp:brz-git
Diff against target: 647 lines (+276/-69)
12 files modified
branch.py (+1/-1)
commands.py (+2/-3)
dir.py (+17/-17)
fetch.py (+3/-3)
object_store.py (+8/-4)
push.py (+1/-1)
refs.py (+8/-1)
remote.py (+30/-15)
tests/test_git_remote_helper.py (+1/-1)
tests/test_refs.py (+54/-6)
tests/test_remote.py (+141/-8)
transportgit.py (+10/-9)
To merge this branch: bzr merge lp:~jelmer/brz-git/remote-test-improvements
Reviewer Review Type Date Requested Status
Jelmer Vernooij Approve
Review via email: mp+341866@code.launchpad.net

Commit message

Fix remote branch operations and add more tests.

Description of the change

Fix remote branch operations and add more tests.

To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) wrote :

Rubberstamp! Proposer approves of own proposal.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'branch.py'
2--- branch.py 2018-03-21 03:06:49 +0000
3+++ branch.py 2018-03-22 01:32:19 +0000
4@@ -1081,7 +1081,7 @@
5 stop_revno = self.source.revision_id_to_revno(stop_revision)
6 if type(stop_revision) is not str:
7 raise TypeError(stop_revision)
8- main_ref = self.target.ref or "refs/heads/master"
9+ main_ref = self.target.ref
10 refs = { main_ref: (None, stop_revision) }
11 if fetch_tags is None:
12 c = self.source.get_config_stack()
13
14=== modified file 'commands.py'
15--- commands.py 2018-03-17 19:20:55 +0000
16+++ commands.py 2018-03-22 01:32:19 +0000
17@@ -124,16 +124,15 @@
18 interrepo = InterRepository.get(source_repo, target_repo)
19 mapping = source_repo.get_mapping()
20 refs = interrepo.fetch()
21- refs_dict = refs.as_dict()
22 pb = ui.ui_factory.nested_progress_bar()
23 try:
24- for i, (name, sha) in enumerate(refs_dict.iteritems()):
25+ for i, (name, sha) in enumerate(refs.iteritems()):
26 try:
27 branch_name = ref_to_branch_name(name)
28 except ValueError:
29 # Not a branch, ignore
30 continue
31- pb.update(gettext("creating branches"), i, len(refs_dict))
32+ pb.update(gettext("creating branches"), i, len(refs))
33 if getattr(target_controldir._format, "colocated_branches", False) and colocated:
34 if name == "HEAD":
35 branch_name = None
36
37=== modified file 'dir.py'
38--- dir.py 2018-03-20 21:05:19 +0000
39+++ dir.py 2018-03-22 01:32:19 +0000
40@@ -261,6 +261,23 @@
41 """
42 return UseExistingRepository(self.find_repository())
43
44+ def get_branches(self):
45+ from .refs import ref_to_branch_name
46+ ret = {}
47+ for ref in self.get_refs_container().keys():
48+ try:
49+ branch_name = ref_to_branch_name(ref)
50+ except ValueError:
51+ continue
52+ except UnicodeDecodeError:
53+ trace.warning("Ignoring branch %r with unicode error ref", ref)
54+ continue
55+ ret[branch_name] = self.open_branch(ref=ref)
56+ return ret
57+
58+ def list_branches(self):
59+ return self.get_branches().values()
60+
61
62 class LocalGitControlDirFormat(GitControlDirFormat):
63 """The .git directory control format."""
64@@ -513,23 +530,6 @@
65 def needs_format_conversion(self, format=None):
66 return not isinstance(self._format, format.__class__)
67
68- def list_branches(self):
69- return self.get_branches().values()
70-
71- def get_branches(self):
72- from .refs import ref_to_branch_name
73- ret = {}
74- for ref in self._git.refs.keys():
75- try:
76- branch_name = ref_to_branch_name(ref)
77- except ValueError:
78- continue
79- except UnicodeDecodeError:
80- trace.warning("Ignoring branch %r with unicode error ref", ref)
81- continue
82- ret[branch_name] = self.open_branch(ref=ref)
83- return ret
84-
85 def open_repository(self):
86 """'open' a repository for this dir."""
87 if self.control_transport.has('commondir'):
88
89=== modified file 'fetch.py'
90--- fetch.py 2018-03-21 03:06:49 +0000
91+++ fetch.py 2018-03-22 01:32:19 +0000
92@@ -602,7 +602,7 @@
93
94 def determine_wants_all(self, refs):
95 potential = set()
96- for k, v in refs.as_dict().iteritems():
97+ for k, v in refs.iteritems():
98 # For non-git target repositories, only worry about peeled
99 if v == ZERO_SHA:
100 continue
101@@ -614,7 +614,7 @@
102 def determine_wants(refs):
103 potential = set(wants)
104 if include_tags:
105- for k, unpeeled in refs.as_dict().iteritems():
106+ for k, unpeeled in refs.iteritems():
107 if not is_tag(k):
108 continue
109 if unpeeled == ZERO_SHA:
110@@ -761,7 +761,7 @@
111 def fetch_objects(self, determine_wants, mapping, limit=None, lossy=False):
112 """See `InterGitNonGitRepository`."""
113 self._warn_slow()
114- remote_refs = self.source.controldir.get_refs_container()
115+ remote_refs = self.source.controldir.get_refs_container().as_dict()
116 wants = determine_wants(remote_refs)
117 create_pb = None
118 pb = ui.ui_factory.nested_progress_bar()
119
120=== modified file 'object_store.py'
121--- object_store.py 2018-03-21 03:06:49 +0000
122+++ object_store.py 2018-03-22 01:32:19 +0000
123@@ -29,6 +29,9 @@
124 from dulwich.object_store import (
125 BaseObjectStore,
126 )
127+from dulwich.pack import (
128+ pack_objects_to_data,
129+ )
130
131 from ... import (
132 errors,
133@@ -705,10 +708,11 @@
134 else:
135 raise KeyError(sha)
136
137- def generate_lossy_pack_contents(self, have, want, progress=None,
138- get_tagged=None):
139- return self.generate_pack_contents(have, want, progress, get_tagged,
140- lossy=True)
141+ def generate_lossy_pack_data(self, have, want, progress=None,
142+ get_tagged=None, ofs_delta=False):
143+ return pack_objects_to_data(
144+ self.generate_pack_contents(have, want, progress, get_tagged,
145+ lossy=True))
146
147 def generate_pack_contents(self, have, want, progress=None,
148 ofs_delta=False, get_tagged=None, lossy=False):
149
150=== modified file 'push.py'
151--- push.py 2018-03-21 03:06:49 +0000
152+++ push.py 2018-03-22 01:32:19 +0000
153@@ -360,7 +360,7 @@
154 self._warn_slow()
155 with self.source_store.lock_read():
156 new_refs = self.target.send_pack(determine_wants,
157- self.source_store.generate_lossy_pack_contents)
158+ self.source_store.generate_lossy_pack_data)
159 # FIXME: revidmap?
160 return revidmap, self.old_refs, self.new_refs
161
162
163=== modified file 'refs.py'
164--- refs.py 2018-03-17 17:27:39 +0000
165+++ refs.py 2018-03-22 01:32:19 +0000
166@@ -25,6 +25,7 @@
167 from ... import (
168 errors,
169 osutils,
170+ revision as _mod_revision,
171 )
172
173 is_tag = lambda x: x.startswith("refs/tags/")
174@@ -97,6 +98,9 @@
175 self.dir = dir
176 self.object_store = object_store
177
178+ def get_packed_refs(self):
179+ return {}
180+
181 def set_symbolic_ref(self, name, other):
182 if name == "HEAD":
183 pass # FIXME: Switch default branch
184@@ -132,8 +136,11 @@
185 revid = self._get_revid_by_tag_name(tag_name)
186 else:
187 revid = self._get_revid_by_branch_name(branch_name)
188+ if revid == _mod_revision.NULL_REVISION:
189+ return None
190 # FIXME: Unpeel if necessary
191- return self.object_store._lookup_revision_sha1(revid)
192+ with self.object_store.lock_read():
193+ return self.object_store._lookup_revision_sha1(revid)
194
195 def get_peeled(self, ref):
196 return self.read_loose_ref(ref)
197
198=== modified file 'remote.py'
199--- remote.py 2018-03-21 03:46:30 +0000
200+++ remote.py 2018-03-22 01:32:19 +0000
201@@ -31,6 +31,7 @@
202 InvalidRevisionId,
203 NoSuchFile,
204 NoSuchRevision,
205+ NoSuchTag,
206 NotBranchError,
207 NotLocalUrl,
208 UninitializableFormat,
209@@ -68,6 +69,7 @@
210 branch_name_to_ref,
211 is_peeled,
212 ref_to_tag_name,
213+ tag_name_to_ref,
214 )
215
216 import dulwich
217@@ -77,6 +79,7 @@
218 )
219 from dulwich.pack import (
220 Pack,
221+ pack_objects_to_data,
222 )
223 from dulwich.repo import DictRefsContainer
224 import os
225@@ -295,31 +298,28 @@
226 if result.refs is None:
227 result.refs = {}
228 self._refs = remote_refs_dict_to_container(result.refs)
229- return result.refs
230+ return result
231 except GitProtocolError, e:
232 raise parse_git_error(self.transport.external_url(), e)
233
234- def send_pack(self, get_changed_refs, generate_pack_contents):
235+ def send_pack(self, get_changed_refs, generate_pack_data):
236 try:
237 return self._client.send_pack(self._client_path, get_changed_refs,
238- generate_pack_contents)
239+ generate_pack_data)
240 except GitProtocolError, e:
241 raise parse_git_error(self.transport.external_url(), e)
242
243- def _get_default_ref(self):
244- return "refs/heads/master"
245-
246 def destroy_branch(self, name=None):
247 refname = self._get_selected_ref(name)
248 def get_changed_refs(old_refs):
249 ret = dict(old_refs)
250 if not refname in ret:
251 raise NotBranchError(self.user_url)
252- ret[refname] = "00" * 20
253+ ret[refname] = dulwich.client.ZERO_SHA
254 return ret
255- def generate_pack_contents(have, want, ofs_delta=False):
256- return []
257- self.send_pack(get_changed_refs, generate_pack_contents)
258+ def generate_pack_data(have, want, ofs_delta=False):
259+ return pack_objects_to_data([])
260+ self.send_pack(get_changed_refs, generate_pack_data)
261
262 @property
263 def user_url(self):
264@@ -486,8 +486,8 @@
265 return self.controldir.fetch_pack(determine_wants, graph_walker,
266 pack_data, progress)
267
268- def send_pack(self, get_changed_refs, generate_pack_contents):
269- return self.controldir.send_pack(get_changed_refs, generate_pack_contents)
270+ def send_pack(self, get_changed_refs, generate_pack_data):
271+ return self.controldir.send_pack(get_changed_refs, generate_pack_data)
272
273 def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref,
274 progress=None):
275@@ -501,7 +501,7 @@
276 return EmptyObjectStoreIterator()
277 return TemporaryPackIterator(path[:-len(".pack")], resolve_ext_ref)
278
279- def lookup_bzr_revision_id(self, bzr_revid):
280+ def lookup_bzr_revision_id(self, bzr_revid, mapping=None):
281 # This won't work for any round-tripped bzr revisions, but it's a start..
282 try:
283 return mapping_registry.revision_id_bzr_to_foreign(bzr_revid)
284@@ -530,8 +530,23 @@
285 class RemoteGitTagDict(GitTags):
286
287 def set_tag(self, name, revid):
288- # FIXME: Not supported yet, should do a push of a new ref
289- raise NotImplementedError(self.set_tag)
290+ sha = self.branch.lookup_bzr_revision_id(revid)[0]
291+ self._set_ref(name, sha)
292+
293+ def delete_tag(self, name):
294+ self._set_ref(name, dulwich.client.ZERO_SHA)
295+
296+ def _set_ref(self, name, sha):
297+ ref = tag_name_to_ref(name)
298+ def get_changed_refs(old_refs):
299+ ret = dict(old_refs)
300+ if sha == dulwich.client.ZERO_SHA and ref not in ret:
301+ raise NoSuchTag(name)
302+ ret[ref] = sha
303+ return ret
304+ def generate_pack_data(have, want, ofs_delta=False):
305+ return pack_objects_to_data([])
306+ self.repository.send_pack(get_changed_refs, generate_pack_data)
307
308
309 class RemoteGitBranch(GitBranch):
310
311=== modified file 'tests/test_git_remote_helper.py'
312--- tests/test_git_remote_helper.py 2018-03-17 17:34:12 +0000
313+++ tests/test_git_remote_helper.py 2018-03-22 01:32:19 +0000
314@@ -115,7 +115,7 @@
315 f = StringIO()
316 self.helper.cmd_list(f, [])
317 self.assertEquals(
318- '0000000000000000000000000000000000000000 HEAD\n\n',
319+ '\n',
320 f.getvalue())
321
322 def test_import(self):
323
324=== modified file 'tests/test_refs.py'
325--- tests/test_refs.py 2018-03-17 17:34:12 +0000
326+++ tests/test_refs.py 2018-03-22 01:32:19 +0000
327@@ -22,18 +22,66 @@
328
329 from .... import tests
330
331-from ...git import refs
332+from ..object_store import BazaarObjectStore
333+from ..refs import (
334+ BazaarRefsContainer,
335+ ref_to_branch_name,
336+ branch_name_to_ref,
337+ )
338
339
340 class BranchNameRefConversionTests(tests.TestCase):
341
342 def test_head(self):
343- self.assertEquals("", refs.ref_to_branch_name("HEAD"))
344- self.assertEquals("HEAD", refs.branch_name_to_ref(""))
345+ self.assertEquals("", ref_to_branch_name("HEAD"))
346+ self.assertEquals("HEAD", branch_name_to_ref(""))
347
348 def test_tag(self):
349- self.assertRaises(ValueError, refs.ref_to_branch_name, "refs/tags/FOO")
350+ self.assertRaises(ValueError, ref_to_branch_name, "refs/tags/FOO")
351
352 def test_branch(self):
353- self.assertEquals("frost", refs.ref_to_branch_name("refs/heads/frost"))
354- self.assertEquals("refs/heads/frost", refs.branch_name_to_ref("frost"))
355+ self.assertEquals("frost", ref_to_branch_name("refs/heads/frost"))
356+ self.assertEquals("refs/heads/frost", branch_name_to_ref("frost"))
357+
358+
359+class BazaarRefsContainerTests(tests.TestCaseWithTransport):
360+
361+ def test_empty(self):
362+ tree = self.make_branch_and_tree('.')
363+ store = BazaarObjectStore(tree.branch.repository)
364+ refs = BazaarRefsContainer(tree.controldir, store)
365+ self.assertEqual(refs.as_dict(), {})
366+
367+ def test_some_commit(self):
368+ tree = self.make_branch_and_tree('.')
369+ revid = tree.commit('somechange')
370+ store = BazaarObjectStore(tree.branch.repository)
371+ refs = BazaarRefsContainer(tree.controldir, store)
372+ self.assertEqual(
373+ refs.as_dict(),
374+ {'HEAD': store._lookup_revision_sha1(revid)})
375+
376+ def test_some_tag(self):
377+ tree = self.make_branch_and_tree('.')
378+ revid = tree.commit('somechange')
379+ tree.branch.tags.set_tag('sometag', revid)
380+ store = BazaarObjectStore(tree.branch.repository)
381+ refs = BazaarRefsContainer(tree.controldir, store)
382+ self.assertEqual(
383+ refs.as_dict(),
384+ {'HEAD': store._lookup_revision_sha1(revid),
385+ 'refs/tags/sometag': store._lookup_revision_sha1(revid),
386+ })
387+
388+ def test_some_branch(self):
389+ tree = self.make_branch_and_tree('.')
390+ revid = tree.commit('somechange')
391+ otherbranch = tree.controldir.create_branch(name='otherbranch')
392+ otherbranch.generate_revision_history(revid)
393+ store = BazaarObjectStore(tree.branch.repository)
394+ refs = BazaarRefsContainer(tree.controldir, store)
395+ self.assertEqual(
396+ refs.as_dict(),
397+ {'HEAD': store._lookup_revision_sha1(revid),
398+ 'refs/heads/otherbranch': store._lookup_revision_sha1(revid),
399+ })
400
401=== modified file 'tests/test_remote.py'
402--- tests/test_remote.py 2018-03-21 03:46:30 +0000
403+++ tests/test_remote.py 2018-03-22 01:32:19 +0000
404@@ -24,6 +24,7 @@
405 from ....errors import (
406 BzrError,
407 NotBranchError,
408+ NoSuchTag,
409 )
410
411 from ....tests import (
412@@ -96,12 +97,14 @@
413 self.assertTrue(self.format.supports_tags())
414
415
416-class TestFetchFromRemote(TestCaseWithTransport):
417+class FetchFromRemoteTestBase(object):
418
419 _test_needs_features = [ExecutableFeature('git')]
420
421+ _to_format = None
422+
423 def setUp(self):
424- super(TestFetchFromRemote, self).setUp()
425+ TestCaseWithTransport.setUp(self)
426 self.remote_real = GitRepo.init('remote', mkdir=True)
427 self.remote_url = 'git://%s/' % os.path.abspath(self.remote_real.path)
428 self.permit_url(self.remote_url)
429@@ -112,8 +115,8 @@
430 committer='committer <committer@example.com>',
431 author='author <author@example.com>')
432
433- self.make_branch_and_tree('.')
434 remote = ControlDir.open(self.remote_url)
435+ self.make_controldir('local', format=self._to_format)
436 local = remote.sprout('local')
437 self.assertEqual(
438 default_mapping.revision_id_foreign_to_bzr(self.remote_real.head()),
439@@ -131,8 +134,8 @@
440 ref='refs/tags/another')
441 self.remote_real.refs['refs/tags/blah'] = self.remote_real.head()
442
443- self.make_branch_and_tree('.')
444 remote = ControlDir.open(self.remote_url)
445+ self.make_controldir('local', format=self._to_format)
446 local = remote.sprout('local')
447 local_branch = local.open_branch()
448 self.assertEqual(
449@@ -144,12 +147,24 @@
450 local_branch.tags.get_tag_dict())
451
452
453-class TestPushToRemote(TestCaseWithTransport):
454+class FetchFromRemoteToBzrTests(FetchFromRemoteTestBase,TestCaseWithTransport):
455+
456+ _to_format = '2a'
457+
458+
459+class FetchFromRemoteToGitTests(FetchFromRemoteTestBase,TestCaseWithTransport):
460+
461+ _to_format = 'git'
462+
463+
464+class PushToRemoteBase(object):
465
466 _test_needs_features = [ExecutableFeature('git')]
467
468+ _from_format = None
469+
470 def setUp(self):
471- super(TestPushToRemote, self).setUp()
472+ TestCaseWithTransport.setUp(self)
473 self.remote_real = GitRepo.init('remote', mkdir=True)
474 self.remote_url = 'git://%s/' % os.path.abspath(self.remote_real.path)
475 self.permit_url(self.remote_url)
476@@ -160,20 +175,138 @@
477 committer='committer <committer@example.com>',
478 author='author <author@example.com>')
479
480- self.make_branch_and_tree('.')
481 remote = ControlDir.open(self.remote_url)
482+ self.make_controldir('local', format=self._from_format)
483 local = remote.sprout('local')
484 self.build_tree(['local/blah'])
485 wt = local.open_workingtree()
486 wt.add(['blah'])
487 revid = wt.commit('blah')
488 wt.branch.tags.set_tag('sometag', revid)
489+ wt.branch.get_config_stack().set('branch.fetch_tags', True)
490
491- remote.push_branch(wt.branch)
492+ if self._from_format == 'git':
493+ wt.branch.push(remote.open_branch())
494+ else:
495+ wt.branch.push(remote.open_branch(), lossy=True)
496
497 self.assertNotEqual(self.remote_real.head(), c1)
498 self.assertEqual(
499 {'refs/heads/master': self.remote_real.head(),
500 'HEAD': self.remote_real.head(),
501+ 'refs/tags/sometag': self.remote_real.head(),
502 },
503 self.remote_real.get_refs())
504+
505+
506+class PushToRemoteFromBzrTests(PushToRemoteBase,TestCaseWithTransport):
507+
508+ _from_format = '2a'
509+
510+
511+class PushToRemoteFromGitTests(PushToRemoteBase,TestCaseWithTransport):
512+
513+ _from_format = 'git'
514+
515+
516+class RemoteControlDirTests(TestCaseWithTransport):
517+
518+ _test_needs_features = [ExecutableFeature('git')]
519+
520+ def setUp(self):
521+ TestCaseWithTransport.setUp(self)
522+ self.remote_real = GitRepo.init('remote', mkdir=True)
523+ self.remote_url = 'git://%s/' % os.path.abspath(self.remote_real.path)
524+ self.permit_url(self.remote_url)
525+
526+ def test_remove_branch(self):
527+ c1 = self.remote_real.do_commit(
528+ message='message',
529+ committer='committer <committer@example.com>',
530+ author='author <author@example.com>')
531+ c2 = self.remote_real.do_commit(
532+ message='another commit',
533+ committer='committer <committer@example.com>',
534+ author='author <author@example.com>',
535+ ref='refs/heads/blah')
536+
537+ remote = ControlDir.open(self.remote_url)
538+ remote.destroy_branch(name='blah')
539+ self.assertEqual(
540+ self.remote_real.get_refs(),
541+ {'refs/heads/master': self.remote_real.head(),
542+ 'HEAD': self.remote_real.head(),
543+ })
544+
545+ def test_list_branches(self):
546+ c1 = self.remote_real.do_commit(
547+ message='message',
548+ committer='committer <committer@example.com>',
549+ author='author <author@example.com>')
550+ c2 = self.remote_real.do_commit(
551+ message='another commit',
552+ committer='committer <committer@example.com>',
553+ author='author <author@example.com>',
554+ ref='refs/heads/blah')
555+
556+ remote = ControlDir.open(self.remote_url)
557+ self.assertEqual(
558+ ['', 'blah', 'master'],
559+ [b.name for b in remote.list_branches()])
560+
561+ def test_get_branches(self):
562+ c1 = self.remote_real.do_commit(
563+ message='message',
564+ committer='committer <committer@example.com>',
565+ author='author <author@example.com>')
566+ c2 = self.remote_real.do_commit(
567+ message='another commit',
568+ committer='committer <committer@example.com>',
569+ author='author <author@example.com>',
570+ ref='refs/heads/blah')
571+
572+ remote = ControlDir.open(self.remote_url)
573+ self.assertEqual(
574+ {'', 'blah', 'master'},
575+ set(remote.get_branches().keys()))
576+
577+ def test_remove_tag(self):
578+ c1 = self.remote_real.do_commit(
579+ message='message',
580+ committer='committer <committer@example.com>',
581+ author='author <author@example.com>')
582+ c2 = self.remote_real.do_commit(
583+ message='another commit',
584+ committer='committer <committer@example.com>',
585+ author='author <author@example.com>',
586+ ref='refs/tags/blah')
587+
588+ remote = ControlDir.open(self.remote_url)
589+ remote_branch = remote.open_branch()
590+ remote_branch.tags.delete_tag('blah')
591+ self.assertRaises(NoSuchTag, remote_branch.tags.delete_tag, 'blah')
592+ self.assertEqual(
593+ self.remote_real.get_refs(),
594+ {'refs/heads/master': self.remote_real.head(),
595+ 'HEAD': self.remote_real.head(),
596+ })
597+
598+ def test_set_tag(self):
599+ c1 = self.remote_real.do_commit(
600+ message='message',
601+ committer='committer <committer@example.com>',
602+ author='author <author@example.com>')
603+ c2 = self.remote_real.do_commit(
604+ message='another commit',
605+ committer='committer <committer@example.com>',
606+ author='author <author@example.com>')
607+
608+ remote = ControlDir.open(self.remote_url)
609+ remote.open_branch().tags.set_tag(
610+ 'blah', default_mapping.revision_id_foreign_to_bzr(c1))
611+ self.assertEqual(
612+ self.remote_real.get_refs(),
613+ {'refs/heads/master': self.remote_real.head(),
614+ 'refs/tags/blah': c1,
615+ 'HEAD': self.remote_real.head(),
616+ })
617
618=== modified file 'transportgit.py'
619--- transportgit.py 2018-03-17 17:27:39 +0000
620+++ transportgit.py 2018-03-22 01:32:19 +0000
621@@ -94,16 +94,17 @@
622 pass
623
624 def subkeys(self, base):
625+ """Refs present in this container under a base.
626+
627+ :param base: The base to return refs under.
628+ :return: A set of valid refs in this container under the base; the base
629+ prefix is stripped from the ref names returned.
630+ """
631 keys = set()
632- try:
633- iter_files = self.transport.clone(base).iter_files_recursive()
634- keys.update(("%s/%s" % (base, urllib.unquote(refname))).strip("/") for
635- refname in iter_files if check_ref_format("%s/%s" % (base, refname)))
636- except (TransportNotPossible, NoSuchFile):
637- pass
638- for key in self.get_packed_refs():
639- if key.startswith(base):
640- keys.add(key[len(base):].strip("/"))
641+ base_len = len(base) + 1
642+ for refname in self.allkeys():
643+ if refname.startswith(base):
644+ keys.add(refname[base_len:])
645 return keys
646
647 def allkeys(self):

Subscribers

People subscribed via source and target branches

to all changes: