/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.264.10 by Jelmer Vernooij
Yield inventory entries.
1
# Copyright (C) 2008-2011 Jelmer Vernooij <jelmer@samba.org>
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
17
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
18
"""An adapter between a Git index and a Bazaar Working Tree"""
19
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
20
0.200.385 by Jelmer Vernooij
Cope with removed files.
21
from cStringIO import (
22
    StringIO,
23
    )
0.200.1210 by Jelmer Vernooij
Implement GitWorkingTree._walkdirs.
24
from collections import defaultdict
0.239.4 by Jelmer Vernooij
Cope with nonexistent files and directories in get_file_sha1.
25
import errno
0.200.1096 by Jelmer Vernooij
Implement GitWorkingTreeFormat.initialize.
26
from dulwich.index import (
27
    Index,
28
    )
0.200.1202 by Jelmer Vernooij
Implement has_or_had_id.
29
from dulwich.object_store import (
30
    tree_lookup_path,
31
    )
0.200.383 by Jelmer Vernooij
Simplify, support rewriting index based on inventory.
32
from dulwich.objects import (
33
    Blob,
0.200.948 by Jelmer Vernooij
Cope with empty inventories.
34
    ZERO_SHA,
35
    )
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
36
import os
0.200.1349 by Jelmer Vernooij
Avoid inline imports.
37
from posix import stat_result
0.264.10 by Jelmer Vernooij
Yield inventory entries.
38
import posixpath
0.200.384 by Jelmer Vernooij
Fix reading of inventory from index.
39
import stat
0.200.1215 by Jelmer Vernooij
Implement GitWorkingTree.remove.
40
import sys
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
41
42
from bzrlib import (
0.200.382 by Jelmer Vernooij
Support flushing index.
43
    errors,
0.262.1 by Jelmer Vernooij
Fix WorkingTree.conflicts().
44
    conflicts as _mod_conflicts,
0.200.409 by Jelmer Vernooij
Support parsing .gitignore.
45
    ignores,
0.264.10 by Jelmer Vernooij
Yield inventory entries.
46
    inventory,
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
47
    lockable_files,
48
    lockdir,
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
49
    osutils,
0.200.1215 by Jelmer Vernooij
Implement GitWorkingTree.remove.
50
    trace,
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
51
    transport,
0.200.519 by Jelmer Vernooij
Move imports down, might not be available in older bzr-git versions.
52
    tree,
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
53
    workingtree,
54
    )
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
55
from bzrlib.decorators import (
56
    needs_read_lock,
57
    )
0.200.1308 by Jelmer Vernooij
Write index to disk after adding files.
58
from bzrlib.mutabletree import needs_tree_write_lock
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
59
60
0.200.1096 by Jelmer Vernooij
Implement GitWorkingTreeFormat.initialize.
61
from bzrlib.plugins.git.dir import (
62
    LocalGitDir,
63
    )
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
64
from bzrlib.plugins.git.tree import (
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
65
    changes_from_git_changes,
0.200.617 by Jelmer Vernooij
Add custom InterTree for use between git revision trees.
66
    tree_delta_from_git_changes,
67
    )
0.200.971 by Chadrik
Fix 'bzr status' after 'bzr add' in native git working trees.
68
from bzrlib.plugins.git.mapping import (
69
    GitFileIdMap,
0.264.10 by Jelmer Vernooij
Yield inventory entries.
70
    mode_kind,
0.200.971 by Chadrik
Fix 'bzr status' after 'bzr add' in native git working trees.
71
    )
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
72
0.200.409 by Jelmer Vernooij
Support parsing .gitignore.
73
IGNORE_FILENAME = ".gitignore"
74
75
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
76
class GitWorkingTree(workingtree.WorkingTree):
77
    """A Git working tree."""
78
0.200.803 by Jelmer Vernooij
Default to non-bare repositories when initializing a control directory.
79
    def __init__(self, bzrdir, repo, branch, index):
0.200.379 by Jelmer Vernooij
Re-enable working tree support.
80
        self.basedir = bzrdir.root_transport.local_abspath('.')
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
81
        self.bzrdir = bzrdir
82
        self.repository = repo
0.200.1205 by Jelmer Vernooij
Implement GitWorkingTree.stored_kind.
83
        self.store = self.repository._git.object_store
0.200.384 by Jelmer Vernooij
Fix reading of inventory from index.
84
        self.mapping = self.repository.get_mapping()
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
85
        self._branch = branch
86
        self._transport = bzrdir.transport
87
0.246.3 by Jelmer Vernooij
Simplify call to abspath, without involving private variables.
88
        self.controldir = self.bzrdir.transport.local_abspath('bzr')
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
89
90
        try:
91
            os.makedirs(self.controldir)
92
            os.makedirs(os.path.join(self.controldir, 'lock'))
93
        except OSError:
94
            pass
95
96
        self._control_files = lockable_files.LockableFiles(
97
            transport.get_transport(self.controldir), 'lock', lockdir.LockDir)
98
        self._format = GitWorkingTreeFormat()
0.200.803 by Jelmer Vernooij
Default to non-bare repositories when initializing a control directory.
99
        self.index = index
0.200.1242 by Jelmer Vernooij
Support directories better.
100
        self._versioned_dirs = None
0.200.239 by Jelmer Vernooij
Provide views.
101
        self.views = self._make_views()
0.200.1173 by Jelmer Vernooij
Provide GitWorkingTree._rules_searcher.
102
        self._rules_searcher = None
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
103
        self._detect_case_handling()
0.200.1202 by Jelmer Vernooij
Implement has_or_had_id.
104
        self._reset_data()
105
        self._fileid_map = self._basis_fileid_map.copy()
0.200.173 by Jelmer Vernooij
Merge changes, open index.
106
0.200.1322 by Jelmer Vernooij
Add case detection.
107
    def _detect_case_handling(self):
108
        try:
109
            self._transport.stat(".git/cOnFiG")
110
        except errors.NoSuchFile:
111
            self.case_sensitive = True
112
        else:
113
            self.case_sensitive = False
114
0.200.1315 by Jelmer Vernooij
Implement WorkingTree.merge_modified.
115
    def merge_modified(self):
116
        return {}
117
0.200.1220 by Jelmer Vernooij
Support set_parent_trees.
118
    def set_parent_trees(self, parents_list, allow_leftmost_as_ghost=False):
