/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-18 15:20:23 UTC
  • mto: (7490.40.61 work)
  • mto: This revision was merged to the branch mainline in revision 7519.
  • Revision ID: jelmer@jelmer.uk-20200718152023-cabh92o24ke217te
Ignore missing revs.

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
    def test_invalid_git_error(self):
 
149
        self.assertEqual(
 
150
            PermissionDenied(
 
151
                'url',
 
152
                'GitLab: You are not allowed to push code to protected '
 
153
                'branches on this project.'),
 
154
            parse_git_error(
 
155
                'url',
 
156
                RemoteGitError(
 
157
                    'GitLab: You are not allowed to push code to '
 
158
                    'protected branches on this project.')))
 
159
 
 
160
 
 
161
class ParseHangupTests(TestCase):
 
162
 
 
163
    def setUp(self):
 
164
        super(ParseHangupTests, self).setUp()
 
165
        try:
 
166
            HangupException([b'foo'])
 
167
        except TypeError:
 
168
            self.skipTest('dulwich version too old')
 
169
 
 
170
    def test_not_set(self):
 
171
        self.assertIsInstance(
 
172
            parse_git_hangup('http://', HangupException()), HangupException)
 
173
 
 
174
    def test_single_line(self):
 
175
        self.assertEqual(
 
176
            RemoteGitError('foo bar'),
 
177
            parse_git_hangup('http://', HangupException([b'foo bar'])))
 
178
 
 
179
    def test_multi_lines(self):
 
180
        self.assertEqual(
 
181
            RemoteGitError('foo bar\nbla bla'),
 
182
            parse_git_hangup(
 
183
                'http://', HangupException([b'foo bar', b'bla bla'])))
 
184
 
 
185
    def test_filter_boring(self):
 
186
        self.assertEqual(
 
187
            RemoteGitError('foo bar'), parse_git_hangup('http://', HangupException(
 
188
                [b'=======', b'foo bar', b'======'])))
 
189
        self.assertEqual(
 
190
            RemoteGitError('foo bar'), parse_git_hangup('http://', HangupException(
 
191
                [b'remote: =======', b'remote: foo bar', b'remote: ======'])))
 
192
 
 
193
    def test_permission_denied(self):
 
194
        self.assertEqual(
 
195
            PermissionDenied('http://', 'You are not allowed to push code to this project.'),
 
196
            parse_git_hangup(
 
197
                'http://',
 
198
                HangupException(
 
199
                    [b'=======',
 
200
                     b'You are not allowed to push code to this project.', b'', b'======'])))
 
201
 
 
202
 
 
203
class TestRemoteGitBranchFormat(TestCase):
 
204
 
 
205
    def setUp(self):
 
206
        super(TestRemoteGitBranchFormat, self).setUp()
 
207
        self.format = RemoteGitBranchFormat()
 
208
 
 
209
    def test_get_format_description(self):
 
210
        self.assertEqual("Remote Git Branch",
 
211
                         self.format.get_format_description())
 
212
 
 
213
    def test_get_network_name(self):
 
214
        self.assertEqual(b"git", self.format.network_name())
 
215
 
 
216
    def test_supports_tags(self):
 
217
        self.assertTrue(self.format.supports_tags())
 
218
 
 
219
 
 
220
class TestRemoteGitBranch(TestCaseWithTransport):
 
221
 
 
222
    _test_needs_features = [ExecutableFeature('git')]
 
223
 
 
224
    def setUp(self):
 
225
        TestCaseWithTransport.setUp(self)
 
226
        self.remote_real = GitRepo.init('remote', mkdir=True)
 
227
        self.remote_url = 'git://%s/' % os.path.abspath(self.remote_real.path)
 
228
        self.permit_url(self.remote_url)
 
229
 
 
230
    def test_set_last_revision_info(self):
 
231
        c1 = self.remote_real.do_commit(
 
232
            message=b'message 1',
 
233
            committer=b'committer <committer@example.com>',
 
234
            author=b'author <author@example.com>',
 
235
            ref=b'refs/heads/newbranch')
 
