forked from libgit2/www.libgit2.org
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapi.html
751 lines (577 loc) · 22 KB
/
api.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>libgit2 API</title>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<link href="stylesheets/application.css" media="all" rel="stylesheet" type="text/css"/>
<link href="stylesheets/sunburst.css" media="all" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="js/sh_main.min.js"></script>
<script type="text/javascript" src="js/sh_lang/sh_c.min.js"></script>
<script type="text/javascript" src="js/sh_lang/sh_ruby.min.js"></script>
<link type="text/css" href="stylesheets/sh_libgit.css" rel="stylesheet" >
</head>
<body onload="sh_highlightDocument();">
<div id="body"><div id="contents">
<div id="header">
<h1><a href="/">LibGit2</a> API Usage Guide</h1>
</div>
<h2 id="content">Contents</h2>
<div class="contents"><div class="bullet">
<div class="description">
<ul>
<li><a href="api.html#sha">SHA conversions and formatting</a></li>
<li><a href="api.html#rawread">object reading (loose and packed)</a></li>
<li><a href="api.html#rawwrite">object writing (loose)</a></li>
<li><a href="api.html#parsing">commit, tag, tree and blob parsing and write-back</a></li>
<li><a href="api.html#trees">tree traversal</a></li>
<li><a href="api.html#revwalk">revision walking</a></li>
<li><a href="api.html#index">index file (staging area) manipulation</a></li>
<li><a href="api.html#backends">custom ODB backends</a></li>
</ul>
</div>
</div></div>
<h2 id="started">Getting started</h2>
<div class="contents"><div class="bullet">
<div class="description">
<p>This is the usage guide for the libgit2 API. The machine generated
documentation for the C API can be found <a href="http://libgit2.github.com/libgit2">here</a>;
this page is to show some examples and usage of libgit2 and the Ruby
bindings, <a href="https://github.com/libgit2/rugged">Rugged</a>.
</p>
<p>You can also see heavily documented, compilable example C files
using libgit2 <a href="http://libgit2.github.com/libgit2/ex/HEAD/libgit.html">here</a></p>
<p>To get started, you need to initialize the <code>Repository</code>
object. This is the starting point for most of what you will do with
the libgit2 API.
</p>
<p>You will have to include <code>git2.h</code> to access the main
libgit2 functionality.</p>
<span class="shtitle">C</span>
<pre class="sh_c">
#include <git2.h>
git_repository *repo;
git_repository_open(&repo, "/path/to/repo.git");
/* do stuff with the repository */
git_repository_free(repo);
</pre>
<br/>
<span class="shtitle">Ruby</span>
<pre class="sh_ruby">
require 'rugged'
@repo = Rugged::Repository.new(@path)
</pre>
</div>
</div></div>
<h2 id="sha">SHA1 Conversion and Formatting</h2>
<div class="contents"><div class="bullet">
<div class="description">
<p>The Git object database is basically a key-value store wher
the key for each object is the SHA1 checksum of the contents of
the object it is storing. This means that working with these SHA1
values is pretty important. The SHA1 algorithm returns a 20-byte
raw value for any content given to it, but in order to be readable
by people or to even accurately represent it in ASCII, you have to
convert the value to 40 hex characters. libgit2 provides helper
functions to easily do this conversion.</p>
<h3>Hex to Raw</h3>
<span class="shtitle">C</span>
<pre class="sh_c">
char hex[] = "599955586da1c3ad514f3e65f1081d2012ec862d";
git_oid oid;
git_oid_mkstr(&oid, hex);
printf("Raw 20 bytes: [%s]\n", (&oid)->id);
</pre>
<br/>
<span class="shtitle">Ruby</span>
<pre class="sh_ruby">
raw = Rugged::hex_to_raw("ce08fe4884650f067bd5703b6a59a8b3b3c99a09")
puts "Raw 20 bytes: #{raw}"
</pre>
<h3>Raw to Hex</h3>
<span class="shtitle">C</span>
<pre class="sh_c">
git_oid oid;
char out[40];
git_oid_mkraw(&oid, raw);
git_oid_fmt(out, &oid);
printf("SHA hex string: %s\n", out);
</pre>
<br/>
<span class="shtitle">Ruby</span>
<pre class="sh_ruby">
hex = Rugged::raw_to_hex(Base64.decode64("FqASNFZ4mrze9Ld1ITwjqL109eA="))
puts "SHA hex string: #{hex}"
</pre>
</div>
</div></div>
<h2 id="rawread">Raw Data Reading and Writing</h2>
<div class="contents"><div class="bullet">
<div class="description">
<p>This is the lowest layer of Git access, raw read and write
access to the object database. With libgit2 you can read the raw
data of any object out of the database by providing the SHA1 hash
of that object.</p>
<p>The object database is split in several layers, called backends.
By default, it is instantiated with two backends, just like the original
git.git: object requests will first be looked up in the loose object storage,
and if not found, a lookup will be attempted on the packfile storage. On top
of that, libgit2 also supports <a href="api.html#backends">custom backends</a>.</p>
<h3>Reading Data</h3>
<span class="shtitle">C</span>
<pre class="sh_c">
git_odb *odb;
git_odb_object *obj;
git_otype otype;
unsigned char *data;
const char *str_type;
int error;
odb = git_repository_database(repo);
error = git_odb_read(&obj, odb, &oid);
data = (char*)git_odb_object_data(obj);
otype = git_odb_object_type(obj);
str_type = git_object_type2string(otype);
printf("object length and type: %d, %s\n", (int)git_odb_object_size(obj), str_type);
git_odb_object_close(obj); // close the object when you are done with it
</pre>
<br/>
<span class="shtitle">Ruby</span>
<pre class="sh_ruby">
sha = "599955586da1c3ad514f3e65f1081d2012ec862d"
if @repo.exists(sha)
raw_objct = @repo.read(sha)
pp raw_object.data
pp raw_object.type
pp raw_object.len
end
</pre>
<p id="rawwrite">We also provide access to write arbitrary content back into
the object database. For writing blob contents, this is fine,
but remember that other types such as commits and trees have very
specific formats. It would be easy to introduce corrupt objects
this way.</p>
<h3>Writing Data</h3>
<span class="shtitle">C</span>
<pre class="sh_c">
git_oid oid2;
git_odb_write(&oid2, odb, "test data", 9, GIT_OBJ_BLOB);
git_oid_fmt(out, &oid2);
printf("Written Object: %s\n", out);
</pre>
<br/>
<span class="shtitle">Ruby</span>
<pre class="sh_ruby">
content = "any ol content will do"
sha = @repo.hash(content, "blob") # just gives you the SHA hash
sha = @repo.write(content, "blob") # actually writes to the odb
</pre>
</div>
</div></div>
<h2 id="parsing">Object Parsing and Writing</h2>
<div class="contents"><div class="bullet">
<div class="description">
<p>
The different Git object types other than blobs have very specific
formats they need to be in. libgit2 is capable of properly parsing
commits, tags, and trees for you. It can also construct the proper
format given the raw data to for easy write-back capability.
</p>
<p>You can get objects from the database either via the
<code>git_[object]_lookup(&obj, repo, &id)</code> method or the more
general <code>git_repository_lookup(&obj, repo, &oid, OBJ_TYPE)</code>
call. I will use them interchangably through these examples.</p>
<p>Note that any object references returned by these two methods are owned by
the Repository object, and shall not be <code>free</code>'d manually. The repository
has an internal object cache, and will take care of freeing all the loaded
objects after the repository itself is <code>free</code>'d. However, if you
are sure that an object won't be needed again, you can manually free it
using the <code>git_object_free(obj)</code> method.</p>
<a class="apilink" href="http://libgit2.github.com/libgit2/#HEAD/group/commit">Commit API</a>
<h3 id="commits">Commits</h3>
<span class="shtitle">C</span>
<pre class="sh_c">
git_commit *commit;
git_oid oid3;
git_oid_mkstr(&oid3, "f0877d0b841d75172ec404fc9370173dfffc20d1");
error = git_commit_lookup(&commit, repo, &oid3);
const git_signature *author, *cmtter;
const char *message, *message_short;
time_t ctime;
unsigned int parents, p;
message = git_commit_message(commit);
message_short = git_commit_message_short(commit);
author = git_commit_author(commit);
cmtter = git_commit_committer(commit);
ctime = git_commit_time(commit);
printf("Author: %s (%s)\n", author->name, author->email);
parents = git_commit_parentcount(commit);
for (p = 0;p < parents;p++) {
git_commit *parent;
git_commit_parent(&parent, commit, p);
git_oid_fmt(out, git_commit_id(parent));
printf("Parent: %s\n", out);
git_commit_close(parent);
}
git_commit_close(commit);
/* and writing a commit object */
git_oid tree_id, parent_id, commit_id;
/* create signatures */
author = git_signature_new("Scott Chacon", "schacon@gmail.com", 123456789, 60);
cmtter = git_signature_new("Scott A Chacon", "scott@github.com", 987654321, 90);
git_oid_mkstr(&tree_id, "28873d96b4e8f4e33ea30f4c682fd325f7ba56ac");
git_oid_mkstr(&parent_id, "f0877d0b841d75172ec404fc9370173dfffc20d1");
git_commit_create_v(
&commit_id, /* out id */
repo,
NULL, /* do not update the HEAD */
author,
cmtter,
"example commit",
&tree_id,
1, &parent_id);
git_oid_fmt(out, &commit_id);
printf("New Commit: %s\n", out);
</pre>
<br/>
<span class="shtitle">Ruby</span>
<pre class="sh_ruby">
sha = "599955586da1c3ad514f3e65f1081d2012ec862d"
obj = @repo.lookup(sha)
obj.sha
obj.type
obj.message
obj.message_short
obj.time
c = obj.committer
c.name # "Scott Chacon"
c.time.to_i # 1273360386
c.email # "schacon@gmail.com"
obj.tree.sha # "181037049a54a1eb5fab404658a3a250b44335d7"
obj.parents.each do |parent|
pp parent
end
tree = @repo.lookup("07b3b552c4e879a21eb81d048fa729df65a49051")
obj.tree = tree
c.name = "Orange Peel Chacon"
c.email = "op@gmail.com"
obj.author = c
obj.committer = c
obj.message = "the new commit message"
obj.write # write back to the database
</pre>
<a class="apilink" href="http://libgit2.github.com/libgit2/#HEAD/group/tag">Tag API</a>
<h3 id="tags">Tags</h3>
<span class="shtitle">C</span>
<pre class="sh_c">
git_tag *tag;
const char *tmessage;
git_oid_mkstr(&oid, "bc422d45275aca289c51d79830b45cecebff7c3a");
error = git_tag_lookup(&tag, repo, &oid);
git_tag_target((git_object **)&commit, tag);
git_tag_name(tag); // "test"
git_tag_type(tag); // GIT_OBJ_TAG
tmessage = git_tag_message(tag); // "tag message\n"
printf("Tag Message: %s\n", tmessage);
</pre>
<br/>
<span class="shtitle">Ruby</span>
<pre class="sh_ruby">
sha = "0c37a5391bbff43c37f0d0371823a5509eed5b1d"
obj = @repo.lookup(sha)
obj.sha
obj.type # "tag"
obj.message # "test tag message\n"
obj.name # "v1.0"
obj.target.sha # "5b5b025afb0b4c913b4c338a42934a3863bf3644"
obj.target_type # "commit"
c = obj.tagger
c.name # "Scott Chacon"
c.time.to_i # 1288114383
c.email # "schacon@gmail.com"
</pre>
<a class="apilink" href="http://libgit2.github.com/libgit2/#HEAD/group/tree">Tree API</a>
<h3 id="trees">Trees</h3>
<span class="shtitle">C</span>
<pre class="sh_c">
git_tree *tree;
git_tree_entry *entry;
git_object *objt;
git_oid_mkstr(&oid, "2a741c18ac5ff082a7caaec6e74db3075a1906b5");
git_tree_lookup(&tree, repo, &oid);
int cnt = git_tree_entrycount(tree); // 3
printf("tree entries: %d\n", cnt);
entry = git_tree_entry_byname(tree, "hello.c");
git_tree_entry_name(entry); // "README"
entry = git_tree_entry_byindex(tree, 0);
printf("Entry name: %s\n", git_tree_entry_name(entry)); // "README"
git_tree_entry_2object(&objt, repo, entry); // blob
</pre>
<br/>
<span class="shtitle">Ruby</span>
<pre class="sh_ruby">
tree = @repo.lookup("1385f264afb75a56a5bec74243be9b367ba4ca08")
tree.sha
tree.type # "tree"
tree.entry_count # 3
tree.each do |entry|
puts entry.name
puts entry.to_object.sha
puts entry.attributes
end
enumdir = tree.sort { |a, b| a.sha <=> b.sha }.map { |e| e.name }.join(':')
puts enumdir # "README:subdir:new.txt"
</pre>
<a class="apilink" href="http://libgit2.github.com/libgit2/#HEAD/group/blob">Blob API</a>
<h3 id="blobs">Blobs</h3>
<p>Since blobs are basically unstructured, there isn't a lot the blob routines
provide over the raw access calls, but there are some interesting methods to help
read in contents from disk.</p>
<span class="shtitle">C</span>
<pre class="sh_c">
git_blob *blob;
git_oid_mkstr(&oid, "af7574ea73f7b166f869ef1a39be126d9a186ae0");
git_blob_lookup(&blob, repo, &oid);
printf("Blob Size: %d\n", git_blob_rawsize(blob)); // 8
git_blob_rawcontent(blob); // "content"
</pre>
<br/>
<span class="shtitle">Ruby</span>
<pre class="sh_ruby">
sha = "fa49b077972391ad58037050f2a75f74e3671e92"
blob = @repo.lookup(sha)
blob.size # 9
blob.content # "new file\n"
blob.type # "blob"
blob.content = "new blob content"
blob.write
</pre>
</div>
</div></div>
<h2 id="revwalk">Revision Walking</h2>
<div class="contents"><div class="bullet">
<div class="description">
<p>libgit2 also has a revision walking API that gives you access to the
mechanics of the 'log' command. Instead of just running 'git log', you
start a graph walker, tell it where to start and just begin asking it
for the next commit in the list.</p>
<p>You can technically write your own walker by starting with any commit
and continuously putting it's parents in a queue and then taking the
next commit off that queue, but the built in walker is faster and has a
few different walking strategies built in.</p>
<span class="shtitle">C</span>
<pre class="sh_c">
git_revwalk *walk;
git_commit *wcommit;
git_oid_mkstr(&oid, "f0877d0b841d75172ec404fc9370173dfffc20d1");
git_revwalk_new(&walk, repo);
git_revwalk_sorting(walk, GIT_SORT_TOPOLOGICAL | GIT_SORT_REVERSE);
git_revwalk_push(walk, &oid);
const git_signature *cauth;
const char *cmsg;
while ((git_revwalk_next(&oid, walk)) == GIT_SUCCESS) {
error = git_commit_lookup(&wcommit, repo, &oid);
cmsg = git_commit_message_short(wcommit);
cauth = git_commit_author(wcommit);
printf("%s (%s)\n", cmsg, cauth->email);
}
git_revwalk_free(walk);
</pre>
<br/>
<span class="shtitle">Ruby</span>
<pre class="sh_ruby">
walker = Rugged::Walker.new(@repo)
# find commits reachable from this
walker.push("d6c2306fcbf0d346b9129b303c3babae58f619f7")
# but not from this
walker.hide("42b551c353a29d29f6f0dc4137a40706b128a8d3")
walker.each do |commit|
msg = commit.message
email = commit.author.email
puts "#{msg} (#{email})"
end
</pre>
</div>
</div></div>
<h2 id="index">Index Manipulation</h2>
<div class="contents"><div class="bullet">
<div class="description">
<p>libgit2 also has a set of index (cachefile) manipulation methods.
These cover being able to read and write the Git index file - stage and
unstage files, that sort of thing.</p>
<a class="apilink" href="http://libgit2.github.com/libgit2/#HEAD/group/index">Index API</a>
<h3 id="indexread">Reading Index Files</h3>
<span class="shtitle">C</span>
<pre class="sh_c">
git_index *index;
unsigned int i, e;
git_index_entry **entries;
git_index_open_inrepo(&index, repo);
if (index->on_disk) {
git_index_read(index);
ecount = git_index_entrycount(index)
entries = (git_index_entry **)index->entries.contents;
for (i = 0; i < ecount; ++i) {
git_index_entry *e = entries[i];
printf("path: %s\n", e->path);
printf("mtime: %d\n", e->mtime.seconds);
printf("fs: %d\n", e->file_size);
}
git_index_free(index);
}
</pre>
<br/>
<span class="shtitle">Ruby</span>
<pre class="sh_ruby">
index = Rugged::Index.new(path)
index.refresh
puts index.entry_count # 2
e = index.get_entry(0)
puts e.path # 'README'
puts e.sha # '1385f264afb75a56a5bec74243be9b367ba4ca08'
puts e.mtime.to_i # 1273360380
puts e.ctime.to_i # 1273360380
puts e.file_size # 4
# also e.dev, e.ino, e.mode, e.uid, e.gid, e.flags, e.valid?, e.stage
index.each do |entry|
puts entry.name # file name of each entry
end
</pre>
</div>
</div></div>
<h2 id="backends">Custom backends</h2>
<div class="contents"><div class="bullet">
<div class="description">
<p>libgit2 decouples the Object Database logic from the actual storage of
the objects. This means that you can actually extend the library with
custom backends that steer away from the default "loose object and packfiles"
storage model that Git uses.</p>
<p>Before extending the library with a custom backend in C, the special header
<code>git2/odb_backend.h</code> must be included<p>
<h3 id="indexread">Implementing a custom backend</h3>
<span class="shtitle">C</span>
<pre class="sh_c">
typedef struct {
git_odb_backend parent;
/* custom data for your backend */
const char *sqlite_db;
} sqlite_backend;
int sqlb_read(git_rawobj *out, git_odb_backend *back, const git_oid *oid)
{
sqlite_backend *b = (sqlite_backend *)back;
/* read the object identified by 'oid' and write its contents
to 'out'. Return 'GIT_SUCCESS' if the read was succesful,
or an error code otherwise. */
return GIT_SUCCESS;
}
int sqlb_read_header(git_rawobj *out, git_odb_backend *back, const git_oid *oid)
{
sqlite_backend *b = (sqlite_backend *)backend;
/* read the header of the object identified by 'oid' and fill
the 'out->type' and 'out->len' fields without actually
loading the whole object in memory. Return 'GIT_SUCCESS' if
the read was succesful, or an error code otherwise. */
return GIT_SUCCESS;
}
int sqlb_exists(git_odb_backend *back, const git_oid *oid)
{
sqlite_backend *b = (sqlite_backend *)back;
/* check whether the object identified by 'oid' exists in the backend.
Return 1 or 0. */
return 1;
}
int sqlb_write(git_oid *out, git_odb_backend *back, git_rawobj *obj)
{
sqlite_backend *b = (sqlite_backend *)back;
/* write the object in 'obj' to the storage, and fill the 'out' oid
with the SHA1 identifier of the written object. Return 'GIT_SUCCESS'
if the write was successful, error code otherwise */
return GIT_SUCCESS;
}
void sqlb_free(git_odb_backend *backend)
{
sqlite_backend *b = (sqlite_backend *)back;
/* completely free the backend instance */
free(b->sqlite_db);
free(b);
}
sqlite_backend *create_backend(const char *path_do_db)
{
sqlite_backend *backend;
/* create a new instance of the backend */
backend = calloc(1, sizeof(sqlite_backend));
/* fill the instance with pointers to the backend methods */
backend->parent.read = &sqlb_read;
backend->parent.read_header = &sqlb_read_header;
backend->parent.write = &sqlb_write;
backend->parent.exists = &sqlb_exists;
backend->parent.free = &sqlb_free;
/* set the priority of the backend */
backend->parent.priority = 3;
/* fill the custom data fields, if needed */
backend->sqlite_db = strdup(path_to_db);
return backend;
}
</pre>
<p>Once you have created a new backend instance, you can add
it to an existing object database using the <code>git_odb_add_backend(backend)</code> method.
A single backend instance can only be active in one ODB at the same time</p>
<p>The <code>priority</code> field is used to when sorting the backends for their usage:
for instance, a <code>read</code> call on the ODB will first check the backend with the
highest priority and attempt to read the object from it; if the backend returns an error
code, it will fallback silently to the following backend, until the object has been read
or there are no more backends left.</p>
<p>It it not necessary to specify all the backend methods on a custom backend: unspecified
methods will be skipped silently on their respective backend calls. If no <code>free</code>
method is specified for a given backend, the library will automatically try to free the backend using
a plain <code>free()</code> call.</p>
<span class="shtitle">Ruby</span>
<pre class="sh_ruby">
class TestBackend < Rugged::Backend
def read(oid)
# return a raw object with the read contents
Rugged::RawObject.new(type, contents)
end
def read_header(oid)
# return a raw object with the read header (type and length)
Rugged::RawObject.new(type, nil, len)
end
def exists(oid)
# return whether the object exists in the backend
true
end
def write(raw_object)
# write the object and return a SHA1 id
sha1
end
end
# add the backend to our repository
backend = TestBackend.new(5) # high priority
@repo.add_backend(backend)
</pre>
<h3 id="indexread">A world of possibilities</h3>
<p>The options when implementing custom backends are endless. Here are just a few examples:</p>
<ul>
<li>in-memory object storage (useful for config storage)</li>
<li>in-memory cache for fast lookups (make sure you write the objects back to disk before flushing the cache!)</li>
<li>a transparent backend acting as a logger for all the ODB reads and writes</li>
<li>SQLite backend writing and reading objects from a compact database</li>
<li>Cassandra backend (or your favourite NoSQL flavour!)</li>
<li>Network backend (store the objects remotely, directly)</li>
<li>...Oh my god, so many cool ideas!</li>
</ul>
</div>
</div></div>
<h2 id="index">Overview</h2>
<div class="contents"><div class="bullet">
<div class="description">
<p>That is the basic usage of the libgit2 library. For more detailed
information, please see the API documentation for the C library or the
Rugged Ruby library.
</p>
</div>
</div></div>
<a href="http://github.com/libgit2/libgit2" id="github">
<img alt="Fork me on GitHub" src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" />
</a>
</body>
</html>