119
        self.set_parent_ids([p for p, t in parents_list])
120
0.264.2 by Jelmer Vernooij
Implement GitWorkingTree.{_add,__iter__,id2path}.
121
    def _index_add_entry(self, path, file_id, kind):
0.200.1206 by Jelmer Vernooij
Implement GitWorkingTree.all_file_ids.
122
        assert isinstance(path, basestring)
0.200.1308 by Jelmer Vernooij
Write index to disk after adding files.
123
        assert type(file_id) == str or file_id is None
0.264.2 by Jelmer Vernooij
Implement GitWorkingTree.{_add,__iter__,id2path}.
124
        if kind == "directory":
125
            # Git indexes don't contain directories
126
            return
127
        if kind == "file":
128
            blob = Blob()
129
            try:
130
                file, stat_val = self.get_file_with_stat(file_id, path)
131
            except (errors.NoSuchFile, IOError):
132
                # TODO: Rather than come up with something here, use the old index
133
                file = StringIO()
134
                stat_val = stat_result((stat.S_IFREG | 0644, 0, 0, 0, 0, 0, 0, 0, 0, 0))
135
            blob.set_raw_string(file.read())
136
        elif kind == "symlink":
137
            blob = Blob()
138
            try:
139
                stat_val = os.lstat(self.abspath(path))
140
            except (errors.NoSuchFile, OSError):
141
                # TODO: Rather than come up with something here, use the 
142
                # old index
143
                stat_val = stat_result((stat.S_IFLNK, 0, 0, 0, 0, 0, 0, 0, 0, 0))
0.200.1321 by Jelmer Vernooij
More fixes for compatibility with bzr.dev testsuite.
144
            blob.set_raw_string(
145
                self.get_symlink_target(file_id, path).encode("utf-8"))
0.264.2 by Jelmer Vernooij
Implement GitWorkingTree.{_add,__iter__,id2path}.
146
        else:
147
            raise AssertionError("unknown kind '%s'" % kind)
148
        # Add object to the repository if it didn't exist yet
0.200.1205 by Jelmer Vernooij
Implement GitWorkingTree.stored_kind.
149
        if not blob.id in self.store:
150
            self.store.add_object(blob)
0.264.2 by Jelmer Vernooij
Implement GitWorkingTree.{_add,__iter__,id2path}.
151
        # Add an entry to the index or update the existing entry
152
        flags = 0 # FIXME
0.200.1242 by Jelmer Vernooij
Support directories better.
153
        encoded_path = path.encode("utf-8")
154
        self.index[encoded_path] = (stat_val.st_ctime,
0.264.2 by Jelmer Vernooij
Implement GitWorkingTree.{_add,__iter__,id2path}.
155
                stat_val.st_mtime, stat_val.st_dev, stat_val.st_ino,
156
                stat_val.st_mode, stat_val.st_uid, stat_val.st_gid,
157
                stat_val.st_size, blob.id, flags)
0.200.1242 by Jelmer Vernooij
Support directories better.
158
        if self._versioned_dirs is not None:
159
            self._ensure_versioned_dir(encoded_path)
160
161
    def _ensure_versioned_dir(self, dirname):
0.200.1249 by Jelmer Vernooij
Fix file id for tree root
162
        if dirname in self._versioned_dirs:
0.200.1242 by Jelmer Vernooij
Support directories better.
163
            return
0.200.1249 by Jelmer Vernooij
Fix file id for tree root
164
        if dirname != "":
165
            self._ensure_versioned_dir(posixpath.dirname(dirname))
0.200.1242 by Jelmer Vernooij
Support directories better.
166
        self._versioned_dirs.add(dirname)
167
168
    def _load_dirs(self):
169
        self._versioned_dirs = set()
170
        for p in self.index:
171
            self._ensure_versioned_dir(posixpath.dirname(p))
0.264.2 by Jelmer Vernooij
Implement GitWorkingTree.{_add,__iter__,id2path}.
172
0.200.1215 by Jelmer Vernooij
Implement GitWorkingTree.remove.
173
    def _unversion_path(self, path):
174
        encoded_path = path.encode("utf-8")
175
        try:
176
            del self.index[encoded_path]
177
        except KeyError:
178
            # A directory, perhaps?
179
            for p in list(self.index):
180
                if p.startswith(encoded_path+"/"):
181
                    del self.index[p]
0.200.1242 by Jelmer Vernooij
Support directories better.
182
        # FIXME: remove empty directories
0.200.1215 by Jelmer Vernooij
Implement GitWorkingTree.remove.
183
0.200.1328 by Jelmer Vernooij
More test fixes.
184
    @needs_tree_write_lock
0.200.1192 by Jelmer Vernooij
Implement path2id.
185
    def unversion(self, file_ids):
186
        for file_id in file_ids:
187
            path = self.id2path(file_id)
0.200.1215 by Jelmer Vernooij
Implement GitWorkingTree.remove.
188
            self._unversion_path(path)
0.200.1328 by Jelmer Vernooij
More test fixes.
189
        self.flush()
0.200.1215 by Jelmer Vernooij
Implement GitWorkingTree.remove.
190
0.200.1243 by Jelmer Vernooij
Implement WorkingTree.check_state.
191
    def check_state(self):
192
        """Check that the working state is/isn't valid."""
193
        pass
194
0.200.1328 by Jelmer Vernooij
More test fixes.
195
    @needs_tree_write_lock
0.200.1215 by Jelmer Vernooij
Implement GitWorkingTree.remove.
196
    def remove(self, files, verbose=False, to_file=None, keep_files=True,
197
        force=False):
198
        """Remove nominated files from the working tree metadata.
199
200
        :param files: File paths relative to the basedir.
201
        :param keep_files: If true, the files will also be kept.
202
        :param force: Delete files and directories, even if they are changed
203
            and even if the directories are not empty.
204
        """
205
        all_files = set() # specified and nested files 
206
207
        if isinstance(files, basestring):
208
            files = [files]
209
210
        if to_file is None:
211
            to_file = sys.stdout
212
213
        files = list(all_files)
214
215
        if len(files) == 0:
216
            return # nothing to do
217
218
        # Sort needed to first handle directory content before the directory
219
        files.sort(reverse=True)
220
221
        def backup(file_to_backup):
222
            abs_path = self.abspath(file_to_backup)