236
        c2 = self.remote_real.do_commit(
 
237
            message=b'message 2',
 
238
            committer=b'committer <committer@example.com>',
 
239
            author=b'author <author@example.com>',
 
240
            ref=b'refs/heads/newbranch')
 
241
 
 
242
        remote = ControlDir.open(self.remote_url)
 
243
        newbranch = remote.open_branch('newbranch')
 
244
        self.assertEqual(newbranch.lookup_foreign_revision_id(c2),
 
245
                         newbranch.last_revision())
 
246
        newbranch.set_last_revision_info(
 
247
            1, newbranch.lookup_foreign_revision_id(c1))
 
248
        self.assertEqual(c1, self.remote_real.refs[b'refs/heads/newbranch'])
 
249
        self.assertEqual(newbranch.last_revision(),
 
250
                         newbranch.lookup_foreign_revision_id(c1))
 
251
 
 
252
 
 
253
class FetchFromRemoteTestBase(object):
 
254
 
 
255
    _test_needs_features = [ExecutableFeature('git')]
 
256
 
 
257
    _to_format = None
 
258
 
 
259
    def setUp(self):
 
260
        TestCaseWithTransport.setUp(self)
 
261
        self.remote_real = GitRepo.init('remote', mkdir=True)
 
262
        self.remote_url = 'git://%s/' % os.path.abspath(self.remote_real.path)
 
263
        self.permit_url(self.remote_url)
 
264
 
 
265
    def test_sprout_simple(self):
 
266
        self.remote_real.do_commit(
 
267
            message=b'message',
 
268
            committer=b'committer <committer@example.com>',
 
269
            author=b'author <author@example.com>')
 
270
 
 
271
        remote = ControlDir.open(self.remote_url)
 
272
        self.make_controldir('local', format=self._to_format)
 
273
        local = remote.sprout('local')
 
274
        self.assertEqual(
 
275
            default_mapping.revision_id_foreign_to_bzr(
 
276
                self.remote_real.head()),
 
277
            local.open_branch().last_revision())
 
278
 
 
279
    def test_sprout_with_tags(self):
 
280
        c1 = self.remote_real.do_commit(
 
281
            message=b'message',
 
282
            committer=b'committer <committer@example.com>',
 
283
            author=b'author <author@example.com>')
 
284
        c2 = self.remote_real.do_commit(
 
285
            message=b'another commit',
 
286
            committer=b'committer <committer@example.com>',
 
287
            author=b'author <author@example.com>',
 
288
            ref=b'refs/tags/another')
 
289
        self.remote_real.refs[b'refs/tags/blah'] = self.remote_real.head()
 
290
 
 
291
        remote = ControlDir.open(self.remote_url)
 
292
        self.make_controldir('local', format=self._to_format)
 
293
        local = remote.sprout('local')
 
294
        local_branch = local.open_branch()
 
295
        self.assertEqual(
 
296
            default_mapping.revision_id_foreign_to_bzr(c1),
 
297
            local_branch.last_revision())
 
298
        self.assertEqual(
 
299
            {'blah': local_branch.last_revision(),
 
300
             'another': default_mapping.revision_id_foreign_to_bzr(c2)},
 
301
            local_branch.tags.get_tag_dict())
 
302
 
 
303
    def test_sprout_with_annotated_tag(self):
 
304
        c1 = self.remote_real.do_commit(
 
305
            message=b'message',
 
306
            committer=b'committer <committer@example.com>',
 
307
            author=b'author <author@example.com>')
 
308
        c2 = self.remote_real.do_commit(
 
309
            message=b'another commit',
 
310
            committer=b'committer <committer@example.com>',
 
311
            author=b'author <author@example.com>',
 
312
            ref=b'refs/heads/another')
 
