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

  • Committer: John Arbash Meinel
  • Date: 2010-01-12 22:51:31 UTC
  • mto: This revision was merged to the branch mainline in revision 4955.
  • Revision ID: john@arbash-meinel.com-20100112225131-he8h411p6aeeb947
Delay grabbing an output stream until we actually go to show a diff.

This makes the test suite happy, but it also seems to be reasonable.
If we aren't going to write anything, we don't need to hold an
output stream open.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2009-2010 Jelmer Vernooij <jelmer@samba.org>
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
 
 
17
 
 
18
 
"""Support for committing in native Git working trees."""
19
 
 
20
 
 
21
 
from dulwich.index import (
22
 
    commit_tree,
23
 
    )
24
 
import os
25
 
import stat
26
 
 
27
 
from bzrlib.repository import (
28
 
    CommitBuilder,
29
 
    )
30
 
 
31
 
from dulwich.objects import (
32
 
    S_IFGITLINK,
33
 
    Blob,
34
 
    Commit,
35
 
    )
36
 
 
37
 
 
38
 
from bzrlib.plugins.git.mapping import (
39
 
    entry_mode,
40
 
    )
41
 
 
42
 
 
43
 
class GitCommitBuilder(CommitBuilder):
44
 
 
45
 
    def __init__(self, *args, **kwargs):
46
 
        super(GitCommitBuilder, self).__init__(*args, **kwargs)
47
 
        self.store = self.repository._git.object_store
48
 
        self._blobs = {}
49
 
 
50
 
    def record_entry_contents(self, ie, parent_invs, path, tree,
51
 
        content_summary):
52
 
        raise NotImplementedError(self.record_entry_contents)
53
 
 
54
 
    def record_delete(self, path, file_id):
55
 
        self._blobs[path] = None
56
 
        self._any_changes = True
57
 
 
58
 
    def record_iter_changes(self, workingtree, basis_revid, iter_changes):
59
 
        index = getattr(workingtree, "index", None)
60
 
        if index is not None:
61
 
            def index_sha1(path, file_id):
62
 
                return index.get_sha1(path.encode("utf-8"))
63
 
            text_sha1 = link_sha1 = index_sha1
64
 
        else:
65
 
            def link_sha1(path, file_id):
66
 
                blob = Blob()
67
 
                blob.data = workingtree.get_symlink_target(file_id)
68
 
                return blob.id
69
 
            def text_sha1(path, file_id):
70
 
                blob = Blob()
71
 
                blob.data = workingtree.get_file_text(file_id, path)
72
 
                return blob.id
73
 
        for (file_id, path, changed_content, versioned, parent, name, kind,
74
 
             executable) in iter_changes:
75
 
            if kind[1] in ("directory",):
76
 
                if kind[0] in ("file", "symlink"):
77
 
                    self.record_delete(path[0], file_id)
78
 
                continue
79
 
            if path[1] is None:
80
 
                self.record_delete(path[0], file_id)
81
 
                continue
82
 
            if kind[1] == "file":
83
 
                mode = stat.S_IFREG
84
 
                sha = text_sha1(path[1], file_id)
85
 
            elif kind[1] == "symlink":
86
 
                mode = stat.S_IFLNK
87
 
                sha = link_sha1(path[1], file_id)
88
 
            elif kind[1] == "tree-reference":
89
 
                mode = S_IFGITLINK
90
 
                sha = "FIXME"
91
 
            else:
92
 
                raise AssertionError("Unknown kind %r" % kind[1])
93
 
            if executable[1]:
94
 
                mode |= 0111
95
 
            self._any_changes = True
96
 
            self._blobs[path[1].encode("utf-8")] = (mode, sha)
97
 
            file_sha1 = workingtree.get_file_sha1(file_id, path[1])
98
 
            yield file_id, path[1], (file_sha1, os.lstat(workingtree.abspath(path[1])))
99
 
        # Fill in entries that were not changed
100
 
        basis_tree = workingtree.basis_tree()
101
 
        assert basis_tree.get_revision_id() == basis_revid
102
 
        for path, entry in basis_tree.iter_entries_by_dir():
103
 
            if entry.kind not in ("file", "symlink"):
104
 
                continue
105
 
            if not path in self._blobs:
106
 
                blob = Blob()
107
 
                if entry.kind == "symlink":
108
 
                    blob.data = basis_tree.get_symlink_target(entry.file_id)
109
 
                else:
110
 
                    blob.data = basis_tree.get_file_text(entry.file_id)
111
 
                self._blobs[path.encode("utf-8")] = (entry_mode(entry), blob.id)
112
 
 
113
 
    def finish_inventory(self):
114
 
        # eliminate blobs that were removed
115
 
        for path, entry in iter(self._blobs.items()):
116
 
            if entry is None:
117
 
                del self._blobs[path]
118
 
 
119
 
    def _iterblobs(self):
120
 
        return ((path, sha, mode) for (path, (mode, sha)) in self._blobs.iteritems())
121
 
 
122
 
    def commit(self, message):
123
 
        c = Commit()
124
 
        c.parents = [self.repository.lookup_bzr_revision_id(revid)[0] for revid in self.parents]
125
 
        c.tree = commit_tree(self.store, self._iterblobs())
126
 
        c.committer = self._committer
127
 
        c.author = self._revprops.get('author', self._committer)
128
 
        c.commit_time = int(self._timestamp)
129
 
        c.author_time = int(self._timestamp)
130
 
        c.commit_timezone = self._timezone
131
 
        c.author_timezone = self._timezone
132
 
        c.encoding = 'utf-8'
133
 
        c.message = message.encode("utf-8")
134
 
        self.store.add_object(c)
135
 
        self._new_revision_id = self.repository.get_mapping().revision_id_foreign_to_bzr(c.id)
136
 
        self.repository.commit_write_group()
137
 
        return self._new_revision_id