/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/git/tests/test_remote.py

  • Committer: Jelmer Vernooij
  • Date: 2020-07-15 21:51:27 UTC
  • mto: (7490.40.58 work)
  • mto: This revision was merged to the branch mainline in revision 7519.
  • Revision ID: jelmer@jelmer.uk-20200715215127-3hn9ktbg3f1xikjj
More fixes for hg probing.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2010-2018 Jelmer Vernooij <jelmer@jelmer.uk>
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
"""Test the smart client."""
 
18
 
 
19
from __future__ import absolute_import
 
20
 
 
21
from io import BytesIO
 
22
 
 
23
import os
 
24
import time
 
25
 
 
26
from ...controldir import ControlDir
 
27
from ...errors import (
 
28
    DivergedBranches,
 
29
    NotBranchError,
 
30
    NoSuchTag,
 
31
    PermissionDenied,
 
32
    )
 
33
 
 
34
from ...tests import (
 
35
    TestCase,
 
36
    TestCaseWithTransport,
 
37
    )
 
38
from ...tests.features import ExecutableFeature
 
39
 
 
40
from ..mapping import default_mapping
 
41
from ..remote import (
 
42
    split_git_url,
 
43
    parse_git_error,
 
44
    parse_git_hangup,
 
45
    HeadUpdateFailed,
 
46
    RemoteGitError,
 
47
    RemoteGitBranchFormat,
 
48
    _git_url_and_path_from_transport,
 
49
    )
 
50
 
 
51
from dulwich import porcelain
 
52
from dulwich.errors import HangupException
 
53
from dulwich.repo import Repo as GitRepo
 
54
 
 
55
 
 
56
class SplitUrlTests(TestCase):
 
57
 
 
58
    def test_simple(self):
 
59
        self.assertEqual(("foo", None, None, "/bar"),
 
60
                         split_git_url("git://foo/bar"))
 
61
 
 
62
    def test_port(self):
 
63
        self.assertEqual(("foo", 343, None, "/bar"),
 
64
                         split_git_url("git://foo:343/bar"))
 
65
 
 
66
    def test_username(self):
 
67
        self.assertEqual(("foo", None, "la", "/bar"),
 
68
                         split_git_url("git://la@foo/bar"))
 
69
 
 
70
    def test_username_password(self):
 
71
        self.assertEqual(
 
72
            ("foo", None, "la", "/bar"),
 
73
            split_git_url("git://la:passwd@foo/bar"))
 
74
 
 
75
    def test_nopath(self):
 
76
        self.assertEqual(("foo", None, None, "/"),
 
77
                         split_git_url("git://foo/"))
 
78
 
 
79
    def test_slashpath(self):
 
80
        self.assertEqual(("foo", None, None, "//bar"),
 
81
                         split_git_url("git://foo//bar"))
 
82
 
 
83
    def test_homedir(self):
 
84
        self.assertEqual(("foo", None, None, "~bar"),
 
85
                         split_git_url("git://foo/~bar"))
 
86
 
 
87
    def test_file(self):
 
88
        self.assertEqual(
 
89
            ("", None, None, "/bar"),
 
90
            split_git_url("file:///bar"))
 
91
 
 
92
 
 
93
class ParseGitErrorTests(TestCase):
 
94
 
 
95
    def test_unknown(self):
 
96
        e = parse_git_error("url", "foo")
 
97
        self.assertIsInstance(e, RemoteGitError)
 
98
 
 
99
    def test_notbrancherror(self):
 
100
        e = parse_git_error("url", "\n Could not find Repository foo/bar")
 
101
        self.assertIsInstance(e, NotBranchError)
 
102
 
 
103
    def test_notbrancherror_launchpad(self):
 
104
        e = parse_git_error("url", "Repository 'foo/bar' not found.")
 
105
        self.assertIsInstance(e, NotBranchError)
 
106
 
 
107
    def test_notbrancherror_github(self):
 
108
        e = parse_git_error("url", "Repository not found.\n")
 
109
        self.assertIsInstance(e, NotBranchError)
 
110
 
 
111
    def test_notbrancherror_normal(self):
 