313
        porcelain.tag_create(
 
314
            self.remote_real,
 
315
            tag=b"blah",
 
316
            author=b'author <author@example.com>',
 
317
            objectish=c2,
 
318
            tag_time=int(time.time()),
 
319
            tag_timezone=0,
 
320
            annotated=True,
 
321
            message=b"Annotated tag")
 
322
 
 
323
        remote = ControlDir.open(self.remote_url)
 
324
        self.make_controldir('local', format=self._to_format)
 
325
        local = remote.sprout(
 
326
            'local', revision_id=default_mapping.revision_id_foreign_to_bzr(c1))
 
327
        local_branch = local.open_branch()
 
328
        self.assertEqual(
 
329
            default_mapping.revision_id_foreign_to_bzr(c1),
 
330
            local_branch.last_revision())
 
331
        self.assertEqual(
 
332
            {'blah': default_mapping.revision_id_foreign_to_bzr(c2)},
 
333
            local_branch.tags.get_tag_dict())
 
334
 
 
335
    def test_sprout_with_annotated_tag_unreferenced(self):
 
336
        c1 = self.remote_real.do_commit(
 
337
            message=b'message',
 
338
            committer=b'committer <committer@example.com>',
 
339
            author=b'author <author@example.com>')
 
340
        c2 = self.remote_real.do_commit(
 
341
            message=b'another commit',
 
342
            committer=b'committer <committer@example.com>',
 
343
            author=b'author <author@example.com>')
 
344
        porcelain.tag_create(
 
345
            self.remote_real,
 
346
            tag=b"blah",
 
347
            author=b'author <author@example.com>',
 
348
            objectish=c1,
 
349
            tag_time=int(time.time()),
 
350
            tag_timezone=0,
 
351
            annotated=True,
 
352
            message=b"Annotated tag")
 
353
 
 
354
        remote = ControlDir.open(self.remote_url)
 
355
        self.make_controldir('local', format=self._to_format)
 
356
        local = remote.sprout(
 
357
            'local',
 
358
            revision_id=default_mapping.revision_id_foreign_to_bzr(c1))
 
359
        local_branch = local.open_branch()
 
360
        self.assertEqual(
 
361
            default_mapping.revision_id_foreign_to_bzr(c1),
 
362
            local_branch.last_revision())
 
363
        self.assertEqual(
 
364
            {'blah': default_mapping.revision_id_foreign_to_bzr(c1)},
 
365
            local_branch.tags.get_tag_dict())
 
366
 
 
367
 
 
368
class FetchFromRemoteToBzrTests(FetchFromRemoteTestBase, TestCaseWithTransport):
 
369
 
 
370
    _to_format = '2a'
 
371
 
 
372
 
 
373
class FetchFromRemoteToGitTests(FetchFromRemoteTestBase, TestCaseWithTransport):
 
374
 
 
375
    _to_format = 'git'
 
376
 
 
377
 
 
378
class PushToRemoteBase(object):
 
379
 
 
380
    _test_needs_features = [ExecutableFeature('git')]
 
381
 
 
382
    _from_format = None
 
383
 
 
384
    def setUp(self):
 
385
        TestCaseWithTransport.setUp(self)
 
386
        self.remote_real = GitRepo.init('remote', mkdir=True)
 
387
        self.remote_url = 'git://%s/' % os.path.abspath(self.remote_real.path)
 
388
        self.permit_url(self.remote_url)
 
389
 
 
390
    def test_push_branch_new(self):
 
391
        remote = ControlDir.open(self.remote_url)
 
392
        wt = self.make_branch_and_tree('local', format=self._from_format)
 
393
        self.build_tree(['local/blah'])
 
394
        wt.add(['blah'])
 
395
        revid = wt.commit('blah')
 
396
 
 
397
        if self._from_format == 'git':
 
398
            result = remote.push_branch(wt.branch, name='newbranch')
 
399
        else:
 
400
            result = remote.push_branch(
 
401
                wt.branch, lossy=True, name='newbranch')
 
402
 
 
403
        self.assertEqual(0, result.old_revno)
 
404
        if self._from_format == 'git':
 
