/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: Breezy landing bot
  • Author(s): Jelmer Vernooij
  • Date: 2020-08-23 01:15:41 UTC
  • mfrom: (7520.1.4 merge-3.1)
  • Revision ID: breezy.the.bot@gmail.com-20200823011541-nv0oh7nzaganx2qy
Merge lp:brz/3.1.

Merged from https://code.launchpad.net/~jelmer/brz/merge-3.1/+merge/389690

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