223
            backup_name = self.bzrdir._available_backup_name(file_to_backup)
224
            osutils.rename(abs_path, self.abspath(backup_name))
225
            return "removed %s (but kept a copy: %s)" % (
226
                file_to_backup, backup_name)
227
228
        for f in files:
229
            fid = self.path2id(f)
230
            if not fid:
231
                message = "%s is not versioned." % (f,)
232
            else:
233
                abs_path = self.abspath(f)
234
                if verbose:
235
                    # having removed it, it must be either ignored or unknown
236
                    if self.is_ignored(f):
237
                        new_status = 'I'
238
                    else:
239
                        new_status = '?'
240
                    # XXX: Really should be a more abstract reporter interface
241
                    kind_ch = osutils.kind_marker(self.kind(fid))
242
                    to_file.write(new_status + '       ' + f + kind_ch + '\n')
243
                # Unversion file
244
                # FIXME: _unversion_path() is O(size-of-index) for directories
245
                self._unversion_path(f)
246
                message = "removed %s" % (f,)
247
                if osutils.lexists(abs_path):
248
                    if (osutils.isdir(abs_path) and
249
                        len(os.listdir(abs_path)) > 0):
250
                        if force:
251
                            osutils.rmtree(abs_path)
252
                            message = "deleted %s" % (f,)
253
                        else:
254
                            message = backup(f)
255
                    else:
256
                        if not keep_files:
257
                            osutils.delete_any(abs_path)
258
                            message = "deleted %s" % (f,)
259
260
            # print only one message (if any) per file.
261
            if message is not None:
262
                trace.note(message)
0.200.1328 by Jelmer Vernooij
More test fixes.
263
        self.flush()
0.200.1192 by Jelmer Vernooij
Implement path2id.
264
0.264.2 by Jelmer Vernooij
Implement GitWorkingTree.{_add,__iter__,id2path}.
265
    def _add(self, files, ids, kinds):
266
        for (path, file_id, kind) in zip(files, ids, kinds):
0.200.1201 by Jelmer Vernooij
Implement _set_root_id.
267
            if file_id is not None:
0.200.1210 by Jelmer Vernooij
Implement GitWorkingTree._walkdirs.
268
                self._fileid_map.set_file_id(path.encode("utf-8"), file_id)
0.200.1206 by Jelmer Vernooij
Implement GitWorkingTree.all_file_ids.
269
            else:
0.200.1210 by Jelmer Vernooij
Implement GitWorkingTree._walkdirs.
270
                file_id = self._fileid_map.lookup_file_id(path.encode("utf-8"))
0.200.1206 by Jelmer Vernooij
Implement GitWorkingTree.all_file_ids.
271
            self._index_add_entry(path, file_id, kind)
0.200.1201 by Jelmer Vernooij
Implement _set_root_id.
272
0.200.1308 by Jelmer Vernooij
Write index to disk after adding files.
273
    @needs_tree_write_lock
0.200.1240 by Jelmer Vernooij
Implement GitWorkingTree.smart_add.
274
    def smart_add(self, file_list, recurse=True, action=None, save=True):
275
        added = []
276
        ignored = {}
277
        user_dirs = []
278
        for filepath in osutils.canonical_relpaths(self.basedir, file_list):
0.200.1308 by Jelmer Vernooij
Write index to disk after adding files.
279
            abspath = self.abspath(filepath)
280
            kind = osutils.file_kind(abspath)
0.200.1240 by Jelmer Vernooij
Implement GitWorkingTree.smart_add.
281
            if action is not None:
0.200.1308 by Jelmer Vernooij
Write index to disk after adding files.
282
                file_id = action(self, None, filepath, kind)
0.200.1240 by Jelmer Vernooij
Implement GitWorkingTree.smart_add.
283
            else:
284
                file_id = None
285
            if kind in ("file", "symlink"):
0.200.1308 by Jelmer Vernooij
Write index to disk after adding files.
286
                if save:
0.200.1240 by Jelmer Vernooij
Implement GitWorkingTree.smart_add.
287
                    self._index_add_entry(filepath, file_id, kind)
288
                added.append(filepath)
289
            elif kind == "directory":
290
                if recurse:
291
                    user_dirs.append(filepath)
292
            else:
293
                raise errors.BadFileKindError(filename=abspath, kind=kind)
294
        for user_dir in user_dirs:
295
            abs_user_dir = self.abspath(user_dir)
296
            for name in os.listdir(abs_user_dir):
297
                subp = os.path.join(user_dir, name)
0.200.1328 by Jelmer Vernooij
More test fixes.
298
                if self.is_control_filename(subp) or self.mapping.is_special_file(subp):
0.200.1257 by Jelmer Vernooij
Don't be verbose on control filenames.
299
                    continue
0.200.1240 by Jelmer Vernooij
Implement GitWorkingTree.smart_add.
300
                ignore_glob = self.is_ignored(subp)
301
                if ignore_glob is not None:
302
                    ignored.setdefault(ignore_glob, []).append(subp)
303
                    continue
304
                abspath = self.abspath(subp)
305
                kind = osutils.file_kind(abspath)
306
                if kind == "directory":
307
                    user_dirs.append(subp)
308
                else:
309
                    if action is not None:
310
                        file_id = action()
311
                    else:
312
                        file_id = None
0.200.1308 by Jelmer Vernooij
Write index to disk after adding files.
313
                    if save:
0.200.1240 by Jelmer Vernooij
Implement GitWorkingTree.smart_add.
314
                        self._index_add_entry(subp, file_id, kind)
0.200.1308 by Jelmer Vernooij
Write index to disk after adding files.
315
        if added and save:
316
            self.flush()
0.200.1240 by Jelmer Vernooij
Implement GitWorkingTree.smart_add.
317
        return added, ignored
318
0.200.1201 by Jelmer Vernooij
Implement _set_root_id.
319
    def _set_root_id(self, file_id):
320
        self._fileid_map.set_file_id("", file_id)
0.264.2 by Jelmer Vernooij
Implement GitWorkingTree.{_add,__iter__,id2path}.
321
0.200.1308 by Jelmer Vernooij
Write index to disk after adding files.
322
    @needs_tree_write_lock
0.200.1193 by Jelmer Vernooij
Implement GitWorkingTree.{move,rename_one}.
323
    def move(self, from_paths, to_dir=None, after=False):
