/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
1
# Copyright (C) 2008 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
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.239.4 by Jelmer Vernooij
Cope with nonexistent files and directories in get_file_sha1.
24
import errno
0.200.383 by Jelmer Vernooij
Simplify, support rewriting index based on inventory.
25
from dulwich.objects import (
26
    Blob,
27
    )
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
28
import os
0.200.384 by Jelmer Vernooij
Fix reading of inventory from index.
29
import stat
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
30
31
from bzrlib import (
0.200.382 by Jelmer Vernooij
Support flushing index.
32
    errors,
0.200.409 by Jelmer Vernooij
Support parsing .gitignore.
33
    ignores,
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
34
    lockable_files,
35
    lockdir,
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
36
    osutils,
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
37
    transport,
0.200.519 by Jelmer Vernooij
Move imports down, might not be available in older bzr-git versions.
38
    tree,
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
39
    urlutils,
40
    workingtree,
41
    )
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
42
from bzrlib.decorators import (
43
    needs_read_lock,
44
    )
45
46
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
47
from bzrlib.plugins.git.inventory import (
48
    GitIndexInventory,
49
    )
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
50
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
51
0.200.409 by Jelmer Vernooij
Support parsing .gitignore.
52
IGNORE_FILENAME = ".gitignore"
53
54
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
55
class GitWorkingTree(workingtree.WorkingTree):
56
    """A Git working tree."""
57
58
    def __init__(self, bzrdir, repo, branch):
0.200.379 by Jelmer Vernooij
Re-enable working tree support.
59
        self.basedir = bzrdir.root_transport.local_abspath('.')
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
60
        self.bzrdir = bzrdir
61
        self.repository = repo
0.200.384 by Jelmer Vernooij
Fix reading of inventory from index.
62
        self.mapping = self.repository.get_mapping()
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
63
        self._branch = branch
64
        self._transport = bzrdir.transport
65
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
66
        self.controldir = urlutils.join(self.repository._git._controldir, 'bzr')
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
67
68
        try:
69
            os.makedirs(self.controldir)
70
            os.makedirs(os.path.join(self.controldir, 'lock'))
71
        except OSError:
72
            pass
73
74
        self._control_files = lockable_files.LockableFiles(
75
            transport.get_transport(self.controldir), 'lock', lockdir.LockDir)
76
        self._format = GitWorkingTreeFormat()
0.200.414 by Jelmer Vernooij
Use new convenience function in dulwich to open index.
77
        self.index = self.repository._git.open_index()
0.200.239 by Jelmer Vernooij
Provide views.
78
        self.views = self._make_views()
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
79
        self._detect_case_handling()
0.200.173 by Jelmer Vernooij
Merge changes, open index.
80
0.200.605 by Jelmer Vernooij
Ignore directories in WorkingTree.extras().
81
    def extras(self):
82
        """Yield all unversioned files in this WorkingTree.
83
        """
84
        for (relroot, top), entries in osutils.walkdirs(self.basedir, ""):
85
            if self.bzrdir.is_control_filename(relroot):
86
                continue
87
            for (relpath, basename, kind, lstat, path_from_top) in entries:
88
                if self.bzrdir.is_control_filename(basename):
89
                    continue
90
                if not self.inventory.has_filename(relpath) and kind in ('file', 'symlink'):
91
                    yield relpath
92
93
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
94
    def unlock(self):
0.200.224 by Jelmer Vernooij
Fix working tree locking.
95
        # non-implementation specific cleanup
96
        self._cleanup()
97
98
        # reverse order of locking.
99
        try:
100
            return self._control_files.unlock()
101
        finally:
102
            self.branch.unlock()
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
103
104
    def is_control_filename(self, path):
105
        return os.path.basename(path) == ".git"
106
0.200.383 by Jelmer Vernooij
Simplify, support rewriting index based on inventory.
107
    def _rewrite_index(self):
108
        self.index.clear()
109
        for path, entry in self._inventory.iter_entries():
110
            if entry.kind == "directory":
111
                # Git indexes don't contain directories
112
                continue
113
            if entry.kind == "file":
114
                blob = Blob()
0.200.385 by Jelmer Vernooij
Cope with removed files.
115
                try:
116
                    file, stat_val = self.get_file_with_stat(entry.file_id, path)
117
                except (errors.NoSuchFile, IOError):
118
                    # TODO: Rather than come up with something here, use the old index
119
                    file = StringIO()
0.239.4 by Jelmer Vernooij
Cope with nonexistent files and directories in get_file_sha1.
120
                    from posix import stat_result
121
                    stat_val = stat_result((stat.S_IFREG | 0644, 0, 0, 0, 0, 0, 0, 0, 0, 0))
0.200.502 by Jelmer Vernooij
Fill in sha1s in inventory.
122
                blob.set_raw_string(file.read())
0.200.383 by Jelmer Vernooij
Simplify, support rewriting index based on inventory.
123
            elif entry.kind == "symlink":
