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

More work on roundtrip push support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# along with this program; if not, write to the Free Software
16
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
17
 
18
 
"""An adapter between a Git control dir and a Bazaar BzrDir."""
 
18
"""An adapter between a Git control dir and a Bazaar ControlDir."""
19
19
 
20
20
from bzrlib import (
21
 
    bzrdir,
22
21
    errors as bzr_errors,
23
22
    lockable_files,
24
23
    urlutils,
28
27
LockWarner = getattr(lockable_files, "_LockWarner", None)
29
28
 
30
29
from bzrlib.plugins.git import (
31
 
    LocalGitBzrDirFormat,
32
 
    get_rich_root_format,
 
30
    BareLocalGitControlDirFormat,
 
31
    LocalGitControlDirFormat,
33
32
    )
 
33
try:
 
34
    from bzrlib.controldir import (
 
35
        ControlDir,
 
36
        format_registry,
 
37
        )
 
38
except ImportError:
 
39
    # bzr < 2.3
 
40
    from bzrlib.bzrdir import (
 
41
        BzrDir,
 
42
        format_registry,
 
43
        )
 
44
    ControlDir = BzrDir
34
45
 
35
46
 
36
47
class GitLock(object):
70
81
            self._lock_warner = LockWarner(repr(self))
71
82
 
72
83
 
73
 
class GitDir(bzrdir.BzrDir):
 
84
class GitDirConfig(object):
 
85
 
 
86
    def get_default_stack_on(self):
 
87
        return None
 
88
 
 
89
    def set_default_stack_on(self, value):
 
90
        raise bzr_errors.BzrError("Cannot set configuration")
 
91
 
 
92
 
 
93
class GitDir(ControlDir):
74
94
    """An adapter to the '.git' dir used by git."""
75
95
 
76
96
    def is_supported(self):
77
97
        return True
78
98
 
 
99
    def can_convert_format(self):
 
100
        return False
 
101
 
 
102
    def break_lock(self):
 
103
        pass
 
104
 
79
105
    def cloning_metadir(self, stacked=False):
80
 
        return get_rich_root_format(stacked)
 
106
        return format_registry.make_bzrdir("default")
81
107
 
82
108
    def _branch_name_to_ref(self, name):
83
109
        raise NotImplementedError(self._branch_name_to_ref)
84
110
 
85
111
    if bzrlib_version >= (2, 2):
86
 
        def open_branch(self, name=None, ignore_fallbacks=None,
87
 
            unsupported=False):
 
112
        def open_branch(self, name=None, unsupported=False, 
 
113
            ignore_fallbacks=None):
88
114
            return self._open_branch(name=name,
89
115
                ignore_fallbacks=ignore_fallbacks, unsupported=unsupported)
90
116
    else:
92
118
            return self._open_branch(name=None,
93
119
                ignore_fallbacks=ignore_fallbacks, unsupported=unsupported)
94
120
 
 
121
    def get_config(self):
 
122
        return GitDirConfig()
 
123
 
95
124
 
96
125
class LocalGitDir(GitDir):
97
126
    """An adapter to the '.git' dir used by git."""
102
131
 
103
132
    _gitrepository_class = property(_get_gitrepository_class)
104
133
 
 
134
    @property
 
135
    def user_transport(self):
 
136
        return self.root_transport
 
137
 
 
138
    @property
 
139
    def control_transport(self):
 
140
        return self.transport
 
141
 
105
142
    def __init__(self, transport, lockfiles, gitrepo, format):
106
143
        self._format = format
107
144
        self.root_transport = transport
 
145
        self._mode_check_done = False
108
146
        self._git = gitrepo
109
147
        if gitrepo.bare:
110
148
            self.transport = transport
115
153
 
116
154
    def _branch_name_to_ref(self, name):
117
155
        from bzrlib.plugins.git.refs import branch_name_to_ref
118
 
        if name in (None, "HEAD"):
 
156
        ref = branch_name_to_ref(name, None)
 
157
        if ref == "HEAD":
119
158
            from dulwich.repo import SYMREF
120
 
            refcontents = self._git.refs.read_ref("HEAD")
 
159
            refcontents = self._git.refs.read_ref(ref)
121
160
            if refcontents.startswith(SYMREF):
122
 
                name = refcontents[len(SYMREF):]
123
 
            else:
124
 
                name = "HEAD"
125
 
        return branch_name_to_ref(name, "HEAD")
 
161
                ref = refcontents[len(SYMREF):]
 
162
        return ref
126
163
 
127
164
    def is_control_filename(self, filename):
128
165
        return filename == '.git' or filename.startswith('.git/')
129
166
 
130
 
    def get_branch_transport(self, branch_format, name):
 
167
    def get_branch_transport(self, branch_format, name=None):
131
168
        if branch_format is None:
132
169
            return self.transport
133
 
        if isinstance(branch_format, LocalGitBzrDirFormat):
 
170
        if isinstance(branch_format, LocalGitControlDirFormat):
134
171
            return self.transport
135
172
        raise bzr_errors.IncompatibleFormat(branch_format, self._format)
136
173
 
137
174
    def get_repository_transport(self, format):
138
175
        if format is None:
139
176
            return self.transport
140
 
        if isinstance(format, LocalGitBzrDirFormat):
 
177
        if isinstance(format, LocalGitControlDirFormat):
141
178
            return self.transport
142
179
        raise bzr_errors.IncompatibleFormat(format, self._format)
143
180
 
144
181
    def get_workingtree_transport(self, format):
145
182
        if format is None:
146
183
            return self.transport
147
 
        if isinstance(format, LocalGitBzrDirFormat):
 
184
        if isinstance(format, LocalGitControlDirFormat):
148
185
            return self.transport
149
186
        raise bzr_errors.IncompatibleFormat(format, self._format)
150
187
 
156
193
            self._lockfiles)
