1
 
# Copyright (C) 2007 Canonical Ltd
 
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.
 
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.
 
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
 
"""Test our ability to build up test repositories"""
 
19
 
from cStringIO import StringIO
 
21
 
from dulwich.repo import Repo as GitRepo
 
23
 
from bzrlib.plugins.git import tests
 
26
 
class TestGitBranchBuilder(tests.TestCase):
 
28
 
    def test__create_blob(self):
 
30
 
        builder = tests.GitBranchBuilder(stream)
 
31
 
        self.assertEqual(1, builder._create_blob('foo\nbar\n'))
 
32
 
        self.assertEqualDiff('blob\nmark :1\ndata 8\nfoo\nbar\n\n',
 
35
 
    def test_set_file(self):
 
37
 
        builder = tests.GitBranchBuilder(stream)
 
38
 
        builder.set_file('foobar', 'foo\nbar\n', False)
 
39
 
        self.assertEqualDiff('blob\nmark :1\ndata 8\nfoo\nbar\n\n',
 
41
 
        self.assertEqual(['M 100644 :1 foobar\n'], builder.commit_info)
 
43
 
    def test_set_file_unicode(self):
 
45
 
        builder = tests.GitBranchBuilder(stream)
 
46
 
        builder.set_file(u'f\xb5/bar', 'contents\nbar\n', False)
 
47
 
        self.assertEqualDiff('blob\nmark :1\ndata 13\ncontents\nbar\n\n',
 
49
 
        self.assertEqual(['M 100644 :1 f\xc2\xb5/bar\n'], builder.commit_info)
 
51
 
    def test_set_file_newline(self):
 
53
 
        builder = tests.GitBranchBuilder(stream)
 
54
 
        builder.set_file(u'foo\nbar', 'contents\nbar\n', False)
 
55
 
        self.assertEqualDiff('blob\nmark :1\ndata 13\ncontents\nbar\n\n',
 
57
 
        self.assertEqual(['M 100644 :1 "foo\\nbar"\n'], builder.commit_info)
 
59
 
    def test_set_file_executable(self):
 
61
 
        builder = tests.GitBranchBuilder(stream)
 
62
 
        builder.set_file(u'f\xb5/bar', 'contents\nbar\n', True)
 
63
 
        self.assertEqualDiff('blob\nmark :1\ndata 13\ncontents\nbar\n\n',
 
65
 
        self.assertEqual(['M 100755 :1 f\xc2\xb5/bar\n'], builder.commit_info)
 
67
 
    def test_set_link(self):
 
69
 
        builder = tests.GitBranchBuilder(stream)
 
70
 
        builder.set_link(u'f\xb5/bar', 'link/contents')
 
71
 
        self.assertEqualDiff('blob\nmark :1\ndata 13\nlink/contents\n',
 
73
 
        self.assertEqual(['M 120000 :1 f\xc2\xb5/bar\n'], builder.commit_info)
 
75
 
    def test_set_link_newline(self):
 
77
 
        builder = tests.GitBranchBuilder(stream)
 
78
 
        builder.set_link(u'foo\nbar', 'link/contents')
 
79
 
        self.assertEqualDiff('blob\nmark :1\ndata 13\nlink/contents\n',
 
81
 
        self.assertEqual(['M 120000 :1 "foo\\nbar"\n'], builder.commit_info)
 
83
 
    def test_delete_entry(self):
 
85
 
        builder = tests.GitBranchBuilder(stream)
 
86
 
        builder.delete_entry(u'path/to/f\xb5')
 
87
 
        self.assertEqual(['D path/to/f\xc2\xb5\n'], builder.commit_info)
 
89
 
    def test_delete_entry_newline(self):
 
91
 
        builder = tests.GitBranchBuilder(stream)
 
92
 
        builder.delete_entry(u'path/to/foo\nbar')
 
93
 
        self.assertEqual(['D "path/to/foo\\nbar"\n'], builder.commit_info)
 
95
 
    def test_encode_path(self):
 
96
 
        encode = tests.GitBranchBuilder._encode_path
 
97
 
        # Unicode is encoded to utf-8
 
98
 
        self.assertEqual(encode(u'f\xb5'), 'f\xc2\xb5')
 
99
 
        # The name must be quoted if it starts by a double quote or contains a
 
101
 
        self.assertEqual(encode(u'"foo'), '"\\"foo"')
 
102
 
        self.assertEqual(encode(u'fo\no'), '"fo\\no"')
 
103
 
        # When the name is quoted, all backslash and quote chars must be
 
105
 
        self.assertEqual(encode(u'fo\\o\nbar'), '"fo\\\\o\\nbar"')
 
106
 
        self.assertEqual(encode(u'fo"o"\nbar'), '"fo\\"o\\"\\nbar"')
 
107
 
        # Other control chars, such as \r, need not be escaped.
 
108
 
        self.assertEqual(encode(u'foo\r\nbar'), '"foo\r\\nbar"')
 
110
 
    def test_add_and_commit(self):
 
112
 
        builder = tests.GitBranchBuilder(stream)
 
114
 
        builder.set_file(u'f\xb5/bar', 'contents\nbar\n', False)
 
115
 
        self.assertEqual(2, builder.commit('Joe Foo <joe@foo.com>',
 
116
 
                                           u'committing f\xb5/bar',
 
117
 
                                           timestamp=1194586400,
 
119
 
        self.assertEqualDiff('blob\nmark :1\ndata 13\ncontents\nbar\n\n'
 
120
 
                             'commit refs/heads/master\n'
 
122
 
                             'committer Joe Foo <joe@foo.com> 1194586400 +0100\n'
 
124
 
                             'committing f\xc2\xb5/bar'
 
126
 
                             'M 100644 :1 f\xc2\xb5/bar\n'
 
130
 
    def test_commit_base(self):
 
132
 
        builder = tests.GitBranchBuilder(stream)
 
134
 
        builder.set_file(u'foo', 'contents\nfoo\n', False)
 
135
 
        r1 = builder.commit('Joe Foo <joe@foo.com>', u'first',
 
136
 
                            timestamp=1194586400)
 
137
 
        r2 = builder.commit('Joe Foo <joe@foo.com>', u'second',
 
138
 
                            timestamp=1194586405)
 
139
 
        r3 = builder.commit('Joe Foo <joe@foo.com>', u'third',
 
140
 
                            timestamp=1194586410,
 
143
 
        self.assertEqualDiff('blob\nmark :1\ndata 13\ncontents\nfoo\n\n'
 
144
 
                             'commit refs/heads/master\n'
 
146
 
                             'committer Joe Foo <joe@foo.com> 1194586400 +0000\n'
 
152
 
                             'commit refs/heads/master\n'
 
154
 
                             'committer Joe Foo <joe@foo.com> 1194586405 +0000\n'
 
159
 
                             'commit refs/heads/master\n'
 
161
 
                             'committer Joe Foo <joe@foo.com> 1194586410 +0000\n'
 
166
 
                             '\n', stream.getvalue())
 
168
 
    def test_commit_merge(self):
 
170
 
        builder = tests.GitBranchBuilder(stream)
 
172
 
        builder.set_file(u'foo', 'contents\nfoo\n', False)
 
173
 
        r1 = builder.commit('Joe Foo <joe@foo.com>', u'first',
 
174
 
                            timestamp=1194586400)
 
175
 
        r2 = builder.commit('Joe Foo <joe@foo.com>', u'second',
 
176
 
                            timestamp=1194586405)
 
177
 
        r3 = builder.commit('Joe Foo <joe@foo.com>', u'third',
 
178
 
                            timestamp=1194586410,
 
180
 
        r4 = builder.commit('Joe Foo <joe@foo.com>', u'Merge',
 
181
 
                            timestamp=1194586415,
 
184
 
        self.assertEqualDiff('blob\nmark :1\ndata 13\ncontents\nfoo\n\n'
 
185
 
                             'commit refs/heads/master\n'
 
187
 
                             'committer Joe Foo <joe@foo.com> 1194586400 +0000\n'
 
193
 
                             'commit refs/heads/master\n'
 
195
 
                             'committer Joe Foo <joe@foo.com> 1194586405 +0000\n'
 
200
 
                             'commit refs/heads/master\n'
 
202
 
                             'committer Joe Foo <joe@foo.com> 1194586410 +0000\n'
 
208
 
                             'commit refs/heads/master\n'
 
210
 
                             'committer Joe Foo <joe@foo.com> 1194586415 +0000\n'
 
215
 
                             '\n', stream.getvalue())
 
217
 
    def test_auto_timestamp(self):
 
219
 
        builder = tests.GitBranchBuilder(stream)
 
220
 
        builder.commit('Joe Foo <joe@foo.com>', u'message')
 
221
 
        self.assertContainsRe(stream.getvalue(),
 
222
 
                              r'committer Joe Foo <joe@foo\.com> \d+ \+0000')
 
224
 
    def test_reset(self):
 
226
 
        builder = tests.GitBranchBuilder(stream)
 
228
 
        self.assertEqualDiff('reset refs/heads/master\n\n', stream.getvalue())
 
230
 
    def test_reset_named_ref(self):
 
232
 
        builder = tests.GitBranchBuilder(stream)
 
233
 
        builder.reset('refs/heads/branch')
 
234
 
        self.assertEqualDiff('reset refs/heads/branch\n\n', stream.getvalue())
 
236
 
    def test_reset_revision(self):
 
238
 
        builder = tests.GitBranchBuilder(stream)
 
239
 
        builder.reset(mark=123)
 
240
 
        self.assertEqualDiff(
 
241
 
            'reset refs/heads/master\n'
 
243
 
            '\n', stream.getvalue())
 
246
 
class TestGitBranchBuilderReal(tests.TestCaseInTempDir):
 
248
 
    def test_create_real_branch(self):
 
251
 
        builder = tests.GitBranchBuilder()
 
252
 
        builder.set_file(u'foo', 'contents\nfoo\n', False)
 
253
 
        r1 = builder.commit('Joe Foo <joe@foo.com>', u'first',
 
254
 
                            timestamp=1194586400)
 
255
 
        mapping = builder.finish()
 
256
 
        self.assertEqual({1:'44411e8e9202177dd19b6599d7a7991059fa3cb4',
 
257
 
                          2: 'b0b62e674f67306fddcf72fa888c3b56df100d64',