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

  • Committer: Jelmer Vernooij
  • Date: 2017-05-21 12:41:27 UTC
  • mto: This revision was merged to the branch mainline in revision 6623.
  • Revision ID: jelmer@jelmer.uk-20170521124127-iv8etg0vwymyai6y
s/bzr/brz/ in apport config.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 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
 
"""Annotate."""
18
 
 
19
 
from dulwich.object_store import (
20
 
    tree_lookup_path,
21
 
    )
22
 
 
23
 
from .. import osutils
24
 
from ..errors import (
25
 
    NoSuchRevision,
26
 
    UnavailableRepresentation,
27
 
    )
28
 
from ..graph import Graph
29
 
from ..revision import (
30
 
    NULL_REVISION,
31
 
    )
32
 
 
33
 
 
34
 
class GitBlobContentFactory(object):
35
 
    """Static data content factory.
36
 
 
37
 
    This takes a fulltext when created and just returns that during
38
 
    get_bytes_as('fulltext').
39
 
 
40
 
    :ivar sha1: None, or the sha1 of the content fulltext.
41
 
    :ivar storage_kind: The native storage kind of this factory. Always
42
 
        'fulltext'.
43
 
    :ivar key: The key of this content. Each key is a tuple with a single
44
 
        string in it.
45
 
    :ivar parents: A tuple of parent keys for self.key. If the object has
46
 
        no parent information, None (as opposed to () for an empty list of
47
 
        parents).
48
 
     """
49
 
 
50
 
    def __init__(self, store, path, revision, blob_id):
51
 
        """Create a ContentFactory."""
52
 
        self.store = store
53
 
        self.key = (path, revision)
54
 
        self.storage_kind = 'git-blob'
55
 
        self.parents = None
56
 
        self.blob_id = blob_id
57
 
        self.size = None
58
 
 
59
 
    def get_bytes_as(self, storage_kind):
60
 
        if storage_kind == 'fulltext':
61
 
            return self.store[self.blob_id].as_raw_string()
62
 
        elif storage_kind == 'lines':
63
 
            return list(osutils.chunks_to_lines(self.store[self.blob_id].as_raw_chunks()))
64
 
        elif storage_kind == 'chunked':
65
 
            return self.store[self.blob_id].as_raw_chunks()
66
 
        raise UnavailableRepresentation(self.key, storage_kind,
67
 
                                        self.storage_kind)
68
 
 
69
 
    def iter_bytes_as(self, storage_kind):
70
 
        if storage_kind == 'lines':
71
 
            return iter(osutils.chunks_to_lines(self.store[self.blob_id].as_raw_chunks()))
72
 
        elif storage_kind == 'chunked':
73
 
            return iter(self.store[self.blob_id].as_raw_chunks())
74
 
        raise UnavailableRepresentation(self.key, storage_kind,
75
 
                                        self.storage_kind)
76
 
 
77
 
 
78
 
class GitAbsentContentFactory(object):
79
 
    """Absent data content factory.
80
 
 
81
 
    :ivar sha1: None, or the sha1 of the content fulltext.
82
 
    :ivar storage_kind: The native storage kind of this factory. Always
83
 
        'fulltext'.
84
 
    :ivar key: The key of this content. Each key is a tuple with a single
85
 
        string in it.
86
 
    :ivar parents: A tuple of parent keys for self.key. If the object has
87
 
        no parent information, None (as opposed to () for an empty list of
88
 
        parents).
89
 
     """
90
 
 
91
 
    def __init__(self, store, path, revision):
92
 
        """Create a ContentFactory."""
93
 
        self.store = store
94
 
        self.key = (path, revision)
95
 
        self.storage_kind = 'absent'
96
 
        self.parents = None
97
 
        self.size = None
98
 
 
99
 
    def get_bytes_as(self, storage_kind):
100
 
        raise ValueError
101
 
 
102
 
    def iter_bytes_as(self, storage_kind):
103
 
        raise ValueError
104
 
 
105
 
 
106
 
class AnnotateProvider(object):
107
 
 
108
 
    def __init__(self, change_scanner):
109
 
        self.change_scanner = change_scanner
110
 
        self.store = self.change_scanner.repository._git.object_store
111
 
 
112
 
    def _get_parents(self, path, text_revision):
113
 
        commit_id, mapping = (
114
 
            self.change_scanner.repository.lookup_bzr_revision_id(
115
 
                text_revision))
116
 
        text_parents = []
117
 
        path = path.encode('utf-8')
118
 
        for commit_parent in self.store[commit_id].parents:
119
 
            try:
120
 
                (path, text_parent) = (
121
 
                    self.change_scanner.find_last_change_revision(
122
 
                        path, commit_parent))
123
 
            except KeyError:
124
 
                continue
125
 
            if text_parent not in text_parents:
126
 
                text_parents.append(text_parent)
127
 
        return tuple([
128
 
            (path.decode('utf-8'),
129
 
                self.change_scanner.repository.lookup_foreign_revision_id(p))
130
 
            for p in text_parents])
131
 
 
132
 
    def get_parent_map(self, keys):
133
 
        ret = {}
134
 
        for key in keys:
135
 
            (path, text_revision) = key
136
 
            if text_revision == NULL_REVISION:
137
 
                ret[key] = ()
138
 
                continue
139
 
            try:
140
 
                ret[key] = self._get_parents(path, text_revision)
141
 
            except KeyError:
142
 
                pass
143
 
        return ret
144
 
 
145
 
    def get_record_stream(self, keys, ordering, include_delta_closure):
146
 
        if ordering == 'topological':
147
 
            graph = Graph(self)
148
 
            keys = graph.iter_topo_order(keys)
149
 
        store = self.change_scanner.repository._git.object_store
150
 
        for (path, text_revision) in keys:
151
 
            try:
152
 
                commit_id, mapping = (
153
 
                    self.change_scanner.repository.lookup_bzr_revision_id(
154
 
                        text_revision))
155
 
            except NoSuchRevision:
156
 
                yield GitAbsentContentFactory(store, path, text_revision)
157
 
                continue
158
 
 
159
 
            try:
160
 
                tree_id = store[commit_id].tree
161
 
            except KeyError:
162
 
                yield GitAbsentContentFactory(store, path, text_revision)
163
 
                continue
164
 
            try:
165
 
                (mode, blob_sha) = tree_lookup_path(
166
 
                    store.__getitem__, tree_id, path.encode('utf-8'))
167
 
            except KeyError:
168
 
                yield GitAbsentContentFactory(store, path, text_revision)
169
 
            else:
170
 
                yield GitBlobContentFactory(
171
 
                    store, path, text_revision, blob_sha)