112
        e = parse_git_error(
 
113
            "url", "fatal: '/srv/git/lintian-brush' does not appear to be a git repository")
 
114
        self.assertIsInstance(e, NotBranchError)
 
115
 
 
116
    def test_head_update(self):
 
117
        e = parse_git_error("url", "HEAD failed to update\n")
 
118
        self.assertIsInstance(e, HeadUpdateFailed)
 
119
 
 
120
    def test_permission_dnied(self):
 
121
        e = parse_git_error(
 
122
            "url",
 
123
            "access denied or repository not exported: /debian/altermime.git")
 
124
        self.assertIsInstance(e, PermissionDenied)
 
125
 
 
126
    def test_permission_denied_gitlab(self):
 
127
        e = parse_git_error(
 
128
            "url",
 
129
            'GitLab: You are not allowed to push code to this project.\n')
 
130
        self.assertIsInstance(e, PermissionDenied)
 
131
 
 
132
    def test_permission_denied_github(self):
 
133
        e = parse_git_error(
 
134
            "url",
 
135
            'Permission to porridge/gaduhistory.git denied to jelmer.')
 
136
        self.assertIsInstance(e, PermissionDenied)
 
137
        self.assertEqual(e.path, 'porridge/gaduhistory.git')
 
138
        self.assertEqual(e.extra, ': denied to jelmer')
 
139
 
 
140
    def test_invalid_repo_name(self):
 
141
        e = parse_git_error(
 
142
            "url",
 
143
            """Gregwar/fatcat/tree/debian is not a valid repository name
 
144
Email support@github.com for help
 
145
""")
 
146
        self.assertIsInstance(e, NotBranchError)
 
147
 
 
148
 
 
149
class ParseHangupTests(TestCase):
 
150
 
 
151
    def setUp(self):
 
152
        super(ParseHangupTests, self).setUp()
 
153
        try:
 
154
            HangupException([b'foo'])
 
155
        except TypeError:
 
156
            self.skipTest('dulwich version too old')
 
157
 
 
158
    def test_not_set(self):
 
159
        self.assertIsInstance(
 
160
            parse_git_hangup('http://', HangupException()), HangupException)
 
161
 
 
162
    def test_single_line(self):
 
163
        self.assertEqual(
 
164
            RemoteGitError('foo bar'),
 
165
            parse_git_hangup('http://', HangupException([b'foo bar'])))
 
166
 
 
167
    def test_multi_lines(self):
 
168
        self.assertEqual(
 
169
            RemoteGitError('foo bar\nbla bla'),
 
170
            parse_git_hangup(
 
171
                'http://', HangupException([b'foo bar', b'bla bla'])))
 
172
 
 
173
    def test_filter_boring(self):
 
174
        self.assertEqual(
 
175
            RemoteGitError('foo bar'), parse_git_hangup('http://', HangupException(
 
176
                [b'=======', b'foo bar', b'======'])))
 
177
        self.assertEqual(
 
178
            RemoteGitError('foo bar'), parse_git_hangup('http://', HangupException(
 
179
                [b'remote: =======', b'remote: foo bar', b'remote: ======'])))
 
180
 
 
181
    def test_permission_denied(self):
 
182
        self.assertEqual(
 
183
            PermissionDenied('http://', 'You are not allowed to push code to this project.'),
 
184
            parse_git_hangup(
 
185
                'http://',
 
186
                HangupException(
 
187
                    [b'=======',
 
188
                     b'You are not allowed to push code to this project.', b'', b'======'])))
 
189
 
 
190
 
 
191
class TestRemoteGitBranchFormat(TestCase):
 
192
 
 
193
    def setUp(self):
 
194
        super(TestRemoteGitBranchFormat, self).setUp()
 
195
        self.format = RemoteGitBranchFormat()
 
196
 
 
197
    def test_get_format_description(self):
 
198
        self.assertEqual("Remote Git Branch",
 
199
                         self.format.get_format_description())
 
200
 
 
201
    def test_get_network_name(self):
 
202
        self.assertEqual(b"git", self.format.network_name())
 
203
 
 
204
    def test_supports_tags(self):
 
