/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.358.2 by Jelmer Vernooij
Refresh copyright headers, add my email.
1
# Copyright (C) 2010-2018 Jelmer Vernooij <jelmer@jelmer.uk>
0.262.1 by Jelmer Vernooij
Fix WorkingTree.conflicts().
2
# Copyright (C) 2011 Canonical Ltd.
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
0.358.1 by Jelmer Vernooij
Fix FSF address.
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
0.262.1 by Jelmer Vernooij
Fix WorkingTree.conflicts().
17
18
"""Tests for Git working trees."""
19
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
20
import os
21
import stat
22
7467.4.2 by Jelmer Vernooij
Add some tests.
23
from dulwich import __version__ as dulwich_version
24
from dulwich.diff_tree import RenameDetector
7131.13.1 by Jelmer Vernooij
Don't show a delta for unchanged submodules.
25
from dulwich.index import IndexEntry
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
26
from dulwich.objects import (
7131.13.1 by Jelmer Vernooij
Don't show a delta for unchanged submodules.
27
    S_IFGITLINK,
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
28
    Blob,
29
    Tree,
30
    ZERO_SHA,
31
    )
32
6986.2.1 by Jelmer Vernooij
Move breezy.plugins.git to breezy.git.
33
from ... import (
6977.1.2 by Jelmer Vernooij
Deal with missing files properly in 'bzr st'.
34
    conflicts as _mod_conflicts,
7131.3.1 by Jelmer Vernooij
When opening working trees with .git files, open the right control transport.
35
    workingtree as _mod_workingtree,
6977.1.2 by Jelmer Vernooij
Deal with missing files properly in 'bzr st'.
36
    )
6986.2.1 by Jelmer Vernooij
Move breezy.plugins.git to breezy.git.
37
from ...delta import TreeDelta
7358.11.3 by Jelmer Vernooij
TreeDelta holds TreeChange objects rather than tuples of various sizes.
38
from ...tree import TreeChange
6977.1.2 by Jelmer Vernooij
Deal with missing files properly in 'bzr st'.
39
from ..mapping import (
40
    default_mapping,
41
    )
6973.1.1 by Jelmer Vernooij
Make InterIndexGitTree suitable for use with MemoryGitTree.
42
from ..tree import (
43
    changes_between_git_tree_and_working_copy,
6977.1.2 by Jelmer Vernooij
Deal with missing files properly in 'bzr st'.
44
    tree_delta_from_git_changes,
6973.1.1 by Jelmer Vernooij
Make InterIndexGitTree suitable for use with MemoryGitTree.
45
    )
0.369.1 by Jelmer Vernooij
Implement conflict handling.
46
from ..workingtree import (
47
    FLAG_STAGEMASK,
0.262.1 by Jelmer Vernooij
Fix WorkingTree.conflicts().
48
    )
6986.2.1 by Jelmer Vernooij
Move breezy.plugins.git to breezy.git.
49
from ...tests import (
6977.1.2 by Jelmer Vernooij
Deal with missing files properly in 'bzr st'.
50
    TestCase,
51
    TestCaseWithTransport,
52
    )
0.262.1 by Jelmer Vernooij
Fix WorkingTree.conflicts().
53
54
55
class GitWorkingTreeTests(TestCaseWithTransport):
56
57
    def setUp(self):
58
        super(GitWorkingTreeTests, self).setUp()
59
        self.tree = self.make_branch_and_tree('.', format="git")
60
0.369.1 by Jelmer Vernooij
Implement conflict handling.
61
    def test_conflict_list(self):
0.369.2 by Jelmer Vernooij
Fix tests.
62
        self.assertIsInstance(
7143.15.2 by Jelmer Vernooij
Run autopep8.
63
            self.tree.conflicts(),
64
            _mod_conflicts.ConflictList)
0.369.1 by Jelmer Vernooij
Implement conflict handling.
65
66
    def test_add_conflict(self):
67
        self.build_tree(['conflicted'])
68
        self.tree.add(['conflicted'])
69
        with self.tree.lock_tree_write():
7143.15.2 by Jelmer Vernooij
Run autopep8.
70
            self.tree.index[b'conflicted'] = self.tree.index[b'conflicted'][:9] + \
71
                (FLAG_STAGEMASK, )
0.415.3 by Jelmer Vernooij
Open index on demand.
72
            self.tree._index_dirty = True
0.369.1 by Jelmer Vernooij
Implement conflict handling.
73
        conflicts = self.tree.conflicts()