405
            self.assertEqual(1, result.new_revno)
 
406
        else:
 
407
            self.assertIs(None, result.new_revno)
 
408
 
 
409
        result.report(BytesIO())
 
410
 
 
411
        self.assertEqual(
 
412
            {b'refs/heads/newbranch': self.remote_real.refs[b'refs/heads/newbranch'],
 
413
             },
 
414
            self.remote_real.get_refs())
 
415
 
 
416
    def test_push_branch_symref(self):
 
417
        cfg = self.remote_real.get_config()
 
418
        cfg.set((b'core', ), b'bare', True)
 
419
        cfg.write_to_path()
 
420
        self.remote_real.refs.set_symbolic_ref(b'HEAD', b'refs/heads/master')
 
421
        c1 = self.remote_real.do_commit(
 
422
            message=b'message',
 
423
            committer=b'committer <committer@example.com>',
 
424
            author=b'author <author@example.com>',
 
425
            ref=b'refs/heads/master')
 
426
        remote = ControlDir.open(self.remote_url)
 
427
        wt = self.make_branch_and_tree('local', format=self._from_format)
 
428
        self.build_tree(['local/blah'])
 
429
        wt.add(['blah'])
 
430
        revid = wt.commit('blah')
 
431
 
 
432
        if self._from_format == 'git':
 
433
            result = remote.push_branch(wt.branch, overwrite=True)
 
434
        else:
 
435
            result = remote.push_branch(wt.branch, lossy=True, overwrite=True)
 
436
 
 
437
        self.assertEqual(None, result.old_revno)
 
438
        if self._from_format == 'git':
 
439
            self.assertEqual(1, result.new_revno)
 
440
        else:
 
441
            self.assertIs(None, result.new_revno)
 
442
 
 
443
        result.report(BytesIO())
 
444
 
 
445
        self.assertEqual(
 
446
            {
 
447
                b'HEAD': self.remote_real.refs[b'refs/heads/master'],
 
448
                b'refs/heads/master': self.remote_real.refs[b'refs/heads/master'],
 
449
            },
 
450
            self.remote_real.get_refs())
 
451
 
 
452
    def test_push_branch_new_with_tags(self):
 
453
        remote = ControlDir.open(self.remote_url)
 
454
        builder = self.make_branch_builder('local', format=self._from_format)
 
455
        builder.start_series()
 
456
        rev_1 = builder.build_snapshot(None, [
 
457
            ('add', ('', None, 'directory', '')),
 
458
            ('add', ('filename', None, 'file', b'content'))])
 
459
        rev_2 = builder.build_snapshot(
 
460
            [rev_1], [('modify', ('filename', b'new-content\n'))])
 
461
        rev_3 = builder.build_snapshot(
 
462
            [rev_1], [('modify', ('filename', b'new-new-content\n'))])
 
463
        builder.finish_series()
 
464
        branch = builder.get_branch()
 
465
        try:
 
466
            branch.tags.set_tag('atag', rev_2)
 
467
        except TagsNotSupported:
 
468
            raise TestNotApplicable('source format does not support tags')
 
469
 
 
470
        branch.get_config_stack().set('branch.fetch_tags', True)
 
471
        if self._from_format == 'git':
 
472
            result = remote.push_branch(branch, name='newbranch')
 
473
        else:
 
474
            result = remote.push_branch(
 
475
                branch, lossy=True, name='newbranch')
 
476
 
 
477
        self.assertEqual(0, result.old_revno)
 
478
        if self._from_format == 'git':
 
479
            self.assertEqual(2, result.new_revno)
 
480
        else:
 
481
            self.assertIs(None, result.new_revno)
 
482
 
 
483
        result.report(BytesIO())
 
484
 
 
485
        self.assertEqual(
 
486
            {b'refs/heads/newbranch', b'refs/tags/atag'},
 
487
            set(self.remote_real.get_refs().keys()))
 
488
 
 
489
    def test_push(self):
 