205
        self.assertTrue(self.format.supports_tags())
 
206
 
 
207
 
 
208
class TestRemoteGitBranch(TestCaseWithTransport):
 
209
 
 
210
    _test_needs_features = [ExecutableFeature('git')]
 
211
 
 
212
    def setUp(self):
 
213
        TestCaseWithTransport.setUp(self)
 
214
        self.remote_real = GitRepo.init('remote', mkdir=True)
 
215
        self.remote_url = 'git://%s/' % os.path.abspath(self.remote_real.path)
 
216
        self.permit_url(self.remote_url)
 
217
 
 
218
    def test_set_last_revision_info(self):
 
219
        c1 = self.remote_real.do_commit(
 
220
            message=b'message 1',
 
221
            committer=b'committer <committer@example.com>',
 
222
            author=b'author <author@example.com>',
 
223
            ref=b'refs/heads/newbranch')
 
224
        c2 = self.remote_real.do_commit(
 
225
            message=b'message 2',
 
226
            committer=b'committer <committer@example.com>',
 
227
            author=b'author <author@example.com>',
 
228
            ref=b'refs/heads/newbranch')
 
229
 
 
230
        remote = ControlDir.open(self.remote_url)
 
231
        newbranch = remote.open_branch('newbranch')
 
232
        self.assertEqual(newbranch.lookup_foreign_revision_id(c2),
 
233
                         newbranch.last_revision())
 
234
        newbranch.set_last_revision_info(
 
235
            1, newbranch.lookup_foreign_revision_id(c1))
 
236
        self.assertEqual(c1, self.remote_real.refs[b'refs/heads/newbranch'])
 
237
        self.assertEqual(newbranch.last_revision(),
 
238
                         newbranch.lookup_foreign_revision_id(c1))
 
239
 
 
240
 
 
241
class FetchFromRemoteTestBase(object):
 
242
 
 
243
    _test_needs_features = [ExecutableFeature('git')]
 
244
 
 
245
    _to_format = None
 
246
 
 
247
    def setUp(self):
 
248
        TestCaseWithTransport.setUp(self)
 
249
        self.remote_real = GitRepo.init('remote', mkdir=True)
 
250
        self.remote_url = 'git://%s/' % os.path.abspath(self.remote_real.path)
 
251
        self.permit_url(self.remote_url)
 
252
 
 
253
    def test_sprout_simple(self):
 
254
        self.remote_real.do_commit(
 
255
            message=b'message',
 
256
            committer=b'committer <committer@example.com>',
 
257
            author=b'author <author@example.com>')
 
258
 
 
259
        remote = ControlDir.open(self.remote_url)
 
260
        self.make_controldir('local', format=self._to_format)
 
261
        local = remote.sprout('local')
 
262
        self.assertEqual(
 
263
            default_mapping.revision_id_foreign_to_bzr(
 
264
                self.remote_real.head()),
 
265
            local.open_branch().last_revision())
 
266
 
 
267
    def test_sprout_with_tags(self):
 
268
        c1 = self.remote_real.do_commit(
 
269
            message=b'message',
 
270
            committer=b'committer <committer@example.com>',
 
271
            author=b'author <author@example.com>')
 
272
        c2 = self.remote_real.do_commit(
 
273
            message=b'another commit',
 
274
            committer=b'committer <committer@example.com>',
 
275
            author=b'author <author@example.com>',
 
276
            ref=b'refs/tags/another')
 
277
        self.remote_real.refs[b'refs/tags/blah'] = self.remote_real.head()
 
278
 
 
279
        remote = ControlDir.open(self.remote_url)
 
280
        self.make_controldir('local', format=self._to_format)
 
281
        local = remote.sprout('local')
 
282
        local_branch = local.open_branch()
 
283
        self.assertEqual(
 
284
            default_mapping.revision_id_foreign_to_bzr(c1),
 
285
            local_branch.last_revision())
 
286
        self.assertEqual(
 
287
            {'blah': local_branch.last_revision(),
 
288
             'another': default_mapping.revision_id_foreign_to_bzr(c2)},
 
289
            local_branch.tags.get_tag_dict())
 