74
        self.assertEqual(1, len(conflicts))
0.385.1 by Jelmer Vernooij
Use specific_files argument to Tree.iter_entries_by_dir.
75
76
    def test_revert_empty(self):
77
        self.build_tree(['a'])
78
        self.tree.add(['a'])
79
        self.assertTrue(self.tree.is_versioned('a'))
80
        self.tree.revert(['a'])
81
        self.assertFalse(self.tree.is_versioned('a'))
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
82
7065.1.1 by Jelmer Vernooij
Properly handle ignored directories in Git.
83
    def test_is_ignored_directory(self):
84
        self.assertFalse(self.tree.is_ignored('a'))
85
        self.build_tree(['a/'])
86
        self.assertFalse(self.tree.is_ignored('a'))
87
        self.build_tree_contents([('.gitignore', 'a\n')])
88
        self.tree._ignoremanager = None
89
        self.assertTrue(self.tree.is_ignored('a'))
90
        self.build_tree_contents([('.gitignore', 'a/\n')])
91
        self.tree._ignoremanager = None
92
        self.assertTrue(self.tree.is_ignored('a'))
93
7265.3.1 by Jelmer Vernooij
Properly ignore .git files.
94
    def test_add_submodule_dir(self):
95
        subtree = self.make_branch_and_tree('asub', format='git')
96
        subtree.commit('Empty commit')
97
        self.tree.add(['asub'])
98
        with self.tree.lock_read():
99
            entry = self.tree.index[b'asub']
100
            self.assertEqual(entry.mode, S_IFGITLINK)
101
        self.assertEqual([], list(subtree.unknowns()))
102
103
    def test_add_submodule_file(self):
104
        os.mkdir('.git/modules')
105
        subbranch = self.make_branch('.git/modules/asub', format='git-bare')
106
        os.mkdir('asub')
107
        with open('asub/.git', 'w') as f:
108
            f.write('gitdir: ../.git/modules/asub\n')
109
        subtree = _mod_workingtree.WorkingTree.open('asub')
110
        subtree.commit('Empty commit')
111
        self.tree.add(['asub'])
112
        with self.tree.lock_read():
113
            entry = self.tree.index[b'asub']
114
            self.assertEqual(entry.mode, S_IFGITLINK)
115
        self.assertEqual([], list(subtree.unknowns()))
116
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
117
7131.3.1 by Jelmer Vernooij
When opening working trees with .git files, open the right control transport.
118
class GitWorkingTreeFileTests(TestCaseWithTransport):
119
120
    def setUp(self):
121
        super(GitWorkingTreeFileTests, self).setUp()
122
        self.tree = self.make_branch_and_tree('actual', format="git")
7143.15.2 by Jelmer Vernooij
Run autopep8.
123
        self.build_tree_contents(
124
            [('linked/',), ('linked/.git', 'gitdir: ../actual/.git')])
7131.3.1 by Jelmer Vernooij
When opening working trees with .git files, open the right control transport.
125
        self.wt = _mod_workingtree.WorkingTree.open('linked')
126
127
    def test_add(self):
128
        self.build_tree(['linked/somefile'])
129
        self.wt.add(["somefile"])
130
        self.wt.commit("Add somefile")
131
132
6977.1.2 by Jelmer Vernooij
Deal with missing files properly in 'bzr st'.
133
class TreeDeltaFromGitChangesTests(TestCase):
134
135
    def test_empty(self):
136
        delta = TreeDelta()
137
        changes = []
138
        self.assertEqual(
139
            delta,
7358.13.1 by Jelmer Vernooij
Drop file id roundtripping support in Git.
140
            tree_delta_from_git_changes(changes, (default_mapping, default_mapping)))
6977.1.2 by Jelmer Vernooij
Deal with missing files properly in 'bzr st'.
141
142
    def test_missing(self):
143
        delta = TreeDelta()
7467.4.2 by Jelmer Vernooij
Add some tests.
144
        delta.removed.append(
145
            TreeChange(
146
                b'git:a', ('a', 'a'), False, (True, True),
147
                (b'TREE_ROOT', b'TREE_ROOT'), ('a', 'a'), ('file', None),
148
                (True, False)))
149
        changes = [
150
            ('remove',
151
                (b'a', stat.S_IFREG | 0o755, b'a' * 40),
152
                (b'a', 0, b'a' * 40))]