324
        rename_tuples = []
325
        to_abs = self.abspath(to_dir)
326
        if not os.path.isdir(to_abs):
327
            raise errors.BzrMoveFailedError('', to_dir,
328
                errors.NotADirectory(to_abs))
329
330
        for from_rel in from_paths:
331
            from_tail = os.path.split(from_rel)[-1]
332
            to_rel = os.path.join(to_dir, from_tail)
333
            self.rename_one(from_rel, to_rel, after=after)
334
            rename_tuples.append((from_rel, to_rel))
0.200.1328 by Jelmer Vernooij
More test fixes.
335
        self.flush()
0.200.1193 by Jelmer Vernooij
Implement GitWorkingTree.{move,rename_one}.
336
        return rename_tuples
337
0.200.1308 by Jelmer Vernooij
Write index to disk after adding files.
338
    @needs_tree_write_lock
0.200.1193 by Jelmer Vernooij
Implement GitWorkingTree.{move,rename_one}.
339
    def rename_one(self, from_rel, to_rel, after=False):
0.200.1203 by Jelmer Vernooij
Fix per_workingtree.test_rename_one.TestRenameOne.test_rename_after_non_existant_non_ascii
340
        from_path = from_rel.encode("utf-8")
341
        to_path = to_rel.encode("utf-8")
342
        if not self.has_filename(to_rel):
343
            raise errors.BzrMoveFailedError(from_rel, to_rel,
344
                errors.NoSuchFile(to_rel))
345
        if not from_path in self.index:
346
            raise errors.BzrMoveFailedError(from_rel, to_rel,
347
                errors.NotVersionedError(path=from_rel))
0.200.1355 by Jelmer Vernooij
Fix missing import of posix.
348
        if not after:
349
            os.rename(self.abspath(from_rel), self.abspath(to_rel))
0.200.1203 by Jelmer Vernooij
Fix per_workingtree.test_rename_one.TestRenameOne.test_rename_after_non_existant_non_ascii
350
        self.index[to_path] = self.index[from_path]
351
        del self.index[from_path]
0.200.1328 by Jelmer Vernooij
More test fixes.
352
        self.flush()
0.200.1193 by Jelmer Vernooij
Implement GitWorkingTree.{move,rename_one}.
353
0.264.1 by Jelmer Vernooij
Provide stubs using inventory for the moment.:
354
    def get_root_id(self):
0.200.1192 by Jelmer Vernooij
Implement path2id.
355
        return self.path2id("")
356
0.200.1242 by Jelmer Vernooij
Support directories better.
357
    def _has_dir(self, path):
358
        if self._versioned_dirs is None:
359
            self._load_dirs()
360
        return path in self._versioned_dirs
361
0.200.1192 by Jelmer Vernooij
Implement path2id.
362
    @needs_read_lock
363
    def path2id(self, path):
0.200.1242 by Jelmer Vernooij
Support directories better.
364
        encoded_path = path.encode("utf-8")
365
        if self._is_versioned(encoded_path):
366
            return self._fileid_map.lookup_file_id(encoded_path)
367
        return None
0.264.1 by Jelmer Vernooij
Provide stubs using inventory for the moment.:
368
0.200.1328 by Jelmer Vernooij
More test fixes.
369
    def _iter_files_recursive(self, from_dir=None):
370
        if from_dir is None:
371
            from_dir = ""
372
        for (dirpath, dirnames, filenames) in os.walk(self.abspath(from_dir)):
0.200.1302 by Jelmer Vernooij
Significantly improve performance of WorkingTree.extras().
373
            dir_relpath = dirpath[len(self.basedir):].strip("/")
374
            if self.bzrdir.is_control_filename(dir_relpath):
0.200.605 by Jelmer Vernooij
Ignore directories in WorkingTree.extras().
375
                continue
0.200.615 by Jelmer Vernooij
Optimize WorkingTree.extras().
376
            for filename in filenames:
0.200.1328 by Jelmer Vernooij
More test fixes.
377
                if not self.mapping.is_special_file(filename):
378
                    yield os.path.join(dir_relpath, filename)
0.200.1327 by Jelmer Vernooij
Factor out all file browsing in extras.
379
380
    def extras(self):
381
        """Yield all unversioned files in this WorkingTree.
382
        """
0.200.1328 by Jelmer Vernooij
More test fixes.
383
        return set(self._iter_files_recursive()) - set(self.index)
0.200.605 by Jelmer Vernooij
Ignore directories in WorkingTree.extras().
384
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
385
    def unlock(self):
0.200.224 by Jelmer Vernooij
Fix working tree locking.
386
        # non-implementation specific cleanup
387
        self._cleanup()
388
389
        # reverse order of locking.
390
        try:
391
            return self._control_files.unlock()
392
        finally:
393
            self.branch.unlock()
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
394
0.200.382 by Jelmer Vernooij
Support flushing index.
395
    def flush(self):
396
        # TODO: Maybe this should only write on dirty ?
397
        if self._control_files._lock_mode != 'w':
398
            raise errors.NotWriteLocked(self)
0.200.385 by Jelmer Vernooij
Cope with removed files.
399
        self.index.write()
0.200.382 by Jelmer Vernooij
Support flushing index.
400
0.264.1 by Jelmer Vernooij
Provide stubs using inventory for the moment.:
401
    def __iter__(self):
0.264.2 by Jelmer Vernooij
Implement GitWorkingTree.{_add,__iter__,id2path}.
402
        for path in self.index:
0.200.1192 by Jelmer Vernooij
Implement path2id.
403
            yield self.path2id(path)
0.200.1242 by Jelmer Vernooij
Support directories better.
404
        self._load_dirs()
405
        for path in self._versioned_dirs:
406
            yield self.path2id(path)
0.264.1 by Jelmer Vernooij
Provide stubs using inventory for the moment.:
407
0.200.1202 by Jelmer Vernooij
Implement has_or_had_id.
408
    def has_or_had_id(self, file_id):
409
        if self.has_id(file_id):
410
            return True
411
        if self.had_id(file_id):
412
            return True
413
        return False
414
415
    def had_id(self, file_id):
416
        path = self._basis_fileid_map.lookup_file_id(file_id)
417
        try:
418
            head = self.repository._git.head()
419
        except KeyError:
420
            # Assume no if basis is not accessible
421
            return False