290
 
 
291
    def test_sprout_with_annotated_tag(self):
 
292
        c1 = self.remote_real.do_commit(
 
293
            message=b'message',
 
294
            committer=b'committer <committer@example.com>',
 
295
            author=b'author <author@example.com>')
 
296
        c2 = self.remote_real.do_commit(
 
297
            message=b'another commit',
 
298
            committer=b'committer <committer@example.com>',
 
299
            author=b'author <author@example.com>',
 
300
            ref=b'refs/heads/another')
 
301
        porcelain.tag_create(
 
302
            self.remote_real,
 
303
            tag=b"blah",
 
304
            author=b'author <author@example.com>',
 
305
            objectish=c2,
 
306
            tag_time=int(time.time()),
 
307
            tag_timezone=0,
 
308
            annotated=True,
 
309
            message=b"Annotated tag")
 
310
 
 
311
        remote = ControlDir.open(self.remote_url)
 
312
        self.make_controldir('local', format=self._to_format)
 
313
        local = remote.sprout(
 
314
            'local', revision_id=default_mapping.revision_id_foreign_to_bzr(c1))
 
315
        local_branch = local.open_branch()
 
316
        self.assertEqual(
 
317
            default_mapping.revision_id_foreign_to_bzr(c1),
 
318
            local_branch.last_revision())
 
319
        self.assertEqual(
 
320
            {'blah': default_mapping.revision_id_foreign_to_bzr(c2)},
 
321
            local_branch.tags.get_tag_dict())
 
322
 
 
323
    def test_sprout_with_annotated_tag_unreferenced(self):
 
324
        c1 = self.remote_real.do_commit(
 
325
            message=b'message',
 
326
            committer=b'committer <committer@example.com>',
 
327
            author=b'author <author@example.com>')
 
328
        c2 = self.remote_real.do_commit(
 
329
            message=b'another commit',
 
330
            committer=b'committer <committer@example.com>',
 
331
            author=b'author <author@example.com>')
 
332
        porcelain.tag_create(
 
333
            self.remote_real,
 
334
            tag=b"blah",
 
335
            author=b'author <author@example.com>',
 
336
            objectish=c1,
 
337
            tag_time=int(time.time()),
 
338
            tag_timezone=0,
 
339
            annotated=True,
 
340
            message=b"Annotated tag")
 
341
 
 
342
        remote = ControlDir.open(self.remote_url)
 
343
        self.make_controldir('local', format=self._to_format)
 
344
        local = remote.sprout(
 
345
            'local',
 
346
            revision_id=default_mapping.revision_id_foreign_to_bzr(c1))
 
347
        local_branch = local.open_branch()
 
348
        self.assertEqual(
 
349
            default_mapping.revision_id_foreign_to_bzr(c1),
 
350
            local_branch.last_revision())
 
351
        self.assertEqual(
 
352
            {'blah': default_mapping.revision_id_foreign_to_bzr(c1)},
 
353
            local_branch.tags.get_tag_dict())
 
354
 
 
355
 
 
356
class FetchFromRemoteToBzrTests(FetchFromRemoteTestBase, TestCaseWithTransport):
 
357
 
 
358
    _to_format = '2a'
 
359
 
 
360
 
 
361
class FetchFromRemoteToGitTests(FetchFromRemoteTestBase, TestCaseWithTransport):
 
362
 
 
363
    _to_format = 'git'
 
364
 
 
365
 
 
366
class PushToRemoteBase(object):
 
367
 
 
368
    _test_needs_features = [ExecutableFeature('git')]
 
369
 
 
370
    _from_format = None
 
371
 
 
372
    def setUp(self):
 
373
        TestCaseWithTransport.setUp(self)
 
374
        self.remote_real = GitRepo.init('remote', mkdir=True)
 
375
        self.remote_url = 'git://%s/' % os.path.abspath(self.remote_real.path)
 
376
        self.permit_url(self.remote_url)
 
377
 
 
378
    def test_push_branch_new(self):
 
379
        remote = ControlDir.open(self.remote_url)
 
380
        wt = self.make_branch_and_tree('local', format=self._from_format)
 
381
        self.build_tree(['local/blah'])
 