124
                blob = Blob()
0.200.502 by Jelmer Vernooij
Fill in sha1s in inventory.
125
                try:
126
                    stat_val = os.lstat(self.abspath(path))
127
                except (errors.NoSuchFile, OSError):
128
                    # TODO: Rather than come up with something here, use the 
129
                    # old index
0.239.4 by Jelmer Vernooij
Cope with nonexistent files and directories in get_file_sha1.
130
                    from posix import stat_result
131
                    stat_val = stat_result((stat.S_IFLNK, 0, 0, 0, 0, 0, 0, 0, 0, 0))
0.200.502 by Jelmer Vernooij
Fill in sha1s in inventory.
132
                blob.set_raw_string(entry.symlink_target)
0.200.383 by Jelmer Vernooij
Simplify, support rewriting index based on inventory.
133
            # Add object to the repository if it didn't exist yet
134
            if not blob.id in self.repository._git.object_store:
135
                self.repository._git.object_store.add_object(blob)
136
            # Add an entry to the index or update the existing entry
0.200.522 by Jelmer Vernooij
Simplify index handling a bit more.
137
            flags = 0 # FIXME
138
            self.index[path.encode("utf-8")] = (stat_val.st_ctime, stat_val.st_mtime, stat_val.st_dev, stat_val.st_ino, stat_val.st_mode, stat_val.st_uid, stat_val.st_gid, stat_val.st_size, blob.id, flags)
0.200.383 by Jelmer Vernooij
Simplify, support rewriting index based on inventory.
139
0.200.382 by Jelmer Vernooij
Support flushing index.
140
    def flush(self):
141
        # TODO: Maybe this should only write on dirty ?
142
        if self._control_files._lock_mode != 'w':
143
            raise errors.NotWriteLocked(self)
0.200.383 by Jelmer Vernooij
Simplify, support rewriting index based on inventory.
144
        self._rewrite_index()           
0.200.385 by Jelmer Vernooij
Cope with removed files.
145
        self.index.write()
0.200.382 by Jelmer Vernooij
Support flushing index.
146
        self._inventory_is_modified = False
147
0.200.409 by Jelmer Vernooij
Support parsing .gitignore.
148
    def get_ignore_list(self):
149
        ignoreset = getattr(self, '_ignoreset', None)
150
        if ignoreset is not None:
151
            return ignoreset
152
153
        ignore_globs = set()
154
        ignore_globs.update(ignores.get_runtime_ignores())
155
        ignore_globs.update(ignores.get_user_ignores())
156
        if self.has_filename(IGNORE_FILENAME):
157
            f = self.get_file_byname(IGNORE_FILENAME)
158
            try:
159
                ignore_globs.update(ignores.parse_ignore_file(f))
160
            finally:
161
                f.close()
162
        self._ignoreset = ignore_globs
163
        return ignore_globs
164
0.200.508 by Jelmer Vernooij
Skip inventory caching bits.
165
    def set_last_revision(self, revid):
166
        self._change_last_revision(revid)
167
0.200.379 by Jelmer Vernooij
Re-enable working tree support.
168
    def _reset_data(self):
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
169
        self._inventory_is_modified = False
0.200.384 by Jelmer Vernooij
Fix reading of inventory from index.
170
        basis_inv = self.repository.get_inventory(self.mapping.revision_id_foreign_to_bzr(self.repository._git.head()))
0.200.502 by Jelmer Vernooij
Fill in sha1s in inventory.
171
        result = GitIndexInventory(basis_inv, self.mapping, self.index,
172
            self.repository._git.object_store)
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
173
        self._set_inventory(result, dirty=False)
0.200.379 by Jelmer Vernooij
Re-enable working tree support.
174
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
175
    @needs_read_lock
176
    def get_file_sha1(self, file_id, path=None, stat_value=None):
177
        if not path:
178
            path = self._inventory.id2path(file_id)
0.239.4 by Jelmer Vernooij
Cope with nonexistent files and directories in get_file_sha1.
179
        try:
180
            return osutils.sha_file_by_name(self.abspath(path).encode(osutils._fs_enc))
181
        except OSError, (num, msg):
182
            if num in (errno.EISDIR, errno.ENOENT):
183
                return None
184
            raise
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
185
0.200.519 by Jelmer Vernooij
Move imports down, might not be available in older bzr-git versions.
186
    def iter_changes(self, from_tree, include_unchanged=False,
187
                     specific_files=None, pb=None, extra_trees=None,
188
                     require_versioned=True, want_unversioned=False):
189
190
        intertree = tree.InterTree.get(from_tree, self)
191
        return intertree.iter_changes(include_unchanged, specific_files, pb,
192
            extra_trees, require_versioned, want_unversioned=want_unversioned)
193
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
194
195
class GitWorkingTreeFormat(workingtree.WorkingTreeFormat):
196
197
    def get_format_description(self):
198
        return "Git Working Tree"