/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) 2009-2018 Jelmer Vernooij <jelmer@jelmer.uk>
0.200.387 by Jelmer Vernooij
Initial work on supporting commit in git 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
0.358.1 by Jelmer Vernooij
Fix FSF address.
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
0.200.387 by Jelmer Vernooij
Initial work on supporting commit in git trees.
16
0.200.405 by Jelmer Vernooij
More work on commit.
17
18
"""Support for committing in native Git working trees."""
19
0.200.1594 by Jelmer Vernooij
Use absolute_import everywhere.
20
from __future__ import absolute_import
0.200.405 by Jelmer Vernooij
More work on commit.
21
0.200.459 by Jelmer Vernooij
Use new commit_tree function from dulwich.
22
from dulwich.index import (
23
    commit_tree,
24
    )
0.200.1544 by Jelmer Vernooij
Hackishly fix tree references.
25
import os
0.200.405 by Jelmer Vernooij
More work on commit.
26
import stat
27
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
28
from ... import (
0.386.1 by Jelmer Vernooij
Support signing commits.
29
    config as _mod_config,
30
    gpg,
0.200.1700 by Jelmer Vernooij
Implement get_basis_delta.
31
    osutils,
0.200.1217 by Jelmer Vernooij
Support committing from a tree that does not have a basis tree.
32
    revision as _mod_revision,
33
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
34
from ...errors import (
0.333.1 by Jelmer Vernooij
Raise exception when unable to set file ids.
35
    BzrError,
0.200.1144 by Jelmer Vernooij
Raise RootMissing if root not specified.
36
    RootMissing,
0.333.1 by Jelmer Vernooij
Raise exception when unable to set file ids.
37
    UnsupportedOperation,
0.200.1144 by Jelmer Vernooij
Raise RootMissing if root not specified.
38
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
39
from ...repository import (
0.200.387 by Jelmer Vernooij
Initial work on supporting commit in git trees.
40
    CommitBuilder,
41
    )
42
43
from dulwich.objects import (
0.200.521 by Jelmer Vernooij
Abstract out kind mapping a bit, initial work on support tree-references.
44
    S_IFGITLINK,
0.200.459 by Jelmer Vernooij
Use new commit_tree function from dulwich.
45
    Blob,
0.200.387 by Jelmer Vernooij
Initial work on supporting commit in git trees.
46
    Commit,
47
    )
0.200.1544 by Jelmer Vernooij
Hackishly fix tree references.
48
from dulwich.repo import Repo
0.200.387 by Jelmer Vernooij
Initial work on supporting commit in git trees.
49
50
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
51
from .mapping import (
0.200.510 by Jelmer Vernooij
Fill in old entries.
52
    entry_mode,
0.200.1762 by Jelmer Vernooij
Fix mode handling.
53
    object_mode,
0.200.1711 by Jelmer Vernooij
Fix up identifiers if no fullname is set.
54
    fix_person_identifier,
0.200.510 by Jelmer Vernooij
Fill in old entries.
55
    )
0.365.1 by Jelmer Vernooij
Add custom GitTree{Directory,File,Symlink}.
56
from .tree import entry_factory
0.200.510 by Jelmer Vernooij
Fill in old entries.
57
58
0.333.1 by Jelmer Vernooij
Raise exception when unable to set file ids.
59
class SettingCustomFileIdsUnsupported(UnsupportedOperation):
60
61
    _fmt = "Unable to store addition of file with custom file ids: %(file_ids)r"
62
63
    def __init__(self, file_ids):
64
        BzrError.__init__(self)
65
        self.file_ids = file_ids
66
67
0.200.387 by Jelmer Vernooij
Initial work on supporting commit in git trees.
68
class GitCommitBuilder(CommitBuilder):
0.200.1144 by Jelmer Vernooij
Raise RootMissing if root not specified.
69
    """Commit builder for Git repositories."""
70
71
    supports_record_entry_contents = False
0.200.387 by Jelmer Vernooij
Initial work on supporting commit in git trees.
72
73
    def __init__(self, *args, **kwargs):
74
        super(GitCommitBuilder, self).__init__(*args, **kwargs)
0.200.1667 by Jelmer Vernooij
Set random_revid and _new_revision_id properties.
75
        self.random_revid = True
0.200.1247 by Jelmer Vernooij
Validate revprops during commit.
76
        self._validate_revprops(self._revprops)
0.200.509 by Jelmer Vernooij
Fix a bunch of bugs in commit, partially works now.
77
        self.store = self.repository._git.object_store
0.200.459 by Jelmer Vernooij
Use new commit_tree function from dulwich.
78
        self._blobs = {}
0.200.1700 by Jelmer Vernooij
Implement get_basis_delta.
79
        self._inv_delta = []
0.200.1229 by Jelmer Vernooij
Provide CommitBuilder.any_changes.
80
        self._any_changes = False
0.200.1328 by Jelmer Vernooij
More test fixes.
81
        self._override_fileids = {}
82
        self._mapping = self.repository.get_mapping()
0.200.1229 by Jelmer Vernooij
Provide CommitBuilder.any_changes.
83
84
    def any_changes(self):
85
        return self._any_changes
0.200.387 by Jelmer Vernooij
Initial work on supporting commit in git trees.
86
87
    def record_iter_changes(self, workingtree, basis_revid, iter_changes):
0.200.1544 by Jelmer Vernooij
Hackishly fix tree references.
88
        def treeref_sha1(path, file_id):
89
            return Repo.open(os.path.join(workingtree.basedir, path)).head()
0.200.1144 by Jelmer Vernooij
Raise RootMissing if root not specified.
90
        seen_root = False
0.200.668 by Jelmer Vernooij
Fix some places where we were way too much memory for repositories with a large number of entries in the inventory and a large number of revisions.
91
        for (file_id, path, changed_content, versioned, parent, name, kind,
0.200.387 by Jelmer Vernooij
Initial work on supporting commit in git trees.
92
             executable) in iter_changes:
93
            if kind[1] in ("directory",):
0.200.1700 by Jelmer Vernooij
Implement get_basis_delta.
94
                self._inv_delta.append((path[0], path[1], file_id, entry_factory[kind[1]](file_id, name[1], parent[1])))
0.200.387 by Jelmer Vernooij
Initial work on supporting commit in git trees.
95
                if kind[0] in ("file", "symlink"):
0.200.1665 by Jelmer Vernooij
Rename _matchingbzrdir to _matchingcnotroldir.
96
                    self._blobs[path[0].encode("utf-8")] = None
0.200.1719 by Jelmer Vernooij
Fix pointless test.
97
                    self._any_changes = True
0.200.1144 by Jelmer Vernooij
Raise RootMissing if root not specified.
98
                if path[1] == "":
99
                    seen_root = True
0.200.387 by Jelmer Vernooij
Initial work on supporting commit in git trees.
100
                continue
0.200.1719 by Jelmer Vernooij
Fix pointless test.
101
            self._any_changes = True
0.200.460 by Jelmer Vernooij
Somewhat fix commit in git working trees.
102
            if path[1] is None:
0.200.1700 by Jelmer Vernooij
Implement get_basis_delta.
103
                self._inv_delta.append((path[0], path[1], file_id, None))
0.200.1665 by Jelmer Vernooij
Rename _matchingbzrdir to _matchingcnotroldir.
104
                self._blobs[path[0].encode("utf-8")] = None
0.200.460 by Jelmer Vernooij
Somewhat fix commit in git working trees.
105
                continue
0.200.1706 by Jelmer Vernooij
Improve KeyError.
106
            try:
107
                entry_kls = entry_factory[kind[1]]
108
            except KeyError:
109
                raise KeyError("unknown kind %s" % kind[1])
110
            entry = entry_kls(file_id, name[1], parent[1])
0.200.509 by Jelmer Vernooij
Fix a bunch of bugs in commit, partially works now.
111
            if kind[1] == "file":
0.200.1700 by Jelmer Vernooij
Implement get_basis_delta.
112
                entry.executable = executable[1]
113
                blob = Blob()
0.345.1 by Jelmer Vernooij
Fix handling of content reporting for symlinks.
114
                f, st = workingtree.get_file_with_stat(path[1], file_id)
115
                try:
116
                    blob.data = f.read()
117
                finally:
118
                    f.close()
0.200.1700 by Jelmer Vernooij
Implement get_basis_delta.
119
                entry.text_size = len(blob.data)
120
                entry.text_sha1 = osutils.sha_string(blob.data)
121
                self.store.add_object(blob)
122
                sha = blob.id
0.200.509 by Jelmer Vernooij
Fix a bunch of bugs in commit, partially works now.
123
            elif kind[1] == "symlink":
0.200.1700 by Jelmer Vernooij
Implement get_basis_delta.
124
                symlink_target = workingtree.get_symlink_target(path[1], file_id)
125
                blob = Blob()
126
                blob.data = symlink_target.encode("utf-8")
127
                self.store.add_object(blob)
128
                sha = blob.id
129
                entry.symlink_target = symlink_target
0.345.1 by Jelmer Vernooij
Fix handling of content reporting for symlinks.
130
                st = None
0.200.521 by Jelmer Vernooij
Abstract out kind mapping a bit, initial work on support tree-references.
131
            elif kind[1] == "tree-reference":
0.200.1544 by Jelmer Vernooij
Hackishly fix tree references.
132
                sha = treeref_sha1(path[1], file_id)
0.200.1700 by Jelmer Vernooij
Implement get_basis_delta.
133
                reference_revision = workingtree.get_reference_revision(path[1], file_id)
134
                entry.reference_revision = reference_revision
0.345.1 by Jelmer Vernooij
Fix handling of content reporting for symlinks.
135
                st = None
0.200.509 by Jelmer Vernooij
Fix a bunch of bugs in commit, partially works now.
136
            else:
137
                raise AssertionError("Unknown kind %r" % kind[1])
0.200.1762 by Jelmer Vernooij
Fix mode handling.
138
            mode = object_mode(kind[1], executable[1])
0.200.1700 by Jelmer Vernooij
Implement get_basis_delta.
139
            self._inv_delta.append((path[0], path[1], file_id, entry))
0.200.1348 by Jelmer Vernooij
Fix handling of file id map.
140
            encoded_new_path = path[1].encode("utf-8")
141
            self._blobs[encoded_new_path] = (mode, sha)
0.345.1 by Jelmer Vernooij
Fix handling of content reporting for symlinks.
142
            if st is not None:
143
                yield file_id, path[1], (entry.text_sha1, st)
0.333.1 by Jelmer Vernooij
Raise exception when unable to set file ids.
144
            if self._mapping.generate_file_id(encoded_new_path) != file_id:
145
                self._override_fileids[encoded_new_path] = file_id
146
            else:
147
                self._override_fileids[encoded_new_path] = None
0.200.1144 by Jelmer Vernooij
Raise RootMissing if root not specified.
148
        if not seen_root and len(self.parents) == 0:
149
            raise RootMissing()
0.200.1217 by Jelmer Vernooij
Support committing from a tree that does not have a basis tree.
150
        if getattr(workingtree, "basis_tree", False):
151
            basis_tree = workingtree.basis_tree()
152
        else:
153
            if len(self.parents) == 0:
154
                basis_revid = _mod_revision.NULL_REVISION
155
            else:
156
                basis_revid = self.parents[0]
157
            basis_tree = self.repository.revision_tree(basis_revid)
0.200.510 by Jelmer Vernooij
Fill in old entries.
158
        # Fill in entries that were not changed
159
        for path, entry in basis_tree.iter_entries_by_dir():
0.361.1 by Jelmer Vernooij
Don't use assert.
160
            if type(path) is not unicode:
161
                raise TypeError(path)
0.345.1 by Jelmer Vernooij
Fix handling of content reporting for symlinks.
162
            if entry.kind == 'directory':
0.200.510 by Jelmer Vernooij
Fill in old entries.
163
                continue
0.345.1 by Jelmer Vernooij
Fix handling of content reporting for symlinks.
164
            encoded_path = path.encode('utf-8')
165
            if encoded_path not in self._blobs:
0.200.510 by Jelmer Vernooij
Fill in old entries.
166
                if entry.kind == "symlink":
0.200.1544 by Jelmer Vernooij
Hackishly fix tree references.
167
                    blob = Blob()
0.200.1715 by Jelmer Vernooij
Fix some more tests.
168
                    blob.data = basis_tree.get_symlink_target(path, entry.file_id).encode('utf-8')
0.345.1 by Jelmer Vernooij
Fix handling of content reporting for symlinks.
169
                    self._blobs[encoded_path] = (entry_mode(entry), blob.id)
0.200.1544 by Jelmer Vernooij
Hackishly fix tree references.
170
                elif entry.kind == "file":
171
                    blob = Blob()
0.285.1 by Jelmer Vernooij
Swap arguments for tree methods.
172
                    blob.data = basis_tree.get_file_text(path, entry.file_id)
0.345.1 by Jelmer Vernooij
Fix handling of content reporting for symlinks.
173
                    self._blobs[encoded_path] = (entry_mode(entry), blob.id)
0.200.1544 by Jelmer Vernooij
Hackishly fix tree references.
174
                else:
0.356.1 by Jelmer Vernooij
Remove unused call to _lookup_entry.
175
                    raise NotImplementedError
0.333.1 by Jelmer Vernooij
Raise exception when unable to set file ids.
176
        if not self._lossy:
0.200.1328 by Jelmer Vernooij
More test fixes.
177
            try:
178
                fileid_map = dict(basis_tree._fileid_map.file_ids)
179
            except AttributeError:
180
                fileid_map = {}
0.200.1348 by Jelmer Vernooij
Fix handling of file id map.
181
            for path, file_id in self._override_fileids.iteritems():
0.361.1 by Jelmer Vernooij
Don't use assert.
182
                if type(path) is not str:
183
                    raise TypeError(path)
0.200.1348 by Jelmer Vernooij
Fix handling of file id map.
184
                if file_id is None:
0.333.1 by Jelmer Vernooij
Raise exception when unable to set file ids.
185
                    if path in fileid_map:
186
                        del fileid_map[path]
0.200.1348 by Jelmer Vernooij
Fix handling of file id map.
187
                else:
0.361.1 by Jelmer Vernooij
Don't use assert.
188
                    if type(file_id) is not str:
189
                        raise TypeError(file_id)
0.200.1348 by Jelmer Vernooij
Fix handling of file id map.
190
                    fileid_map[path] = file_id
0.200.1328 by Jelmer Vernooij
More test fixes.
191
            if fileid_map:
192
                fileid_blob = self._mapping.export_fileid_map(fileid_map)
0.320.1 by Jelmer Vernooij
Don't set file ids unless different from default.
193
            else:
194
                fileid_blob = None
195
            if fileid_blob is not None:
0.333.1 by Jelmer Vernooij
Raise exception when unable to set file ids.
196
                if self._mapping.BZR_FILE_IDS_FILE is None:
197
                    raise SettingCustomFileIdsUnsupported(fileid_map)
198
                self.store.add_object(fileid_blob)
0.200.1328 by Jelmer Vernooij
More test fixes.
199
                self._blobs[self._mapping.BZR_FILE_IDS_FILE] = (stat.S_IFREG | 0644, fileid_blob.id)
200
            else:
201
                self._blobs[self._mapping.BZR_FILE_IDS_FILE] = None
0.200.1145 by Jelmer Vernooij
reset new_inventory after record_iter_changes
202
        self.new_inventory = None
0.200.387 by Jelmer Vernooij
Initial work on supporting commit in git trees.
203
0.200.1670 by Jelmer Vernooij
Fix compatibility with newer versions of bzr.
204
    def update_basis(self, tree):
205
        # Nothing to do here
206
        pass
0.200.1230 by Jelmer Vernooij
Provide CommitBuilder.get_basis_delta.
207
0.200.509 by Jelmer Vernooij
Fix a bunch of bugs in commit, partially works now.
208
    def finish_inventory(self):
0.200.510 by Jelmer Vernooij
Fill in old entries.
209
        # eliminate blobs that were removed
0.200.998 by Jelmer Vernooij
Don't modify dictionary during iteration.
210
        for path, entry in iter(self._blobs.items()):
0.200.510 by Jelmer Vernooij
Fill in old entries.
211
            if entry is None:
212
                del self._blobs[path]
0.200.509 by Jelmer Vernooij
Fix a bunch of bugs in commit, partially works now.
213
0.200.737 by Jelmer Vernooij
Add helper function, always set encoding to utf-8.
214
    def _iterblobs(self):
215
        return ((path, sha, mode) for (path, (mode, sha)) in self._blobs.iteritems())
216
0.200.391 by Jelmer Vernooij
Fix syntax error.
217
    def commit(self, message):
0.200.1177 by Jelmer Vernooij
Check message for validity.
218
        self._validate_unicode_text(message, 'commit message')
0.200.387 by Jelmer Vernooij
Initial work on supporting commit in git trees.
219
        c = Commit()
0.200.650 by Jelmer Vernooij
Use standard names for lookup functions.
220
        c.parents = [self.repository.lookup_bzr_revision_id(revid)[0] for revid in self.parents]
0.200.737 by Jelmer Vernooij
Add helper function, always set encoding to utf-8.
221
        c.tree = commit_tree(self.store, self._iterblobs())
0.200.1747 by Jelmer Vernooij
Fix some revprop failures.
222
        c.encoding = self._revprops.pop('git-explicit-encoding', 'utf-8')
0.200.1711 by Jelmer Vernooij
Fix up identifiers if no fullname is set.
223
        c.committer = fix_person_identifier(self._committer.encode(c.encoding))
224
        c.author = fix_person_identifier(self._revprops.pop('author', self._committer).encode(c.encoding))
0.200.1709 by Jelmer Vernooij
Avoid encoding commit supplements.
225
        if self._revprops:
226
            raise NotImplementedError(self._revprops)
0.200.509 by Jelmer Vernooij
Fix a bunch of bugs in commit, partially works now.
227
        c.commit_time = int(self._timestamp)
228
        c.author_time = int(self._timestamp)
0.200.416 by Jelmer Vernooij
Use public properties to set git objects values.
229
        c.commit_timezone = self._timezone
230
        c.author_timezone = self._timezone
0.200.1651 by Jelmer Vernooij
Encode committer/author.
231
        c.message = message.encode(c.encoding)
0.386.1 by Jelmer Vernooij
Support signing commits.
232
        if self._config_stack.get('create_signatures') == _mod_config.SIGN_ALWAYS:
233
            strategy = gpg.GPGStrategy(self._config_stack)
234
            c.gpgsig = strategy.sign(c.as_raw_string(), gpg.MODE_DETACH)
0.200.509 by Jelmer Vernooij
Fix a bunch of bugs in commit, partially works now.
235
        self.store.add_object(c)
0.200.702 by Jelmer Vernooij
properly commit write group
236
        self.repository.commit_write_group()
0.200.1667 by Jelmer Vernooij
Set random_revid and _new_revision_id properties.
237
        self._new_revision_id = self._mapping.revision_id_foreign_to_bzr(c.id)
238
        return self._new_revision_id
0.200.1191 by Jelmer Vernooij
Implement CommitBuilder.revision_tree.
239
0.200.1225 by Jelmer Vernooij
provide explicit CommitBuilder.abort.
240
    def abort(self):
0.334.1 by Jelmer Vernooij
Improve transaction and write group handling.
241
        if self.repository.is_in_write_group():
242
            self.repository.abort_write_group()
0.200.1225 by Jelmer Vernooij
provide explicit CommitBuilder.abort.
243
0.200.1191 by Jelmer Vernooij
Implement CommitBuilder.revision_tree.
244
    def revision_tree(self):
245
        return self.repository.revision_tree(self._new_revision_id)
0.200.1678 by Jelmer Vernooij
Fix tests.
246
247
    def get_basis_delta(self):
0.200.1700 by Jelmer Vernooij
Implement get_basis_delta.
248
        for (oldpath, newpath, file_id, entry) in self._inv_delta:
249
            if entry is not None:
250
                entry.revision = self._new_revision_id
251
        return self._inv_delta
252
253
    def update_basis_by_delta(self, revid, delta):
254
        pass