382
        wt.add(['blah'])
 
383
        revid = wt.commit('blah')
 
384
 
 
385
        if self._from_format == 'git':
 
386
            result = remote.push_branch(wt.branch, name='newbranch')
 
387
        else:
 
388
            result = remote.push_branch(
 
389
                wt.branch, lossy=True, name='newbranch')
 
390
 
 
391
        self.assertEqual(0, result.old_revno)
 
392
        if self._from_format == 'git':
 
393
            self.assertEqual(1, result.new_revno)
 
394
        else:
 
395
            self.assertIs(None, result.new_revno)
 
396
 
 
397
        result.report(BytesIO())
 
398
 
 
399
        self.assertEqual(
 
400
            {b'refs/heads/newbranch': self.remote_real.refs[b'refs/heads/newbranch'],
 
401
             },
 
402
            self.remote_real.get_refs())
 
403
 
 
404
    def test_push_branch_symref(self):
 
405
        cfg = self.remote_real.get_config()
 
406
        cfg.set((b'core', ), b'bare', True)
 
407
        cfg.write_to_path()
 
408
        self.remote_real.refs.set_symbolic_ref(b'HEAD', b'refs/heads/master')
 
409
        c1 = self.remote_real.do_commit(
 
410
            message=b'message',
 
411
            committer=b'committer <committer@example.com>',
 
412
            author=b'author <author@example.com>',
 
413
            ref=b'refs/heads/master')
 
414
        remote = ControlDir.open(self.remote_url)
 
415
        wt = self.make_branch_and_tree('local', format=self._from_format)
 
416
        self.build_tree(['local/blah'])
 
417
        wt.add(['blah'])
 
418
        revid = wt.commit('blah')
 
419
 
 
420
        if self._from_format == 'git':
 
421
            result = remote.push_branch(wt.branch, overwrite=True)
 
422
        else:
 
423
            result = remote.push_branch(wt.branch, lossy=True, overwrite=True)
 
424
 
 
425
        self.assertEqual(None, result.old_revno)
 
426
        if self._from_format == 'git':
 
427
            self.assertEqual(1, result.new_revno)
 
428
        else:
 
429
            self.assertIs(None, result.new_revno)
 
430
 
 
431
        result.report(BytesIO())
 
432
 
 
433
        self.assertEqual(
 
434
            {
 
435
                b'HEAD': self.remote_real.refs[b'refs/heads/master'],
 
436
                b'refs/heads/master': self.remote_real.refs[b'refs/heads/master'],
 
437
            },
 
438
            self.remote_real.get_refs())
 
439
 
 
440
    def test_push_branch_new_with_tags(self):
 
441
        remote = ControlDir.open(self.remote_url)
 
442
        builder = self.make_branch_builder('local', format=self._from_format)
 
443
        builder.start_series()
 
444
        rev_1 = builder.build_snapshot(None, [
 
445
            ('add', ('', None, 'directory', '')),
 
446
            ('add', ('filename', None, 'file', b'content'))])
 
447
        rev_2 = builder.build_snapshot(
 
448
            [rev_1], [('modify', ('filename', b'new-content\n'))])
 
449
        rev_3 = builder.build_snapshot(
 
450
            [rev_1], [('modify', ('filename', b'new-new-content\n'))])
 
451
        builder.finish_series()
 
452
        branch = builder.get_branch()
 
453
        try:
 
454
            branch.tags.set_tag('atag', rev_2)
 
455
        except TagsNotSupported:
 
456
            raise TestNotApplicable('source format does not support tags')
 
457
 
 
458
        branch.get_config_stack().set('branch.fetch_tags', True)
 
459
        if self._from_format == 'git':
 
460
            result = remote.push_branch(branch, name='newbranch')
 
461
        else:
 
462
            result = remote.push_branch(
 
463
                branch, lossy=True, name='newbranch')
 
464
 
 
465
        self.assertEqual(0, result.old_revno)
 
466
        if self._from_format == 'git':
 
467
            self.assertEqual(2, result.new_revno)
 
468
        else:
 
469
            self.assertIs(None, result.new_revno)
 