6977.1.2 by Jelmer Vernooij
Deal with missing files properly in 'bzr st'.
153
        self.assertEqual(
154
            delta,
7358.13.1 by Jelmer Vernooij
Drop file id roundtripping support in Git.
155
            tree_delta_from_git_changes(changes, (default_mapping, default_mapping)))
6977.1.2 by Jelmer Vernooij
Deal with missing files properly in 'bzr st'.
156
157
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
158
class ChangesBetweenGitTreeAndWorkingCopyTests(TestCaseWithTransport):
159
160
    def setUp(self):
161
        super(ChangesBetweenGitTreeAndWorkingCopyTests, self).setUp()
162
        self.wt = self.make_branch_and_tree('.', format='git')
7131.13.1 by Jelmer Vernooij
Don't show a delta for unchanged submodules.
163
        self.store = self.wt.branch.repository._git.object_store
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
164
165
    def expectDelta(self, expected_changes,
7131.13.1 by Jelmer Vernooij
Don't show a delta for unchanged submodules.
166
                    expected_extras=None, want_unversioned=False,
7467.4.2 by Jelmer Vernooij
Add some tests.
167
                    tree_id=None, rename_detector=None):
7131.13.1 by Jelmer Vernooij
Don't show a delta for unchanged submodules.
168
        if tree_id is None:
169
            try:
170
                tree_id = self.store[self.wt.branch.repository._git.head()].tree
171
            except KeyError:
172
                tree_id = None
0.415.3 by Jelmer Vernooij
Open index on demand.
173
        with self.wt.lock_read():
174
            changes, extras = changes_between_git_tree_and_working_copy(
7467.4.2 by Jelmer Vernooij
Add some tests.
175
                self.store, tree_id, self.wt, want_unversioned=want_unversioned,
176
                rename_detector=rename_detector)
0.415.3 by Jelmer Vernooij
Open index on demand.
177
            self.assertEqual(expected_changes, list(changes))
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
178
        if expected_extras is None:
179
            expected_extras = set()
180
        self.assertEqual(set(expected_extras), set(extras))
181
182
    def test_empty(self):
183
        self.expectDelta(
7467.4.2 by Jelmer Vernooij
Add some tests.
184
            [('add', (None, None, None), (b'', stat.S_IFDIR, Tree().id))])
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
185
186
    def test_added_file(self):
187
        self.build_tree(['a'])
188
        self.wt.add(['a'])
6973.13.2 by Jelmer Vernooij
Fix some more tests.
189
        a = Blob.from_string(b'contents of a\n')
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
190
        t = Tree()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
191
        t.add(b"a", stat.S_IFREG | 0o644, a.id)
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
192
        self.expectDelta(
7467.4.2 by Jelmer Vernooij
Add some tests.
193
            [('add', (None, None, None), (b'', stat.S_IFDIR, t.id)),
194
             ('add', (None, None, None), (b'a', stat.S_IFREG | 0o644, a.id))])
195
196
    def test_renamed_file(self):
197
        self.build_tree(['a'])
198
        self.wt.add(['a'])
199
        self.wt.rename_one('a', 'b')
200
        a = Blob.from_string(b'contents of a\n')
201
        self.store.add_object(a)
202
        oldt = Tree()
203
        oldt.add(b"a", stat.S_IFREG | 0o644, a.id)
204
        self.store.add_object(oldt)
205
        newt = Tree()
206
        newt.add(b"b", stat.S_IFREG | 0o644, a.id)
207
        self.store.add_object(newt)
208
        self.expectDelta(
209
            [('modify', (b'', stat.S_IFDIR, oldt.id), (b'', stat.S_IFDIR, newt.id)),
210
             ('delete', (b'a', stat.S_IFREG | 0o644, a.id), (None, None, None)),
211
             ('add', (None, None, None), (b'b', stat.S_IFREG | 0o644, a.id)),
212
             ],
213
            tree_id=oldt.id)
214
        if dulwich_version >= (0, 19, 15):
215
            self.expectDelta(
216
                [('modify', (b'', stat.S_IFDIR, oldt.id), (b'', stat.S_IFDIR, newt.id)),
217
                 ('rename', (b'a', stat.S_IFREG | 0o644, a.id), (b'b', stat.S_IFREG | 0o644, a.id))],
218
                tree_id=oldt.id, rename_detector=RenameDetector(self.store))
219
220
    def test_copied_file(self):
221
        self.build_tree(['a'])
222
        self.wt.add(['a'])
223
        self.wt.copy_one('a', 'b')