0.200.1205 by Jelmer Vernooij
Implement GitWorkingTree.stored_kind.
422
        if head == ZERO_SHA:
423
            return False
0.200.1202 by Jelmer Vernooij
Implement has_or_had_id.
424
        root_tree = self.store[head].tree
425
        try:
426
            tree_lookup_path(self.store.__getitem__, root_tree, path)
427
        except KeyError:
428
            return False
429
        else:
430
            return True
431
0.200.1198 by Jelmer Vernooij
Implement GitWorkingTree.has_id.
432
    def has_id(self, file_id):
433
        try:
434
            self.id2path(file_id)
435
        except errors.NoSuchId:
436
            return False
437
        else:
438
            return True
439
0.264.1 by Jelmer Vernooij
Provide stubs using inventory for the moment.:
440
    def id2path(self, file_id):
0.264.2 by Jelmer Vernooij
Implement GitWorkingTree.{_add,__iter__,id2path}.
441
        if type(file_id) != str:
442
            raise AssertionError
443
        path = self._fileid_map.lookup_path(file_id)
0.200.1213 by Jelmer Vernooij
Add note about directories.
444
        # FIXME: What about directories?
0.200.1242 by Jelmer Vernooij
Support directories better.
445
        if self._is_versioned(path):
446
            return path.decode("utf-8")
0.200.1214 by Jelmer Vernooij
Set container when raising NoSuchId.
447
        raise errors.NoSuchId(self, file_id)
0.264.1 by Jelmer Vernooij
Provide stubs using inventory for the moment.:
448
0.200.1200 by Jelmer Vernooij
Support GitWorkingTree.get_file_mtime.
449
    def get_file_mtime(self, file_id, path=None):
450
        """See Tree.get_file_mtime."""
451
        if not path:
452
            path = self.id2path(file_id)
453
        return os.lstat(self.abspath(path)).st_mtime
454
0.200.409 by Jelmer Vernooij
Support parsing .gitignore.
455
    def get_ignore_list(self):
456
        ignoreset = getattr(self, '_ignoreset', None)
457
        if ignoreset is not None:
458
            return ignoreset
459
460
        ignore_globs = set()
461
        ignore_globs.update(ignores.get_runtime_ignores())
462
        ignore_globs.update(ignores.get_user_ignores())
463
        if self.has_filename(IGNORE_FILENAME):
464
            f = self.get_file_byname(IGNORE_FILENAME)
465
            try:
0.200.1198 by Jelmer Vernooij
Implement GitWorkingTree.has_id.
466
                # FIXME: Parse git file format, rather than assuming it's
467
                # the same as for bzr's native formats.
0.200.409 by Jelmer Vernooij
Support parsing .gitignore.
468
                ignore_globs.update(ignores.parse_ignore_file(f))
469
            finally:
470
                f.close()
471
        self._ignoreset = ignore_globs
472
        return ignore_globs
473
0.200.508 by Jelmer Vernooij
Skip inventory caching bits.
474
    def set_last_revision(self, revid):
475
        self._change_last_revision(revid)
476
0.200.379 by Jelmer Vernooij
Re-enable working tree support.
477
    def _reset_data(self):
0.248.3 by Jelmer Vernooij
Handle working trees without valid HEAD branch.
478
        try:
479
            head = self.repository._git.head()
480
        except KeyError, name:
0.200.1308 by Jelmer Vernooij
Write index to disk after adding files.
481
            raise errors.NotBranchError("branch %s at %s" % (name,
482
                self.repository.base))
0.200.948 by Jelmer Vernooij
Cope with empty inventories.
483
        if head == ZERO_SHA:
0.200.1202 by Jelmer Vernooij
Implement has_or_had_id.
484
            self._basis_fileid_map = GitFileIdMap({}, self.mapping)
0.200.948 by Jelmer Vernooij
Cope with empty inventories.
485
        else:
0.200.1308 by Jelmer Vernooij
Write index to disk after adding files.
486
            self._basis_fileid_map = self.mapping.get_fileid_map(
487
                self.store.__getitem__, self.store[head].tree)
0.200.379 by Jelmer Vernooij
Re-enable working tree support.
488
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
489
    @needs_read_lock
0.200.1302 by Jelmer Vernooij
Significantly improve performance of WorkingTree.extras().
490
    def get_file_verifier(self, file_id, path=None, stat_value=None):
491
        if path is None:
492
            path = self.id2path(file_id)
493
        return ("GIT", self.index[path][-2])
494
495
    @needs_read_lock
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
496
    def get_file_sha1(self, file_id, path=None, stat_value=None):
497
        if not path:
0.264.2 by Jelmer Vernooij
Implement GitWorkingTree.{_add,__iter__,id2path}.
498
            path = self.id2path(file_id)
0.200.1302 by Jelmer Vernooij
Significantly improve performance of WorkingTree.extras().
499
        abspath = self.abspath(path).encode(osutils._fs_enc)
0.239.4 by Jelmer Vernooij
Cope with nonexistent files and directories in get_file_sha1.
500
        try:
0.200.1302 by Jelmer Vernooij
Significantly improve performance of WorkingTree.extras().
501
            return osutils.sha_file_by_name(abspath)
0.239.4 by Jelmer Vernooij
Cope with nonexistent files and directories in get_file_sha1.
502
        except OSError, (num, msg):
503
            if num in (errno.EISDIR, errno.ENOENT):
504
                return None
505
            raise
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
506
0.200.610 by Jelmer Vernooij
Support retrieving basis tree properly.
507
    def revision_tree(self, revid):
508
        return self.repository.revision_tree(revid)
509
0.200.1242 by Jelmer Vernooij
Support directories better.
510
    def _is_versioned(self, path):
511
        return (path in self.index or self._has_dir(path))
512
0.200.1239 by Jelmer Vernooij
Implement GitWorkingTree.filter_unversioned_files.
513
    def filter_unversioned_files(self, files):
0.200.1316 by Jelmer Vernooij
Fix filter_unversioned_files.
514
        return set([p for p in files if not self._is_versioned(p.encode("utf-8"))])
0.200.1239 by Jelmer Vernooij
Implement GitWorkingTree.filter_unversioned_files.
515
0.264.11 by Jelmer Vernooij
Completer implementation of iter_entries_by_dir and list_files.
516
    def _get_dir_ie(self, path, parent_id):