470
 
 
471
        result.report(BytesIO())
 
472
 
 
473
        self.assertEqual(
 
474
            {b'refs/heads/newbranch', b'refs/tags/atag'},
 
475
            set(self.remote_real.get_refs().keys()))
 
476
 
 
477
    def test_push(self):
 
478
        c1 = self.remote_real.do_commit(
 
479
            message=b'message',
 
480
            committer=b'committer <committer@example.com>',
 
481
            author=b'author <author@example.com>')
 
482
 
 
483
        remote = ControlDir.open(self.remote_url)
 
484
        self.make_controldir('local', format=self._from_format)
 
485
        local = remote.sprout('local')
 
486
        self.build_tree(['local/blah'])
 
487
        wt = local.open_workingtree()
 
488
        wt.add(['blah'])
 
489
        revid = wt.commit('blah')
 
490
        wt.branch.tags.set_tag('sometag', revid)
 
491
        wt.branch.get_config_stack().set('branch.fetch_tags', True)
 
492
 
 
493
        if self._from_format == 'git':
 
494
            result = wt.branch.push(remote.create_branch('newbranch'))
 
495
        else:
 
496
            result = wt.branch.push(
 
497
                remote.create_branch('newbranch'), lossy=True)
 
498
 
 
499
        self.assertEqual(0, result.old_revno)
 
500
        self.assertEqual(2, result.new_revno)
 
501
 
 
502
        result.report(BytesIO())
 
503
 
 
504
        self.assertEqual(
 
505
            {b'refs/heads/master': self.remote_real.head(),
 
506
             b'HEAD': self.remote_real.head(),
 
507
             b'refs/heads/newbranch': self.remote_real.refs[b'refs/heads/newbranch'],
 
508
             b'refs/tags/sometag': self.remote_real.refs[b'refs/heads/newbranch'],
 
509
             },
 
510
            self.remote_real.get_refs())
 
511
 
 
512
    def test_push_diverged(self):
 
513
        c1 = self.remote_real.do_commit(
 
514
            message=b'message',
 
515
            committer=b'committer <committer@example.com>',
 
516
            author=b'author <author@example.com>',
 
517
            ref=b'refs/heads/newbranch')
 
518
 
 
519
        remote = ControlDir.open(self.remote_url)
 
520
        wt = self.make_branch_and_tree('local', format=self._from_format)
 
521
        self.build_tree(['local/blah'])
 
522
        wt.add(['blah'])
 
523
        revid = wt.commit('blah')
 
524
 
 
525
        newbranch = remote.open_branch('newbranch')
 
526
        if self._from_format == 'git':
 
527
            self.assertRaises(DivergedBranches, wt.branch.push, newbranch)
 
528
        else:
 
529
            self.assertRaises(DivergedBranches, wt.branch.push,
 
530
                              newbranch, lossy=True)
 
531
 
 
532
        self.assertEqual(
 
533
            {b'refs/heads/newbranch': c1},
 
534
            self.remote_real.get_refs())
 
535
 
 
536
        if self._from_format == 'git':
 
537
            wt.branch.push(newbranch, overwrite=True)
 
538
        else:
 
539
            wt.branch.push(newbranch, lossy=True, overwrite=True)
 
540
 
 
541
        self.assertNotEqual(c1, self.remote_real.refs[b'refs/heads/newbranch'])
 
542
 
 
543
 
 
544
class PushToRemoteFromBzrTests(PushToRemoteBase, TestCaseWithTransport):
 
545
 
 
546
    _from_format = '2a'
 
547
 
 
548
 
 
549
class PushToRemoteFromGitTests(PushToRemoteBase, TestCaseWithTransport):
 
550
 
 
551
    _from_format = 'git'
 
552
 
 
553
 
 
554
class RemoteControlDirTests(TestCaseWithTransport):
 
555
 
 
556
    _test_needs_features = [ExecutableFeature('git')]
 
557
 
 
558
    def setUp(self):
 
559
        TestCaseWithTransport.setUp(self)
 
560
        self.remote_real = GitRepo.init('remote', mkdir=True)
 
561
        self.remote_url = 'git://%s/' % os.path.abspath(self.remote_real.path)
 
