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

  • Committer: Jelmer Vernooij
  • Date: 2010-06-28 22:30:34 UTC
  • mto: (0.200.953 trunk)
  • mto: This revision was merged to the branch mainline in revision 6960.
  • Revision ID: jelmer@samba.org-20100628223034-vylrgdyakmqoupl6
use transport repo objects even for local access.

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
    PACKDIR,
31
31
    )
32
32
from dulwich.pack import (
33
 
    MemoryPackIndex,
34
33
    PackData,
35
34
    Pack,
36
 
    ThinPackData,
37
35
    iter_sha1,
38
36
    load_pack_index_file,
39
 
    write_pack_data,
40
37
    write_pack_index_v2,
41
38
    )
42
39
from dulwich.repo import (
70
67
    def __repr__(self):
71
68
        return "%s(%r)" % (self.__class__.__name__, self.transport)
72
69
 
73
 
    def _ensure_dir_exists(self, path):
74
 
        for n in range(path.count("/")):
75
 
            dirname = "/".join(path.split("/")[:n+1])
76
 
            try:
77
 
                self.transport.mkdir(dirname)
78
 
            except FileExists:
79
 
                pass
80
 
 
81
70
    def subkeys(self, base):
82
71
        keys = set()
 
72
        path = self.refpath(base)
83
73
        try:
84
74
            iter_files = self.transport.clone(base).iter_files_recursive()
85
 
            keys.update(("%s/%s" % (base, refname)).strip("/") for 
86
 
                    refname in iter_files if check_ref_format("%s/%s" % (base, refname)))
87
 
        except (TransportNotPossible, NoSuchFile):
 
75
        except TransportNotPossible:
88
76
            pass
 
77
        else:
 
78
            for refname in iter_files:
 
79
                # check_ref_format requires at least one /, so we prepend the
 
80
                # base before calling it.
 
81
                if check_ref_format("%s/%s" % (base, refname)):
 
82
                    keys.add(("%s/%s" % refname).strip("/"))
89
83
        for key in self.get_packed_refs():
90
84
            if key.startswith(base):
91
85
                keys.add(key[len(base):].strip("/"))
95
89
        keys = set()
96
90
        if self.transport.has("HEAD"):
97
91
            keys.add("HEAD")
 
92
        path = ""
98
93
        try:
99
 
            iter_files = list(self.transport.clone("refs").iter_files_recursive())
100
 
            for filename in iter_files:
101
 
                refname = "refs/%s" % filename
 
94
            iter_files = self.transport.clone("refs").iter_files_recursive()
 
95
        except TransportNotPossible:
 
96
            pass
 
97
        else:
 
98
            for refname in iter_files:
102
99
                if check_ref_format(refname):
103
100
                    keys.add(refname)
104
 
        except (TransportNotPossible, NoSuchFile):
105
 
            pass
106
101
        keys.update(self.get_packed_refs())
107
102
        return keys
108
103
 
198
193
        del self._packed_refs[name]
199
194
        if name in self._peeled_refs:
200
195
            del self._peeled_refs[name]
201
 
        f = self.transport.open_write_stream("packed-refs")
202
 
        try:
203
 
            write_packed_refs(f, self._packed_refs, self._peeled_refs)
204
 
        finally:
205
 
            f.close()
 
196
        f = StringIO()
 
197
        write_packed_refs(f, self._packed_refs, self._peeled_refs)
 
198
        f.seek(0)
 
199
        self.transport.put_file("packed-refs", f)
206
200
 
207
201
    def set_symbolic_ref(self, name, other):
208
202
        """Make a ref point at another ref.
212
206
        """
213
207
        self._check_refname(name)
214
208
        self._check_refname(other)
215
 
        self._ensure_dir_exists(name)
216
209
        self.transport.put_bytes(name, SYMREF + other + '\n')
217
210
 
218
211
    def set_if_equals(self, name, old_ref, new_ref):
231
224
            realname, _ = self._follow(name)
232
225
        except KeyError:
233
226
            realname = name
234
 
        self._ensure_dir_exists(realname)
235
 
        self.transport.put_bytes(realname, new_ref+"\n")
 
227
        self.transport.put_bytes_non_atomic(realname, new_ref+"\n",
 
228
                create_parent_dir=True)
236
229
        return True
237
230
 
238
231
    def add_if_new(self, name, ref):
252
245
        except KeyError:
253
246
            realname = name
254
247
        self._check_refname(realname)
255
 
        self._ensure_dir_exists(realname)
256
 
        self.transport.put_bytes(realname, ref+"\n")
 
248
        self.transport.put_bytes_non_atomic(realname, ref+"\n",
 
249
                create_parent_dir=True)
257
250
        return True
258
251
 
259
252
    def remove_if_equals(self, name, old_ref):
270
263
        self._check_refname(name)
271
264
        # may only be packed
272
265
        try:
273
 
            self.transport.delete(name)
 
266
            self.transport.remove(name)
274
267
        except NoSuchFile:
275
268
            pass
276
269
        self._remove_packed_ref(name)
285
278
            if self.transport.has(".git/%s" % OBJECTDIR):
286
279
                self.bare = False
287
280
                self._controltransport = self.transport.clone('.git')
288
 
            elif self.transport.has_any(["info/refs", OBJECTDIR, REFSDIR]):
 
281
            elif self.transport.has(OBJECTDIR) or self.transport.has(REFSDIR):
289
282
                self.bare = True
290
283
                self._controltransport = self.transport
291
284
            else:
324
317
        return Index(self.index_path())
325
318
 
326
319
    def has_index(self):
327
 
        """Check if an index is present."""
328
 
        # Bare repos must never have index files; non-bare repos may have a
329
 
        # missing index file, which is treated as empty.
330
 
        return not self.bare
 
320
        return self._controltransport.has(INDEX_FILENAME)
331
321
 
332
322
    def __repr__(self):
333
 
        return "<%s for %r>" % (self.__class__.__name__, self.transport)
 
323
        return "<TransportRepo for %r>" % self.transport
334
324
 
335
325
 
336
326
class TransportObjectStore(PackBasedObjectStore):
344
334
        super(TransportObjectStore, self).__init__()
345
335
        self.transport = transport
346
336
        self.pack_transport = self.transport.clone(PACKDIR)
347
 
 
348
 
    def __repr__(self):
349
 
        return "%s(%r)" % (self.__class__.__name__, self.transport)
350
 
 
 
337
    
351
338
    def _pack_cache_stale(self):
352
339
        return False # FIXME
353
340
 
375
362
                try:
376
363
                    size = self.pack_transport.stat(name).st_size
377
364
                except TransportNotPossible:
378
 
                    # FIXME: This reads the whole pack file at once
379
 
                    f = self.pack_transport.get(name)
380
 
                    contents = f.read()
381
 
                    pd = PackData(name, StringIO(contents), size=len(contents))
 
365
                    def pd():
 
366
                        # FIXME: This reads the whole pack file at once
 
367
                        f = self.pack_transport.get(name)
 
368
                        contents = f.read()
 
369
                        return PackData(name, StringIO(contents), size=len(contents))
382
370
                else:
383
 
                    pd = PackData(name, self.pack_transport.get(name),
 
371
                    pd = lambda: PackData(name, self.pack_transport.get(name),
384
372
                            size=size)
385
373
                idxname = name.replace(".pack", ".idx")
386
 
                idx = load_pack_index_file(idxname, self.pack_transport.get(idxname))
387
 
                pack = Pack.from_objects(pd, idx)
 
374
                idx = lambda: load_pack_index_file(idxname, self.pack_transport.get(idxname))
 
375
                pack = Pack.from_lazy_objects(pd, idx)
388
376
                ret.append(pack)
389
377
        return ret
390
378
 
400
388
 
401
389
    def _remove_loose_object(self, sha):
402
390
        path = '%s/%s' % self._split_loose_object(sha)
403
 
        self.transport.delete(path)
 
391
        self.transport.remove(path)
404
392
 
405
393
    def _get_loose_object(self, sha):
406
394
        path = '%s/%s' % self._split_loose_object(sha)
438
426
        basename = "pack-%s" % iter_sha1(entry[0] for entry in entries)
439
427
        f.seek(0)
440
428
        self.pack_transport.put_file(basename + ".pack", f)
441
 
        idxfile = self.pack_transport.open_write_stream(basename + ".idx")
442
 
        try:
443
 
            write_pack_index_v2(idxfile, entries, p.get_stored_checksum())
444
 
        finally:
445
 
            idxfile.close()
446
 
        idxfile = self.pack_transport.get(basename + ".idx")
 
429
        idxfile = StringIO()
 
430
        write_pack_index_v2(idxfile, entries, p.get_stored_checksum())
 
431
        idxfile.seek(0)
 
432
        self.pack_transport.put_file(basename + ".idx", idxfile)
 
433
        idxfile.seek(0)
447
434
        idx = load_pack_index_file(basename+".idx", idxfile)
448
435
        final_pack = Pack.from_objects(p, idx)
449
436
        self._add_known_pack(final_pack)
450
437
        return final_pack
451
438
 
452
 
    def add_thin_pack(self):
453
 
        """Add a new thin pack to this object store.
454
 
 
455
 
        Thin packs are packs that contain deltas with parents that exist
456
 
        in a different pack.
457
 
        """
458
 
        from cStringIO import StringIO
459
 
        f = StringIO()
460
 
        def commit():
461
 
            if len(f.getvalue()) > 0:
462
 
                return self.move_in_thin_pack(f)
463
 
            else:
464
 
                return None
465
 
        return f, commit
466
 
 
467
 
    def move_in_thin_pack(self, f):
468
 
        """Move a specific file containing a pack into the pack directory.
469
 
 
470
 
        :note: The file should be on the same file system as the
471
 
            packs directory.
472
 
 
473
 
        :param path: Path to the pack file.
474
 
        """
475
 
        f.seek(0)
476
 
        data = ThinPackData.from_file(self.get_raw, f, len(f.getvalue()))
477
 
        idx = MemoryPackIndex(data.sorted_entries(), data.get_stored_checksum())
478
 
        p = Pack.from_objects(data, idx)
479
 
 
480
 
        pack_sha = idx.objects_sha1()
481
 
 
482
 
        datafile = self.pack_transport.open_write_stream("pack-%s.pack" % pack_sha)
483
 
        try:
484
 
            entries, data_sum = write_pack_data(datafile, ((o, None) for o in p.iterobjects()), len(p))
485
 
        finally:
486
 
            datafile.close()
487
 
        entries.sort()
488
 
        idxfile = self.pack_transport.open_write_stream("pack-%s.idx" % pack_sha)
489
 
        try:
490
 
            write_pack_index_v2(idxfile, data.sorted_entries(), data_sum)
491
 
        finally:
492
 
            idxfile.close()
493
 
        final_pack = Pack("pack-%s" % pack_sha)
494
 
        self._add_known_pack(final_pack)
495
 
        return final_pack
496
 
 
497
 
 
498
 
 
499
439
    def add_pack(self):
500
440
        """Add a new pack to this object store. 
501
441