157
194
 
158
195
    def destroy_branch(self, name=None):
159
 
        del self._git.refs[self._branch_name_to_ref(name)]
 
196
        refname = self._branch_name_to_ref(name)
 
197
        if not refname in self._git.refs:
 
198
            raise bzr_errors.NotBranchError(self.root_transport.base,
 
199
                    bzrdir=self)
 
200
        del self._git.refs[refname]
 
201
 
 
202
    def destroy_repository(self):
 
203
        raise bzr_errors.UnsupportedOperation(self.destroy_repository, self)
 
204
 
 
205
    def destroy_workingtree(self):
 
206
        raise bzr_errors.UnsupportedOperation(self.destroy_workingtree, self)
 
207
 
 
208
    def needs_format_conversion(self, format=None):
 
209
        return not isinstance(self._format, format.__class__)
160
210
 
161
211
    def list_branches(self):
162
212
        ret = []
179
229
                pass
180
230
            else:
181
231
                from bzrlib.plugins.git.workingtree import GitWorkingTree
182
 
                return GitWorkingTree(self, repo, self.open_branch(), index)
 
232
                try:
 
233
                    branch = self.open_branch()
 
234
                except bzr_errors.NotBranchError:
 
235
                    pass
 
236
                else:
 
237
                    return GitWorkingTree(self, repo, branch, index)
183
238
        loc = urlutils.unescape_for_display(self.root_transport.base, 'ascii')
184
239
        raise bzr_errors.NoWorkingTree(loc)
185
240
 
189
244
    def create_branch(self, name=None):
190
245
        refname = self._branch_name_to_ref(name)
191
246
        from dulwich.protocol import ZERO_SHA
192
 
        self._git.refs[refname] = ZERO_SHA
 
247
        self._git.refs[refname or "HEAD"] = ZERO_SHA
193
248
        return self.open_branch(name)
194
249
 
195
250
    def backup_bzrdir(self):
213
268
        finally:
214
269
            f.close()
215
270
        return self.open_workingtree()
 
271
 
 
272
    def find_repository(self):
 
273
        """Find the repository that should be used.
 
274
 
 
275
        This does not require a branch as we use it to find the repo for
 
276
        new branches as well as to hook existing branches up to their
 
277
        repository.
 
278
        """
 
279
        return self.open_repository()
 
280
 
 
281
    def _find_creation_modes(self):
 
282
        """Determine the appropriate modes for files and directories.
 
283
 
 
284
        They're always set to be consistent with the base directory,
 
285
        assuming that this transport allows setting modes.
 
286
        """
 
287
        # TODO: Do we need or want an option (maybe a config setting) to turn
 
288
        # this off or override it for particular locations? -- mbp 20080512
 
289
        if self._mode_check_done:
 
290
            return
 
291
        self._mode_check_done = True
 
292
        try:
 
293
            st = self.transport.stat('.')
 
294
        except TransportNotPossible:
 
295
            self._dir_mode = None
 
296
            self._file_mode = None
 
297
        else:
 
298
            # Check the directory mode, but also make sure the created
 
299
            # directories and files are read-write for this user. This is
 
300
            # mostly a workaround for filesystems which lie about being able to
 
301
            # write to a directory (cygwin & win32)
 
302
            if (st.st_mode & 07777 == 00000):
 
303
                # FTP allows stat but does not return dir/file modes
 
304
                self._dir_mode = None
 
305
                self._file_mode = None
 
306
            else:
 
307
                self._dir_mode = (st.st_mode & 07777) | 00700
 
308
                # Remove the sticky and execute bits for files
 
309
                self._file_mode = self._dir_mode & ~07111
 
310
 
 
311
    def _get_file_mode(self):
 
312
        """Return Unix mode for newly created files, or None.
 
313
        """
 
314
        if not self._mode_check_done:
 
315
            self._find_creation_modes()
 
316
        return self._file_mode
 
317
 
 
318
    def _get_dir_mode(self):
 
319
        """Return Unix mode for newly created directories, or None.
 
320
        """
 
321
        if not self._mode_check_done:
 
322
            self._find_creation_modes()
 
323
        return self._dir_mode
 
324
 
 
325