562
        self.permit_url(self.remote_url)
 
563
 
 
564
    def test_remove_branch(self):
 
565
        c1 = self.remote_real.do_commit(
 
566
            message=b'message',
 
567
            committer=b'committer <committer@example.com>',
 
568
            author=b'author <author@example.com>')
 
569
        c2 = self.remote_real.do_commit(
 
570
            message=b'another commit',
 
571
            committer=b'committer <committer@example.com>',
 
572
            author=b'author <author@example.com>',
 
573
            ref=b'refs/heads/blah')
 
574
 
 
575
        remote = ControlDir.open(self.remote_url)
 
576
        remote.destroy_branch(name='blah')
 
577
        self.assertEqual(
 
578
            self.remote_real.get_refs(),
 
579
            {b'refs/heads/master': self.remote_real.head(),
 
580
             b'HEAD': self.remote_real.head(),
 
581
             })
 
582
 
 
583
    def test_list_branches(self):
 
584
        c1 = self.remote_real.do_commit(
 
585
            message=b'message',
 
586
            committer=b'committer <committer@example.com>',
 
587
            author=b'author <author@example.com>')
 
588
        c2 = self.remote_real.do_commit(
 
589
            message=b'another commit',
 
590
            committer=b'committer <committer@example.com>',
 
591
            author=b'author <author@example.com>',
 
592
            ref=b'refs/heads/blah')
 
593
 
 
594
        remote = ControlDir.open(self.remote_url)
 
595
        self.assertEqual(
 
596
            set(['master', 'blah', 'master']),
 
597
            set([b.name for b in remote.list_branches()]))
 
598
 
 
599
    def test_get_branches(self):
 
600
        c1 = self.remote_real.do_commit(
 
601
            message=b'message',
 
602
            committer=b'committer <committer@example.com>',
 
603
            author=b'author <author@example.com>')
 
604
        c2 = self.remote_real.do_commit(
 
605
            message=b'another commit',
 
606
            committer=b'committer <committer@example.com>',
 
607
            author=b'author <author@example.com>',
 
608
            ref=b'refs/heads/blah')
 
609
 
 
610
        remote = ControlDir.open(self.remote_url)
 
611
        self.assertEqual(
 
612
            {'': 'master', 'blah': 'blah', 'master': 'master'},
 
613
            {n: b.name for (n, b) in remote.get_branches().items()})
 
614
        self.assertEqual(
 
615
            set(['', 'blah', 'master']), set(remote.branch_names()))
 
616
 
 
617
    def test_remove_tag(self):
 
618
        c1 = self.remote_real.do_commit(
 
619
            message=b'message',
 
620
            committer=b'committer <committer@example.com>',
 
621
            author=b'author <author@example.com>')
 
622
        c2 = self.remote_real.do_commit(
 
623
            message=b'another commit',
 
624
            committer=b'committer <committer@example.com>',
 
625
            author=b'author <author@example.com>',
 
626
            ref=b'refs/tags/blah')
 
627
 
 
628
        remote = ControlDir.open(self.remote_url)
 
629
        remote_branch = remote.open_branch()
 
630
        remote_branch.tags.delete_tag('blah')
 
631
        self.assertRaises(NoSuchTag, remote_branch.tags.delete_tag, 'blah')
 
632
        self.assertEqual(
 
633
            self.remote_real.get_refs(),
 
634
            {b'refs/heads/master': self.remote_real.head(),
 
635
             b'HEAD': self.remote_real.head(),
 
636
             })
 
637
 
 
638
    def test_set_tag(self):
 
639
        c1 = self.remote_real.do_commit(
 
640
            message=b'message',
 
641
            committer=b'committer <committer@example.com>',
 
642
            author=b'author <author@example.com>')
 
643
        c2 = self.remote_real.do_commit(
 
644
            message=b'another commit',
 
645
            committer=b'committer <committer@example.com>',
 
646
            author=b'author <author@example.com>')
 
647
 
 
648
        remote = ControlDir.open(self.remote_url)
 
649
        remote.open_branch().tags.set_tag(
 
650
            b'blah', default_mapping.revision_id_foreign_to_bzr(c1))
 
