/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-03-22 01:35:14 UTC
  • mfrom: (7490.7.6 work)
  • mto: This revision was merged to the branch mainline in revision 7499.
  • Revision ID: jelmer@jelmer.uk-20200322013514-7vw1ntwho04rcuj3
merge lp:brz/3.1.

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