0.200.1192 by Jelmer Vernooij
Implement path2id.
517
        file_id = self.path2id(path)
0.264.11 by Jelmer Vernooij
Completer implementation of iter_entries_by_dir and list_files.
518
        return inventory.InventoryDirectory(file_id,
0.200.1190 by Jelmer Vernooij
Fix get_symlink_target call.
519
            posixpath.basename(path).strip("/"), parent_id)
0.264.11 by Jelmer Vernooij
Completer implementation of iter_entries_by_dir and list_files.
520
521
    def _add_missing_parent_ids(self, path, dir_ids):
522
        if path in dir_ids:
523
            return []
524
        parent = posixpath.dirname(path).strip("/")
525
        ret = self._add_missing_parent_ids(parent, dir_ids)
526
        parent_id = dir_ids[parent]
527
        ie = self._get_dir_ie(path, parent_id)
528
        dir_ids[path] = ie.file_id
529
        ret.append((path, ie))
530
        return ret
531
0.200.1321 by Jelmer Vernooij
More fixes for compatibility with bzr.dev testsuite.
532
    def _get_file_ie(self, name, path, value, parent_id):
533
        assert isinstance(name, unicode)
0.200.1192 by Jelmer Vernooij
Implement path2id.
534
        assert isinstance(path, unicode)
0.264.10 by Jelmer Vernooij
Yield inventory entries.
535
        assert isinstance(value, tuple) and len(value) == 10
536
        (ctime, mtime, dev, ino, mode, uid, gid, size, sha, flags) = value
0.200.1192 by Jelmer Vernooij
Implement path2id.
537
        file_id = self.path2id(path)
0.264.10 by Jelmer Vernooij
Yield inventory entries.
538
        if type(file_id) != str:
539
            raise AssertionError
540
        kind = mode_kind(mode)
0.200.1321 by Jelmer Vernooij
More fixes for compatibility with bzr.dev testsuite.
541
        ie = inventory.entry_factory[kind](file_id, name, parent_id)
0.264.10 by Jelmer Vernooij
Yield inventory entries.
542
        if kind == 'symlink':
0.200.1190 by Jelmer Vernooij
Fix get_symlink_target call.
543
            ie.symlink_target = self.get_symlink_target(file_id)
0.264.10 by Jelmer Vernooij
Yield inventory entries.
544
        else:
545
            data = self.get_file_text(file_id, path)
546
            ie.text_sha1 = osutils.sha_string(data)
547
            ie.text_size = len(data)
548
            ie.executable = self.is_executable(file_id, path)
549
        ie.revision = None
550
        return ie
551
0.264.11 by Jelmer Vernooij
Completer implementation of iter_entries_by_dir and list_files.
552
    def _is_executable_from_path_and_stat_from_stat(self, path, stat_result):
553
        mode = stat_result.st_mode
554
        return bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
555
0.200.1205 by Jelmer Vernooij
Implement GitWorkingTree.stored_kind.
556
    def stored_kind(self, file_id, path=None):
557
        if path is None:
558
            path = self.id2path(file_id)
0.200.1328 by Jelmer Vernooij
More test fixes.
559
        try:
560
            return mode_kind(self.index[path.encode("utf-8")][4])
561
        except KeyError:
562
            # Maybe it's a directory?
563
            if self._has_dir(path):
564
                return "directory"
0.200.1205 by Jelmer Vernooij
Implement GitWorkingTree.stored_kind.
565
            raise errors.NoSuchId(self, file_id)
566
0.264.11 by Jelmer Vernooij
Completer implementation of iter_entries_by_dir and list_files.
567
    if not osutils.supports_executable():
568
        def is_executable(self, file_id, path=None):
569
            basis_tree = self.basis_tree()
570
            if file_id in basis_tree:
571
                return basis_tree.is_executable(file_id)
572
            # Default to not executable
573
            return False
574
    else:
575
        def is_executable(self, file_id, path=None):
576
            if not path:
577
                path = self.id2path(file_id)
578
            mode = os.lstat(self.abspath(path)).st_mode
579
            return bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
580
581
        _is_executable_from_path_and_stat = \
582
            _is_executable_from_path_and_stat_from_stat
583
0.264.10 by Jelmer Vernooij
Yield inventory entries.
584
    def list_files(self, include_root=False, from_dir=None, recursive=True):
0.264.11 by Jelmer Vernooij
Completer implementation of iter_entries_by_dir and list_files.
585
        # FIXME: Yield non-versioned files
0.200.1321 by Jelmer Vernooij
More fixes for compatibility with bzr.dev testsuite.
586
        if from_dir is None:
587
            from_dir = ""
0.264.11 by Jelmer Vernooij
Completer implementation of iter_entries_by_dir and list_files.
588
        dir_ids = {}
0.200.1339 by Jelmer Vernooij
Some reformatting.
589
        fk_entries = {'directory': workingtree.TreeDirectory,
590
                      'file': workingtree.TreeFile,
591
                      'symlink': workingtree.TreeLink}
0.200.1192 by Jelmer Vernooij
Implement path2id.
592
        root_ie = self._get_dir_ie(u"", None)
0.264.11 by Jelmer Vernooij
Completer implementation of iter_entries_by_dir and list_files.
593
        if include_root and not from_dir:
594
            yield "", "V", root_ie.kind, root_ie.file_id, root_ie
0.200.1192 by Jelmer Vernooij
Implement path2id.
595
        dir_ids[u""] = root_ie.file_id
0.200.1328 by Jelmer Vernooij
More test fixes.
596
        if recursive:
597
            path_iterator = self._iter_files_recursive(from_dir)
598
        else:
599
            if from_dir is None:
600
                start = self.basedir
601
            else:
602
                start = os.path.join(self.basedir, from_dir)
603
            path_iterator = sorted([os.path.join(from_dir, name) for name in
604
                os.listdir(start) if not self.bzrdir.is_control_filename(name)
605
                and not self.mapping.is_special_file(name)])
606
        for path in path_iterator:
607
            try:
608
                value = self.index[path]
609
            except KeyError:
610
                value = None
0.200.1192 by Jelmer Vernooij
Implement path2id.
611
            path = path.decode("utf-8")
0.200.1321 by Jelmer Vernooij
More fixes for compatibility with bzr.dev testsuite.
612
            parent, name = posixpath.split(path)