651
        self.assertEqual(
 
652
            self.remote_real.get_refs(),
 
653
            {b'refs/heads/master': self.remote_real.head(),
 
654
             b'refs/tags/blah': c1,
 
655
             b'HEAD': self.remote_real.head(),
 
656
             })
 
657
 
 
658
    def test_annotated_tag(self):
 
659
        c1 = self.remote_real.do_commit(
 
660
            message=b'message',
 
661
            committer=b'committer <committer@example.com>',
 
662
            author=b'author <author@example.com>')
 
663
        c2 = self.remote_real.do_commit(
 
664
            message=b'another commit',
 
665
            committer=b'committer <committer@example.com>',
 
666
            author=b'author <author@example.com>')
 
667
 
 
668
        porcelain.tag_create(
 
669
            self.remote_real,
 
670
            tag=b"blah",
 
671
            author=b'author <author@example.com>',
 
672
            objectish=c2,
 
673
            tag_time=int(time.time()),
 
674
            tag_timezone=0,
 
675
            annotated=True,
 
676
            message=b"Annotated tag")
 
677
 
 
678
        remote = ControlDir.open(self.remote_url)
 
679
        remote_branch = remote.open_branch()
 
680
        self.assertEqual({
 
681
            'blah': default_mapping.revision_id_foreign_to_bzr(c2)},
 
682
            remote_branch.tags.get_tag_dict())
 
683
 
 
684
    def test_get_branch_reference(self):
 
685
        c1 = self.remote_real.do_commit(
 
686
            message=b'message',
 
687
            committer=b'committer <committer@example.com>',
 
688
            author=b'author <author@example.com>')
 
689
        c2 = self.remote_real.do_commit(
 
690
            message=b'another commit',
 
691
            committer=b'committer <committer@example.com>',
 
692
            author=b'author <author@example.com>')
 
693
 
 
694
        remote = ControlDir.open(self.remote_url)
 
695
        self.assertEqual(b'refs/heads/master', remote.get_branch_reference(''))
 
696
        self.assertEqual(None, remote.get_branch_reference('master'))
 
697
 
 
698
    def test_get_branch_nick(self):
 
699
        c1 = self.remote_real.do_commit(
 
700
            message=b'message',
 
701
            committer=b'committer <committer@example.com>',
 
702
            author=b'author <author@example.com>')
 
703
        remote = ControlDir.open(self.remote_url)
 
704
        self.assertEqual('master', remote.open_branch().nick)
 
705
 
 
706
 
 
707
class GitUrlAndPathFromTransportTests(TestCase):
 
708
 
 
709
    def test_file(self):
 
710
        split_url = _git_url_and_path_from_transport('file:///home/blah')
 
711
        self.assertEqual(split_url.scheme, 'file')
 
712
        self.assertEqual(split_url.path, '/home/blah')
 
713
 
 
714
    def test_file_segment_params(self):
 
715
        split_url = _git_url_and_path_from_transport('file:///home/blah,branch=master')
 
716
        self.assertEqual(split_url.scheme, 'file')
 
717
        self.assertEqual(split_url.path, '/home/blah')
 
718
 
 
719
    def test_git_smart(self):
 
720
        split_url = _git_url_and_path_from_transport(
 
721
            'git://github.com/dulwich/dulwich,branch=master')
 
722
        self.assertEqual(split_url.scheme, 'git')
 
723
        self.assertEqual(split_url.path, '/dulwich/dulwich')
 
724
 
 
725
    def test_https(self):
 
726
        split_url = _git_url_and_path_from_transport(
 
727
            'https://github.com/dulwich/dulwich')
 
728
        self.assertEqual(split_url.scheme, 'https')
 
729
        self.assertEqual(split_url.path, '/dulwich/dulwich')
 
730
 
 
731
    def test_https_segment_params(self):
 
732
        split_url = _git_url_and_path_from_transport(
 
733
            'https://github.com/dulwich/dulwich,branch=master')
 
734
        self.assertEqual(split_url.scheme, 'https')
 
735
        self.assertEqual(split_url.path, '/dulwich/dulwich')