224
        a = Blob.from_string(b'contents of a\n')
225
        self.store.add_object(a)
226
        oldt = Tree()
227
        oldt.add(b"a", stat.S_IFREG | 0o644, a.id)
228
        self.store.add_object(oldt)
229
        newt = Tree()
230
        newt.add(b"a", stat.S_IFREG | 0o644, a.id)
231
        newt.add(b"b", stat.S_IFREG | 0o644, a.id)
232
        self.store.add_object(newt)
233
        self.expectDelta(
234
            [('modify', (b'', stat.S_IFDIR, oldt.id), (b'', stat.S_IFDIR, newt.id)),
235
             ('add', (None, None, None), (b'b', stat.S_IFREG | 0o644, a.id)),
236
             ],
237
            tree_id=oldt.id)
238
239
        if dulwich_version >= (0, 19, 15):
240
            self.expectDelta(
241
                [('modify', (b'', stat.S_IFDIR, oldt.id), (b'', stat.S_IFDIR, newt.id)),
242
                 ('copy', (b'a', stat.S_IFREG | 0o644, a.id), (b'b', stat.S_IFREG | 0o644, a.id))],
243
                tree_id=oldt.id, rename_detector=RenameDetector(self.store, find_copies_harder=True))
244
            self.expectDelta(
245
                [('modify', (b'', stat.S_IFDIR, oldt.id), (b'', stat.S_IFDIR, newt.id)),
246
                 ('add', (None, None, None), (b'b', stat.S_IFREG | 0o644, a.id)),
247
                 ],
248
                tree_id=oldt.id, rename_detector=RenameDetector(self.store, find_copies_harder=False))
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
249
250
    def test_added_unknown_file(self):
251
        self.build_tree(['a'])
252
        t = Tree()
253
        self.expectDelta(
7467.4.2 by Jelmer Vernooij
Add some tests.
254
            [('add', (None, None, None), (b'', stat.S_IFDIR, t.id))])
6973.13.2 by Jelmer Vernooij
Fix some more tests.
255
        a = Blob.from_string(b'contents of a\n')
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
256
        t = Tree()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
257
        t.add(b"a", stat.S_IFREG | 0o644, a.id)
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
258
        self.expectDelta(
7467.4.2 by Jelmer Vernooij
Add some tests.
259
            [('add', (None, None, None), (b'', stat.S_IFDIR, t.id)),
260
             ('add', (None, None, None), (b'a', stat.S_IFREG | 0o644, a.id))],
6973.13.2 by Jelmer Vernooij
Fix some more tests.
261
            [b'a'],
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
262
            want_unversioned=True)
263
264
    def test_missing_added_file(self):
265
        self.build_tree(['a'])
266
        self.wt.add(['a'])
267
        os.unlink('a')
6973.13.2 by Jelmer Vernooij
Fix some more tests.
268
        a = Blob.from_string(b'contents of a\n')
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
269
        t = Tree()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
270
        t.add(b"a", 0, ZERO_SHA)
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
271
        self.expectDelta(
7467.4.2 by Jelmer Vernooij
Add some tests.
272
            [('add', (None, None, None), (b'', stat.S_IFDIR, t.id)),
273
             ('add', (None, None, None), (b'a', 0, ZERO_SHA))],
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
274
            [])
275
276
    def test_missing_versioned_file(self):
277
        self.build_tree(['a'])
278
        self.wt.add(['a'])
279
        self.wt.commit('')
280
        os.unlink('a')
6973.13.2 by Jelmer Vernooij
Fix some more tests.
281
        a = Blob.from_string(b'contents of a\n')
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
282
        oldt = Tree()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
283
        oldt.add(b"a", stat.S_IFREG | 0o644, a.id)
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
284
        newt = Tree()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
285
        newt.add(b"a", 0, ZERO_SHA)
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
286
        self.expectDelta(
7467.4.2 by Jelmer Vernooij
Add some tests.
287
            [('modify',
288
                (b'', stat.S_IFDIR, oldt.id),
289
                (b'', stat.S_IFDIR, newt.id)),
290
             ('modify',
291
                 (b'a', stat.S_IFREG | 0o644, a.id),
292
                 (b'a', 0, ZERO_SHA))])
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
293
294
    def test_versioned_replace_by_dir(self):
295
        self.build_tree(['a'])
296
        self.wt.add(['a'])
297
        self.wt.commit('')
298
        os.unlink('a')
299
        os.mkdir('a')