490
        c1 = self.remote_real.do_commit(
 
491
            message=b'message',
 
492
            committer=b'committer <committer@example.com>',
 
493
            author=b'author <author@example.com>')
 
494
 
 
495
        remote = ControlDir.open(self.remote_url)
 
496
        self.make_controldir('local', format=self._from_format)
 
497
        local = remote.sprout('local')
 
498
        self.build_tree(['local/blah'])
 
499
        wt = local.open_workingtree()
 
500
        wt.add(['blah'])
 
501
        revid = wt.commit('blah')
 
502
        wt.branch.tags.set_tag('sometag', revid)
 
503
        wt.branch.get_config_stack().set('branch.fetch_tags', True)
 
504
 
 
505
        if self._from_format == 'git':
 
506
            result = wt.branch.push(remote.create_branch('newbranch'))
 
507
        else:
 
508
            result = wt.branch.push(
 
509
                remote.create_branch('newbranch'), lossy=True)
 
510
 
 
511
        self.assertEqual(0, result.old_revno)
 
512
        self.assertEqual(2, result.new_revno)
 
513
 
 
514
        result.report(BytesIO())
 
515
 
 
516
        self.assertEqual(
 
517
            {b'refs/heads/master': self.remote_real.head(),
 
518
             b'HEAD': self.remote_real.head(),
 
519
             b'refs/heads/newbranch': self.remote_real.refs[b'refs/heads/newbranch'],
 
520
             b'refs/tags/sometag': self.remote_real.refs[b'refs/heads/newbranch'],
 
521
             },
 
522
            self.remote_real.get_refs())
 
523
 
 
524
    def test_push_diverged(self):
 
525
        c1 = self.remote_real.do_commit(
 
526
            message=b'message',
 
527
            committer=b'committer <committer@example.com>',
 
528
            author=b'author <author@example.com>',
 
529
            ref=b'refs/heads/newbranch')
 
530
 
 
531
        remote = ControlDir.open(self.remote_url)
 
532
        wt = self.make_branch_and_tree('local', format=self._from_format)
 
533
        self.build_tree(['local/blah'])
 
534
        wt.add(['blah'])
 
535
        revid = wt.commit('blah')
 
536
 
 
537
        newbranch = remote.open_branch('newbranch')
 
538
        if self._from_format == 'git':
 
539
            self.assertRaises(DivergedBranches, wt.branch.push, newbranch)
 
540
        else:
 
541
            self.assertRaises(DivergedBranches, wt.branch.push,
 
542
                              newbranch, lossy=True)
 
543
 
 
544
        self.assertEqual(
 
545
            {b'refs/heads/newbranch': c1},
 
546
            self.remote_real.get_refs())
 
547
 
 
548
        if self._from_format == 'git':
 
549
            wt.branch.push(newbranch, overwrite=True)
 
550
        else:
 
551
            wt.branch.push(newbranch, lossy=True, overwrite=True)
 
552
 
 
553
        self.assertNotEqual(c1, self.remote_real.refs[b'refs/heads/newbranch'])
 
554
 
 
555
 
 
556
class PushToRemoteFromBzrTests(PushToRemoteBase, TestCaseWithTransport):
 
557
 
 
558
    _from_format = '2a'
 
559
 
 
560
 
 
561
class PushToRemoteFromGitTests(PushToRemoteBase, TestCaseWithTransport):
 
562
 
 
563
    _from_format = 'git'
 
564
 
 
565
 
 
566
class RemoteControlDirTests(TestCaseWithTransport):
 
567
 
 
568
    _test_needs_features = [ExecutableFeature('git')]
 
569
 
 
570
    def setUp(self):
 
571
        TestCaseWithTransport.setUp(self)
 
572
        self.remote_real = GitRepo.init('remote', mkdir=True)
 
573
        self.remote_url = 'git://%s/' % os.path.abspath(self.remote_real.path)
 
574
        self.permit_url(self.remote_url)
 
575
 
 
576
    def test_remove_branch(self):
 
