/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 tree.py

Implement GitRevisionTree.get_file_sha1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 
18
18
"""Git Trees."""
19
19
 
 
20
from dulwich.object_store import tree_lookup_path
 
21
import stat
 
22
import posixpath
 
23
 
20
24
from bzrlib import (
21
25
    delta,
22
26
    errors,
 
27
    inventory,
 
28
    osutils,
23
29
    revisiontree,
24
30
    tree,
25
31
    )
26
32
 
27
 
from bzrlib.plugins.git.inventory import (
28
 
    GitInventory,
29
 
    )
30
33
from bzrlib.plugins.git.mapping import (
31
34
    mode_is_executable,
32
35
    mode_kind,
39
42
    def __init__(self, repository, revision_id):
40
43
        self._revision_id = revision_id
41
44
        self._repository = repository
42
 
        store = repository._git.object_store
 
45
        self.store = repository._git.object_store
43
46
        assert isinstance(revision_id, str)
44
47
        git_id, self.mapping = repository.lookup_bzr_revision_id(revision_id)
45
48
        try:
46
 
            commit = store[git_id]
 
49
            commit = self.store[git_id]
47
50
        except KeyError, r:
48
51
            raise errors.NoSuchRevision(repository, revision_id)
49
52
        self.tree = commit.tree
50
 
        fileid_map = self.mapping.get_fileid_map(store.__getitem__, self.tree)
51
 
        self._inventory = GitInventory(self.tree, self.mapping, fileid_map,
52
 
            store, revision_id)
 
53
        self.fileid_map = self.mapping.get_fileid_map(self.store.__getitem__, self.tree)
 
54
 
 
55
    def id2path(self, file_id):
 
56
        return self.fileid_map.lookup_path(file_id)
 
57
 
 
58
    def path2id(self, path):
 
59
        return self.fileid_map.lookup_file_id(path.encode('utf-8'))
 
60
 
 
61
    def get_root_id(self):
 
62
        return self.path2id("")
 
63
 
 
64
    def has_or_had_id(self, file_id):
 
65
        return self.has_id(file_id)
 
66
 
 
67
    def has_id(self, file_id):
 
68
        try:
 
69
            path = self.id2path(file_id)
 
70
        except errors.NoSuchId:
 
71
            return False
 
72
        return self.has_filename(path)
 
73
 
 
74
    def kind(self, file_id, path=None):
 
75
        if path is None:
 
76
            path = self.id2path(file_id)
 
77
        (mode, hexsha) = tree_lookup_path(self.store.__getitem__, self.tree, path)
 
78
        if mode is None:
 
79
            # the tree root is a directory
 
80
            return "directory"
 
81
        return mode_kind(mode)
 
82
 
 
83
    def has_filename(self, path):
 
84
        try:
 
85
            tree_lookup_path(self.store.__getitem__, self.tree,
 
86
                path.encode("utf-8"))
 
87
        except KeyError:
 
88
            return False
 
89
        else:
 
90
            return True
 
91
 
 
92
    def list_files(self, include_root=False, from_dir=None, recursive=True):
 
93
        if from_dir is None:
 
94
            from_dir = u""
 
95
        (mode, hexsha) = tree_lookup_path(self.store.__getitem__, self.tree,
 
96
            from_dir.encode("utf-8"))
 
97
        if mode is None: # Root
 
98
            root_ie = self._get_dir_ie("", None)
 
99
        else:
 
100
            parent_path = posixpath.dirname(from_dir.encode("utf-8"))
 
101
            parent_id = self.fileid_map.lookup_file_id(parent_path)
 
102
            if mode_kind(mode) == 'directory':
 
103
                root_ie = self._get_dir_ie(from_dir.encode("utf-8"), parent_id)
 
104
            else:
 
105
                root_ie = self._get_file_ie(from_dir.encode("utf-8"),
 
106
                    posixpath.basename(from_dir), mode, hexsha)
 
107
        if from_dir != "" or include_root:
 
108
            yield (from_dir, "V", root_ie.kind, root_ie.file_id, root_ie)
 
109
        todo = set()
 
110
        if root_ie.kind == 'directory':
 
111
            todo.add((from_dir.encode("utf-8"), hexsha, root_ie.file_id))
 
112
        while todo:
 
113
            (path, hexsha, parent_id) = todo.pop()
 
114
            tree = self.store[hexsha]
 
115
            for name, mode, hexsha in tree.iteritems():
 
116
                child_path = posixpath.join(path, name)
 
117
                if stat.S_ISDIR(mode):
 
118
                    ie = self._get_dir_ie(child_path, parent_id)
 
119
                    if recursive:
 
120
                        todo.add((child_path, hexsha, ie.file_id))
 
121
                else:
 
122
                    ie = self._get_file_ie(child_path, name, mode, hexsha, parent_id)
 
123
                yield child_path, "V", ie.kind, ie.file_id, ie
 
124
 
 
125
    def _get_file_ie(self, path, name, mode, hexsha, parent_id):
 
126
        kind = mode_kind(mode)
 
127
        file_id = self.fileid_map.lookup_file_id(path)
 
128
        ie = inventory.entry_factory[kind](file_id, name.decode("utf-8"), parent_id)
 
129
        if kind == 'symlink':
 
130
            ie.symlink_target = self.store[hexsha].data
 
131
        else:
 
132
            data = self.store[hexsha].data
 
133
            ie.text_sha1 = osutils.sha_string(data)
 
134
            ie.text_size = len(data)
 
135
            ie.executable = mode_is_executable(mode)
 
136
        return ie
 
137
 
 
138
    def _get_dir_ie(self, path, parent_id):
 
139
        file_id = self.fileid_map.lookup_file_id(path)
 
140
        return inventory.InventoryDirectory(file_id,
 
141
            posixpath.basename(path).decode("utf-8"), parent_id)
 
142
 
 
143
    def iter_entries_by_dir(self, specific_file_ids=None, yield_parents=False):
 
144
        # FIXME: Support specific_file_ids
 
145
        #FIXME: yield actual inventory entries
 
146
        if specific_file_ids is not None:
 
147
            raise NotImplementedError(self.iter_entries_by_dir)
 
148
        todo = set([("", self.tree, None)])
 
149
        while todo:
 
150
            path, tree_sha, parent_id = todo.pop()
 
151
            ie = self._get_dir_ie(path, parent_id)
 
152
            yield path, ie
 
153
            tree = self.store[tree_sha]
 
154
            for name, mode, hexsha  in tree.iteritems():
 
155
                child_path = posixpath.join(path, name)
 
156
                if stat.S_ISDIR(mode):
 
157
                    todo.add((child_path, hexsha, ie.file_id))
 
158
                else:
 
159
                    yield child_path, self._get_file_ie(path, name, mode, hexsha, ie.file_id)
53
160
 
54
161
    def get_revision_id(self):
55
162
        """See RevisionTree.get_revision_id."""
56
163
        return self._revision_id
57
164
 
 
165
    def get_file_sha1(self, file_id, path=None):
 
166
        return osutils.sha_string(self.get_file_text(file_id, path))
 
167
 
58
168
    def get_file_text(self, file_id, path=None):
59
169
        """See RevisionTree.get_file_text."""
60
 
        if path is not None:
61
 
            entry = self._inventory._get_ie(path)
 
170
        if path is None:
 
171
            path = self.id2path(file_id)
 
172
        (mode, hexsha)= tree_lookup_path(self.store.__getitem__, self.tree, path)
 
173
        if stat.S_ISREG(mode):
 
174
            return self.store[hexsha].data
62
175
        else:
63
 
            entry = self._inventory[file_id]
64
 
        if entry.kind in ('directory', 'tree-reference'):
65
176
            return ""
66
 
        return entry.object.data
 
177
 
 
178
    def _comparison_data(self, entry, path):
 
179
        if entry is None:
 
180
            return None, False, None
 
181
        return entry.kind, entry.executable, None
67
182
 
68
183
 
69
184
def tree_delta_from_git_changes(changes, mapping,