/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-09-02 11:51:19 UTC
  • mto: (7490.40.109 work)
  • mto: This revision was merged to the branch mainline in revision 7526.
  • Revision ID: jelmer@jelmer.uk-20200902115119-otuspc349t9rmhua
add test for git file merge.

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