577
        c1 = self.remote_real.do_commit(
 
578
            message=b'message',
 
579
            committer=b'committer <committer@example.com>',
 
580
            author=b'author <author@example.com>')
 
581
        c2 = self.remote_real.do_commit(
 
582
            message=b'another commit',
 
583
            committer=b'committer <committer@example.com>',
 
584
            author=b'author <author@example.com>',
 
585
            ref=b'refs/heads/blah')
 
586
 
 
587
        remote = ControlDir.open(self.remote_url)
 
588
        remote.destroy_branch(name='blah')
 
589
        self.assertEqual(
 
590
            self.remote_real.get_refs(),
 
591
            {b'refs/heads/master': self.remote_real.head(),
 
592
             b'HEAD': self.remote_real.head(),
 
593
             })
 
594
 
 
595
    def test_list_branches(self):
 
596
        c1 = self.remote_real.do_commit(
 
597
            message=b'message',
 
598
            committer=b'committer <committer@example.com>',
 
599
            author=b'author <author@example.com>')
 
600
        c2 = self.remote_real.do_commit(
 
601
            message=b'another commit',
 
602
            committer=b'committer <committer@example.com>',
 
603
            author=b'author <author@example.com>',
 
604
            ref=b'refs/heads/blah')
 
605
 
 
606
        remote = ControlDir.open(self.remote_url)
 
607
        self.assertEqual(
 
608
            set(['master', 'blah', 'master']),
 
609
            set([b.name for b in remote.list_branches()]))
 
610
 
 
611
    def test_get_branches(self):
 
612
        c1 = self.remote_real.do_commit(
 
613
            message=b'message',
 
614
            committer=b'committer <committer@example.com>',
 
615
            author=b'author <author@example.com>')
 
616
        c2 = self.remote_real.do_commit(
 
617
            message=b'another commit',
 
618
            committer=b'committer <committer@example.com>',
 
619
            author=b'author <author@example.com>',
 
620
            ref=b'refs/heads/blah')
 
621
 
 
622
        remote = ControlDir.open(self.remote_url)
 
623
        self.assertEqual(
 
624
            {'': 'master', 'blah': 'blah', 'master': 'master'},
 
625
            {n: b.name for (n, b) in remote.get_branches().items()})
 
626
        self.assertEqual(
 
627
            set(['', 'blah', 'master']), set(remote.branch_names()))
 
628
 
 
629
    def test_remove_tag(self):
 
630
        c1 = self.remote_real.do_commit(
 
631
            message=b'message',
 
632
            committer=b'committer <committer@example.com>',
 
633
            author=b'author <author@example.com>')
 
634
        c2 = self.remote_real.do_commit(
 
635
            message=b'another commit',
 
636
            committer=b'committer <committer@example.com>',
 
637
            author=b'author <author@example.com>',
 
638
            ref=b'refs/tags/blah')
 
639
 
 
640
        remote = ControlDir.open(self.remote_url)
 
641
        remote_branch = remote.open_branch()
 
642
        remote_branch.tags.delete_tag('blah')
 
643
        self.assertRaises(NoSuchTag, remote_branch.tags.delete_tag, 'blah')
 
644
        self.assertEqual(
 
645
            self.remote_real.get_refs(),
 
646
            {b'refs/heads/master': self.remote_real.head(),
 
647
             b'HEAD': self.remote_real.head(),
 
648
             })
 