6973.13.2 by Jelmer Vernooij
Fix some more tests.
300
        olda = Blob.from_string(b'contents of a\n')
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
301
        oldt = Tree()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
302
        oldt.add(b"a", stat.S_IFREG | 0o644, olda.id)
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
303
        newt = Tree()
304
        newa = Tree()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
305
        newt.add(b"a", stat.S_IFDIR, newa.id)
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
306
        self.expectDelta([
7467.4.2 by Jelmer Vernooij
Add some tests.
307
            ('modify',
308
                (b'', stat.S_IFDIR, oldt.id),
309
                (b'', stat.S_IFDIR, newt.id)),
310
            ('modify',
311
                (b'a', stat.S_IFREG | 0o644, olda.id),
312
                (b'a', stat.S_IFDIR, newa.id))
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
313
            ], want_unversioned=False)
314
        self.expectDelta([
7467.4.2 by Jelmer Vernooij
Add some tests.
315
            ('modify',
316
                (b'', stat.S_IFDIR, oldt.id),
317
                (b'', stat.S_IFDIR, newt.id)),
318
            ('modify',
319
                (b'a', stat.S_IFREG | 0o644, olda.id),
320
                (b'a', stat.S_IFDIR, newa.id)),
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
321
            ], want_unversioned=True)
322
323
    def test_extra(self):
324
        self.build_tree(['a'])
6964.2.1 by Jelmer Vernooij
Initial work to support brz-git on python3.
325
        newa = Blob.from_string(b'contents of a\n')
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
326
        newt = Tree()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
327
        newt.add(b"a", stat.S_IFREG | 0o644, newa.id)
0.391.7 by Jelmer Vernooij
Fix reporting of missing files in .iter_changes.
328
        self.expectDelta([
7467.4.2 by Jelmer Vernooij
Add some tests.
329
            ('add',
330
                (None, None, None),
331
                (b'', stat.S_IFDIR, newt.id)),
332
            ('add',
333
                (None, None, None),
334
                (b'a', stat.S_IFREG | 0o644, newa.id)),
6973.13.2 by Jelmer Vernooij
Fix some more tests.
335
            ], [b'a'], want_unversioned=True)
7131.13.1 by Jelmer Vernooij
Don't show a delta for unchanged submodules.
336
337
    def test_submodule(self):
7296.1.3 by Jelmer Vernooij
Fix submodule test.
338
        self.subtree = self.make_branch_and_tree('a', format="git")
7131.13.1 by Jelmer Vernooij
Don't show a delta for unchanged submodules.
339
        a = Blob.from_string(b'irrelevant\n')
7296.1.3 by Jelmer Vernooij
Fix submodule test.
340
        self.build_tree_contents([('a/.git/HEAD', a.id)])
7131.13.1 by Jelmer Vernooij
Don't show a delta for unchanged submodules.
341
        with self.wt.lock_tree_write():
7131.13.3 by Jelmer Vernooij
Fix python3 compatibility.
342
            (index, index_path) = self.wt._lookup_index(b'a')
7183.2.1 by Martin
Fix E999 lint error for Python 2 flake8
343
            index[b'a'] = IndexEntry(0, 0, 0, 0, S_IFGITLINK, 0, 0, 0, a.id, 0)
7131.13.1 by Jelmer Vernooij
Don't show a delta for unchanged submodules.
344
            self.wt._index_dirty = True
345
        t = Tree()
7183.2.1 by Martin
Fix E999 lint error for Python 2 flake8
346
        t.add(b"a", S_IFGITLINK, a.id)
7131.13.1 by Jelmer Vernooij
Don't show a delta for unchanged submodules.
347
        self.store.add_object(t)
348
        self.expectDelta([], tree_id=t.id)
7452.1.1 by Jelmer Vernooij
Don't show submodules that are not checked out as deltas.
349
350
    def test_submodule_not_checked_out(self):
351
        a = Blob.from_string(b'irrelevant\n')
352
        with self.wt.lock_tree_write():
353
            (index, index_path) = self.wt._lookup_index(b'a')
354
            index[b'a'] = IndexEntry(0, 0, 0, 0, S_IFGITLINK, 0, 0, 0, a.id, 0)
355
            self.wt._index_dirty = True
356
        os.mkdir(self.wt.abspath('a'))
357
        t = Tree()
358
        t.add(b"a", S_IFGITLINK, a.id)
359
        self.store.add_object(t)
360
        self.expectDelta([], tree_id=t.id)