0.264.11 by Jelmer Vernooij
Completer implementation of iter_entries_by_dir and list_files.
613
            for dir_path, dir_ie in self._add_missing_parent_ids(parent, dir_ids):
614
                yield dir_path, "V", dir_ie.kind, dir_ie.file_id, dir_ie
0.200.1328 by Jelmer Vernooij
More test fixes.
615
            if value is not None:
616
                ie = self._get_file_ie(name, path, value, dir_ids[parent])
617
                yield path, "V", ie.kind, ie.file_id, ie
618
            else:
619
                kind = osutils.file_kind(self.abspath(path))
620
                ie = fk_entries[kind]()
621
                yield path, "?", kind, None, ie
0.264.10 by Jelmer Vernooij
Yield inventory entries.
622
0.200.1206 by Jelmer Vernooij
Implement GitWorkingTree.all_file_ids.
623
    def all_file_ids(self):
624
        ids = {u"": self.path2id("")}
625
        for path in self.index:
0.200.1328 by Jelmer Vernooij
More test fixes.
626
            if self.mapping.is_special_file(path):
627
                continue
0.200.1206 by Jelmer Vernooij
Implement GitWorkingTree.all_file_ids.
628
            path = path.decode("utf-8")
629
            parent = posixpath.dirname(path).strip("/")
630
            for e in self._add_missing_parent_ids(parent, ids):
631
                pass
632
            ids[path] = self.path2id(path)
633
        return set(ids.values())
634
0.264.9 by Jelmer Vernooij
Implement basic GitWorkingTree.iter_entries_by_dir.
635
    def iter_entries_by_dir(self, specific_file_ids=None, yield_parents=False):
636
        # FIXME: Is return order correct?
0.200.1252 by Jelmer Vernooij
Support specific_file_ids in GitWorkingTree.iter_entries_by_dir.
637
        if yield_parents:
638
            raise NotImplementedError(self.iter_entries_by_dir)
0.264.9 by Jelmer Vernooij
Implement basic GitWorkingTree.iter_entries_by_dir.
639
        if specific_file_ids is not None:
0.200.1252 by Jelmer Vernooij
Support specific_file_ids in GitWorkingTree.iter_entries_by_dir.
640
            specific_paths = [self.id2path(file_id) for file_id in specific_file_ids]
641
            if specific_paths in ([u""], []):
642
                specific_paths = None
643
            else:
644
                specific_paths = set(specific_paths)
645
        else:
646
            specific_paths = None
0.200.1192 by Jelmer Vernooij
Implement path2id.
647
        root_ie = self._get_dir_ie(u"", None)
0.200.1252 by Jelmer Vernooij
Support specific_file_ids in GitWorkingTree.iter_entries_by_dir.
648
        if specific_paths is None:
649
            yield u"", root_ie
0.200.1192 by Jelmer Vernooij
Implement path2id.
650
        dir_ids = {u"": root_ie.file_id}
0.264.10 by Jelmer Vernooij
Yield inventory entries.
651
        for path, value in self.index.iteritems():
0.200.1328 by Jelmer Vernooij
More test fixes.
652
            if self.mapping.is_special_file(path):
653
                continue
0.200.1192 by Jelmer Vernooij
Implement path2id.
654
            path = path.decode("utf-8")
0.200.1252 by Jelmer Vernooij
Support specific_file_ids in GitWorkingTree.iter_entries_by_dir.
655
            if specific_paths is not None and not path in specific_paths:
656
                continue
0.200.1321 by Jelmer Vernooij
More fixes for compatibility with bzr.dev testsuite.
657
            (parent, name) = posixpath.split(path)
0.200.1251 by Jelmer Vernooij
Cope with files dissapearing in GitWorkingTree.
658
            try:
0.200.1321 by Jelmer Vernooij
More fixes for compatibility with bzr.dev testsuite.
659
                file_ie = self._get_file_ie(name, path, value, None)
0.200.1251 by Jelmer Vernooij
Cope with files dissapearing in GitWorkingTree.
660
            except IOError:
661
                continue
0.200.1207 by Jelmer Vernooij
Fix some formatting.
662
            for (dir_path, dir_ie) in self._add_missing_parent_ids(parent,
663
                    dir_ids):
0.264.11 by Jelmer Vernooij
Completer implementation of iter_entries_by_dir and list_files.
664
                yield dir_path, dir_ie
0.200.1251 by Jelmer Vernooij
Cope with files dissapearing in GitWorkingTree.
665
            file_ie.parent_id = self.path2id(parent)
666
            yield path, file_ie
0.264.9 by Jelmer Vernooij
Implement basic GitWorkingTree.iter_entries_by_dir.
667
0.200.619 by Jelmer Vernooij
Provide dummy WorkingTree.conflicts() implementation rather than spending a lot of time not finding any conflicts.
668
    @needs_read_lock
669
    def conflicts(self):
670
        # FIXME:
0.262.1 by Jelmer Vernooij
Fix WorkingTree.conflicts().
671
        return _mod_conflicts.ConflictList()
0.200.619 by Jelmer Vernooij
Provide dummy WorkingTree.conflicts() implementation rather than spending a lot of time not finding any conflicts.
672
0.200.1193 by Jelmer Vernooij
Implement GitWorkingTree.{move,rename_one}.
673
    def update_basis_by_delta(self, new_revid, delta):
0.200.1196 by Jelmer Vernooij
Implement GitWorkingTree.update_basis_by_delta.
674
        # The index just contains content, which won't have changed.
0.200.1202 by Jelmer Vernooij
Implement has_or_had_id.
675
        self._reset_data()
0.200.1193 by Jelmer Vernooij
Implement GitWorkingTree.{move,rename_one}.
676
0.200.1328 by Jelmer Vernooij
More test fixes.
677
    def get_canonical_inventory_path(self, path):
678
        for p in self.index:
679
            if p.lower() == path.lower():
680
                return p
681
        else:
682
            return path
683
0.200.1210 by Jelmer Vernooij
Implement GitWorkingTree._walkdirs.
684
    def _walkdirs(self, prefix=""):
685
        if prefix != "":
686
            prefix += "/"
687
        per_dir = defaultdict(list)
688
        for path, value in self.index.iteritems():
0.200.1328 by Jelmer Vernooij
More test fixes.
689
            if self.mapping.is_special_file(path):
690
                continue