649
 
 
650
    def test_set_tag(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
        c2 = self.remote_real.do_commit(
 
656
            message=b'another commit',
 
657
            committer=b'committer <committer@example.com>',
 
658
            author=b'author <author@example.com>')
 
659
 
 
660
        remote = ControlDir.open(self.remote_url)
 
661
        remote.open_branch().tags.set_tag(
 
662
            b'blah', default_mapping.revision_id_foreign_to_bzr(c1))
 
663
        self.assertEqual(
 
664
            self.remote_real.get_refs(),
 
665
            {b'refs/heads/master': self.remote_real.head(),
 
666
             b'refs/tags/blah': c1,
 
667
             b'HEAD': self.remote_real.head(),
 
668
             })
 
669
 
 
670
    def test_annotated_tag(self):
 
671
        c1 = self.remote_real.do_commit(
 
672
            message=b'message',
 
673
            committer=b'committer <committer@example.com>',
 
674
            author=b'author <author@example.com>')
 
675
        c2 = self.remote_real.do_commit(
 
676
            message=b'another commit',
 
677
            committer=b'committer <committer@example.com>',
 
678
            author=b'author <author@example.com>')
 
679
 
 
680
        porcelain.tag_create(
 
681
            self.remote_real,
 
682
            tag=b"blah",
 
683
            author=b'author <author@example.com>',
 
684
            objectish=c2,
 
685
            tag_time=int(time.time()),
 
686
            tag_timezone=0,
 
687
            annotated=True,
 
688
            message=b"Annotated tag")
 
689
 
 
690
        remote = ControlDir.open(self.remote_url)
 
691
        remote_branch = remote.open_branch()
 
692
        self.assertEqual({
 
693
            'blah': default_mapping.revision_id_foreign_to_bzr(c2)},
 
694
            remote_branch.tags.get_tag_dict())
 
695
 
 
696
    def test_get_branch_reference(self):
 
697
        c1 = self.remote_real.do_commit(
 
698
            message=b'message',
 
699
            committer=b'committer <committer@example.com>',
 
700
            author=b'author <author@example.com>')
 
701
        c2 = self.remote_real.do_commit(
 
702
            message=b'another commit',
 
703
            committer=b'committer <committer@example.com>',
 
704
            author=b'author <author@example.com>')
 
705
 
 
706
        remote = ControlDir.open(self.remote_url)
 
707
        self.assertEqual(b'refs/heads/master', remote.get_branch_reference(''))
 
708
        self.assertEqual(None, remote.get_branch_reference('master'))
 
709
 
 
710
    def test_get_branch_nick(self):
 
711
        c1 = self.remote_real.do_commit(
 
712
            message=b'message',
 
713
            committer=b'committer <committer@example.com>',
 
714
            author=b'author <author@example.com>')
 
715
        remote = ControlDir.open(self.remote_url)
 
716
        self.assertEqual('master', remote.open_branch().nick)
 
717
 
 
718
 
 
719
class GitUrlAndPathFromTransportTests(TestCase):
 
720
 
 
721
    def test_file(self):
 
722
        split_url = _git_url_and_path_from_transport('file:///home/blah')
 
723
        self.assertEqual(split_url.scheme, 'file')
 
724
        self.assertEqual(split_url.path, '/home/blah')
 
725
 
 
726
    def test_file_segment_params(self):
 
727
        split_url = _git_url_and_path_from_transport('file:///home/blah,branch=master')
 
728
        self.assertEqual(split_url.scheme, 'file')
 
729
        self.assertEqual(split_url.path, '/home/blah')
 
730
 
 
731
    def test_git_smart(self):
 
732
        split_url = _git_url_and_path_from_transport(
 
733
            'git://github.com/dulwich/dulwich,branch=master')
 
734
        self.assertEqual(split_url.scheme, 'git')
 
735
        self.assertEqual(split_url.path, '/dulwich/dulwich')
 
736
 
 
737
    def test_https(self):
 
738
        split_url = _git_url_and_path_from_transport(
 
739
            'https://github.com/dulwich/dulwich')
 
740
        self.assertEqual(split_url.scheme, 'https')
 
741
        self.assertEqual(split_url.path, '/dulwich/dulwich')
 
742
 
 
743
    def test_https_segment_params(self):
 
744
        split_url = _git_url_and_path_from_transport(
 
745
            'https://github.com/dulwich/dulwich,branch=master')
 
746
        self.assertEqual(split_url.scheme, 'https')
 
747
        self.assertEqual(split_url.path, '/dulwich/dulwich')