0.200.1210 by Jelmer Vernooij
Implement GitWorkingTree._walkdirs.
691
            if not path.startswith(prefix):
692
                continue
693
            (dirname, child_name) = posixpath.split(path)
694
            dirname = dirname.decode("utf-8")
695
            dir_file_id = self.path2id(dirname)
696
            assert isinstance(value, tuple) and len(value) == 10
697
            (ctime, mtime, dev, ino, mode, uid, gid, size, sha, flags) = value
0.200.1355 by Jelmer Vernooij
Fix missing import of posix.
698
            stat_result = stat_result((mode, ino,
0.200.1211 by Jelmer Vernooij
Fix statresult.
699
                    dev, 1, uid, gid, size,
700
                    0, mtime, ctime))
0.200.1210 by Jelmer Vernooij
Implement GitWorkingTree._walkdirs.
701
            per_dir[(dirname, dir_file_id)].append(
702
                (path.decode("utf-8"), child_name.decode("utf-8"),
703
                mode_kind(mode), stat_result,
704
                self.path2id(path.decode("utf-8")),
705
                mode_kind(mode)))
706
        return per_dir.iteritems()
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
707
0.200.1308 by Jelmer Vernooij
Write index to disk after adding files.
708
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
709
class GitWorkingTreeFormat(workingtree.WorkingTreeFormat):
710
0.200.1206 by Jelmer Vernooij
Implement GitWorkingTree.all_file_ids.
711
    _tree_class = GitWorkingTree
712
0.200.1295 by Jelmer Vernooij
Mark working trees as not supporting directories.
713
    supports_versioned_directories = False
714
0.200.656 by Jelmer Vernooij
Implement GitWorkingTreeFormat._matchingbzrdir.
715
    @property
716
    def _matchingbzrdir(self):
0.200.1140 by Jelmer Vernooij
Update now that the control dir formats are no longer in __init__.
717
        from bzrlib.plugins.git.dir import LocalGitControlDirFormat
0.200.1013 by Jelmer Vernooij
More renames.
718
        return LocalGitControlDirFormat()
0.200.656 by Jelmer Vernooij
Implement GitWorkingTreeFormat._matchingbzrdir.
719
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
720
    def get_format_description(self):
721
        return "Git Working Tree"
0.200.616 by Jelmer Vernooij
Provide custom intertree implementation for GitRevisionTree->GitWorkingTree.
722
0.200.1096 by Jelmer Vernooij
Implement GitWorkingTreeFormat.initialize.
723
    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
724
                   accelerator_tree=None, hardlink=False):
725
        """See WorkingTreeFormat.initialize()."""
726
        if not isinstance(a_bzrdir, LocalGitDir):
727
            raise errors.IncompatibleFormat(self, a_bzrdir)
728
        index = Index(a_bzrdir.root_transport.local_abspath(".git/index"))
729
        index.write()
730
        return GitWorkingTree(a_bzrdir, a_bzrdir.open_repository(),
731
            a_bzrdir.open_branch(), index)
732
0.200.616 by Jelmer Vernooij
Provide custom intertree implementation for GitRevisionTree->GitWorkingTree.
733
734
class InterIndexGitTree(tree.InterTree):
735
    """InterTree that works between a Git revision tree and an index."""
736
737
    def __init__(self, source, target):
738
        super(InterIndexGitTree, self).__init__(source, target)
739
        self._index = target.index
740
741
    @classmethod
742
    def is_compatible(cls, source, target):
743
        from bzrlib.plugins.git.repository import GitRevisionTree
744
        return (isinstance(source, GitRevisionTree) and 
745
                isinstance(target, GitWorkingTree))
746
747
    def compare(self, want_unchanged=False, specific_files=None,
748
                extra_trees=None, require_versioned=False, include_root=False,
749
                want_unversioned=False):
750
        changes = self._index.changes_from_tree(
0.200.1205 by Jelmer Vernooij
Implement GitWorkingTree.stored_kind.
751
            self.source.store, self.source.tree, 
0.200.616 by Jelmer Vernooij
Provide custom intertree implementation for GitRevisionTree->GitWorkingTree.
752
            want_unchanged=want_unchanged)
0.200.1338 by Jelmer Vernooij
Simplify code for getting file id map.
753
        source_fileid_map = self.source._fileid_map
754
        target_fileid_map = self.target._fileid_map
0.200.1030 by Jelmer Vernooij
More work on supporting roundtripping push.
755
        ret = tree_delta_from_git_changes(changes, self.target.mapping,
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
756
            (source_fileid_map, target_fileid_map),
0.200.616 by Jelmer Vernooij
Provide custom intertree implementation for GitRevisionTree->GitWorkingTree.
757
            specific_file=specific_files, require_versioned=require_versioned)
758
        if want_unversioned:
759
            for e in self.target.extras():
0.200.1207 by Jelmer Vernooij
Fix some formatting.
760
                ret.unversioned.append((e, None,
761
                    osutils.file_kind(self.target.abspath(e))))
0.200.616 by Jelmer Vernooij
Provide custom intertree implementation for GitRevisionTree->GitWorkingTree.
762
        return ret
763
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
764
    def iter_changes(self, include_unchanged=False, specific_files=None,
0.200.1207 by Jelmer Vernooij
Fix some formatting.
765
        pb=None, extra_trees=[], require_versioned=True,
766
        want_unversioned=False):
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
767
        changes = self._index.changes_from_tree(
0.200.1205 by Jelmer Vernooij
Implement GitWorkingTree.stored_kind.
768
            self.source.store, self.source.tree,
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
769
            want_unchanged=include_unchanged)
770
        # FIXME: Handle want_unversioned
0.200.1179 by Jelmer Vernooij
Avoid using verifiers for natively imported revisions, save a lot of time.
771
        return changes_from_git_changes(changes, self.target.mapping,
0.200.622 by Jelmer Vernooij
Implement InterTree.iter_changes() as well.
772
            specific_file=specific_files)
0.200.616 by Jelmer Vernooij
Provide custom intertree implementation for GitRevisionTree->GitWorkingTree.
773
0.200.1179 by Jelmer Vernooij
Avoid using verifiers for natively imported revisions, save a lot of time.
774
0.200.616 by Jelmer Vernooij
Provide custom intertree implementation for GitRevisionTree->GitWorkingTree.
775
tree.InterTree.register_optimiser(InterIndexGitTree)