Skip to content

Commit 698c74e

Browse files
committed
GitOdb
1 parent da4c29d commit 698c74e

15 files changed

Lines changed: 982 additions & 180 deletions

File tree

TODO

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@
22
- audit all ** methods so that all finds go through the repo in js land so that the .repo pointer is set.
33
- rename files remove .h
44
- Cleanup diff api
5+
- free everything malloc'd
6+
- codegen documentation
7+
- extract out more partials

binding.gyp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
'src/threads.cc',
2828
'src/wrapper.cc',
2929
'src/refdb.cc',
30+
'src/odb_object.cc',
31+
'src/odb.cc',
3032
'src/submodule.cc'
3133
],
3234

example/general.js

Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
var git = require('nodegit');
2+
3+
git.Repo.open('/opt/libgit2-test/.git', function(error, repo) {
4+
if (error) throw error;
5+
6+
// ### SHA-1 Value Conversions
7+
8+
// The `git_oid` is the structure that keeps the SHA value. We will use
9+
// this throughout the example for storing the value of the current SHA
10+
// key we're working with.
11+
var oid = git.Oid.fromString('fd6e612585290339ea8bf39c692a7ff6a29cb7c3');
12+
13+
// If you have a oid, you can easily get the hex value of the SHA as well.
14+
console.log(oid.sha());
15+
16+
// ### Working with the Object Database
17+
18+
// **libgit2** provides [direct access][odb] to the object database. The
19+
// object database is where the actual objects are stored in Git. For
20+
// working with raw objects, we'll need to get this structure from the
21+
// repository.
22+
var odb = repo.odb();
23+
24+
// We can read raw objects directly from the object database if we have
25+
// the oid (SHA) of the object. This allows us to access objects without
26+
// knowing thier type and inspect the raw bytes unparsed.
27+
28+
odb.read(oid, function(error, object) {
29+
if (error) throw error;
30+
31+
// A raw object only has three properties - the type (commit, blob, tree
32+
// or tag), the size of the raw data and the raw, unparsed data itself.
33+
// For a commit or tag, that raw data is human readable plain ASCII
34+
// text. For a blob it is just file contents, so it could be text or
35+
// binary data. For a tree it is a special binary format, so it's unlikely
36+
// to be hugely helpful as a raw object.
37+
var data = object.data(),
38+
type = object.type();
39+
40+
console.log(object.size(), object.type());
41+
});
42+
43+
// You can also write raw object data to Git. This is pretty cool because
44+
// it gives you direct access to the key/value properties of Git. Here
45+
// we'll write a new blob object that just contains a simple string.
46+
// Notice that we have to specify the object type as the `git_otype` enum.
47+
odb.write("test data", git.Object.Type.Blob, function(error, oid) {
48+
if (error) throw error;
49+
50+
// Now that we've written the object, we can check out what SHA1 was
51+
// generated when the object was written to our database.
52+
console.log(oid.sha());
53+
});
54+
55+
// ### Object Parsing
56+
57+
// libgit2 has methods to parse every object type in Git so you don't have
58+
// to work directly with the raw data. This is much faster and simpler
59+
// than trying to deal with the raw data yourself.
60+
61+
// #### Commit Parsing
62+
63+
// [Parsing commit objects][pco] is simple and gives you access to all the
64+
// data in the commit - the author (name, email, datetime), committer
65+
// (same), tree, message, encoding and parent(s).
66+
67+
oid = git.Oid.fromString("f0877d0b841d75172ec404fc9370173dfffc20d1");
68+
repo.getCommit(oid, function(error, commit) {
69+
if (error) throw error;
70+
71+
// Each of the properties of the commit object are accessible via methods,
72+
// including commonly needed variations, such as `git_commit_time` which
73+
// returns the author time and `git_commit_message` which gives you the
74+
// commit message (as a NUL-terminated string).
75+
console.log(commit.message(), commit.author(), commit.committer(), commit.time());
76+
77+
// Commits can have zero or more parents. The first (root) commit will
78+
// have no parents, most commits will have one (i.e. the commit it was
79+
// based on) and merge commits will have two or more. Commits can
80+
// technically have any number, though it's rare to have more than two.
81+
commit.getParents(function(error, parents) {
82+
parents.forEach(function(parent) {
83+
console.log(parent.oid());
84+
});
85+
});
86+
});
87+
88+
// #### Writing Commits
89+
90+
// libgit2 provides a couple of methods to create commit objects easily as
91+
// well. There are four different create signatures, we'll just show one
92+
// of them here. You can read about the other ones in the [commit API
93+
// docs][cd].
94+
//
95+
// [cd]: http://libgit2.github.com/libgit2/#HEAD/group/commit
96+
97+
var author = new git.Signature("Scott Chacon", "schacon@gmail.com", 123456789, 60);
98+
var committer = new git.Signature("Scott A Chacon", "scott@github.com", 987654321, 90);
99+
100+
// Commit objects need a tree to point to and optionally one or more
101+
// parents. Here we're creating oid objects to create the commit with,
102+
// but you can also use existing ones:
103+
var treeId = git.Oid.fromString("28873d96b4e8f4e33ea30f4c682fd325f7ba56ac");
104+
var parentId = git.Oid.fromString("f0877d0b841d75172ec404fc9370173dfffc20d1");
105+
106+
repo.getTree(treeId, function(error, tree) {
107+
repo.getCommit(parentId, function(error, parent) {
108+
109+
// Here we actually create the commit object with a single call with all
110+
// the values we need to create the commit. The SHA key is written to the
111+
// `commit_id` variable here.
112+
repo.createCommit(
113+
null /* do not update the HEAD */,
114+
author,
115+
committer,
116+
null /* use default message encoding */,
117+
"example commit",
118+
tree,
119+
1, parent,
120+
function (error, commitOid) {
121+
console.log(commitOid.sha());
122+
});
123+
});
124+
});
125+
126+
// #### Tag Parsing
127+
128+
// You can parse and create tags with the [tag management API][tm], which
129+
// functions very similarly to the commit lookup, parsing and creation
130+
// methods, since the objects themselves are very similar.
131+
132+
var oid = git.Oid.fromString("bc422d45275aca289c51d79830b45cecebff7c3a");
133+
repo.getTag(oid, function(error, tag) {
134+
if (error) throw error;
135+
136+
// Now that we have the tag object, we can extract the information it
137+
// generally contains: the target (usually a commit object), the type of
138+
// the target object (usually 'commit'), the name ('v1.0'), the tagger (a
139+
// git_signature - name, email, timestamp), and the tag message.
140+
console.log(tag.name(), tag.type(), tag.message());
141+
142+
tag.getTarget(function (error, commit) {
143+
if (error) throw error;
144+
console.log(commit);
145+
});
146+
});
147+
148+
// #### Tree Parsing
149+
150+
// [Tree parsing][tp] is a bit different than the other objects, in that
151+
// we have a subtype which is the tree entry. This is not an actual
152+
// object type in Git, but a useful structure for parsing and traversing
153+
// tree entries.
154+
155+
var oid = git.Oid.fromString("2a741c18ac5ff082a7caaec6e74db3075a1906b5");
156+
repo.getTree(oid, function(error, tree) {
157+
if (error) throw error;
158+
159+
console.log(tree.size());
160+
tree.entries().forEach(function(entry) {
161+
console.log(entry.name());
162+
163+
if (entry.isDirectory()) {
164+
entry.getTree(function(error, tree) {
165+
if (error) throw error;
166+
167+
console.log("Recursively got tree");
168+
});
169+
} else {
170+
entry.getBlob(function(error, blob) {
171+
console.log(blob.toString());
172+
});
173+
}
174+
});
175+
176+
// You can also access tree entries by path if you know the path of the
177+
// entry you're looking for.
178+
tree.getFile("/src/hello.c", function(error, entry) {
179+
entry.getBlob(function(error, blob) {
180+
console.log(blob.toString());
181+
});
182+
});
183+
});
184+
185+
// #### Blob Parsing
186+
187+
// The last object type is the simplest and requires the least parsing
188+
// help. Blobs are just file contents and can contain anything, there is
189+
// no structure to it. The main advantage to using the [simple blob
190+
// api][ba] is that when you're creating blobs you don't have to calculate
191+
// the size of the content. There is also a helper for reading a file
192+
// from disk and writing it to the db and getting the oid back so you
193+
// don't have to do all those steps yourself.
194+
195+
var oid = git.Oid.fromString("af7574ea73f7b166f869ef1a39be126d9a186ae0");
196+
repo.getBlob(oid, function(error, blob) {
197+
if (error) throw error;
198+
199+
// You can access a buffer with the raw contents of the blob directly.
200+
// Note that this buffer may not be contain ASCII data for certain blobs
201+
// (e.g. binary files).
202+
203+
var buffer = blob.content();
204+
205+
// If you know that the blob is UTF-8, however,
206+
207+
console.log(blob.toString());
208+
});
209+
210+
// ### Revwalking
211+
212+
// The libgit2 [revision walking api][rw] provides methods to traverse the
213+
// directed graph created by the parent pointers of the commit objects.
214+
// Since all commits point back to the commit that came directly before
215+
// them, you can walk this parentage as a graph and find all the commits
216+
// that were ancestors of (reachable from) a given starting point. This
217+
// can allow you to create `git log` type functionality.
218+
219+
var oid = git.Oid.fromString("f0877d0b841d75172ec404fc9370173dfffc20d1");
220+
221+
// To use the revwalker, create a new walker, tell it how you want to sort
222+
// the output and then push one or more starting points onto the walker.
223+
// If you want to emulate the output of `git log` you would push the SHA
224+
// of the commit that HEAD points to into the walker and then start
225+
// traversing them. You can also 'hide' commits that you want to stop at
226+
// or not see any of their ancestors. So if you want to emulate `git log
227+
// branch1..branch2`, you would push the oid of `branch2` and hide the oid
228+
// of `branch1`.
229+
var revWalk = repo.createRevWalk();
230+
revWalk.sorting(git.RevWalk.Topological | git.RevWalkReverse);
231+
revWalk.push(oid);
232+
233+
// Now that we have the starting point pushed onto the walker, we start
234+
// asking for ancestors. It will return them in the sorting order we asked
235+
// for as commit oids. We can then lookup and parse the commited pointed
236+
// at by the returned OID; note that this operation is specially fast
237+
// since the raw contents of the commit object will be cached in memory
238+
239+
function walk() {
240+
revWalk.next(function(error, oid) {
241+
if (error) throw error;
242+
if (!oid) return;
243+
244+
repo.getCommit(oid, function(error, commit) {
245+
if (error) throw error;
246+
247+
console.log(commit.sha());
248+
walk();
249+
});
250+
});
251+
}
252+
walk();
253+
254+
// ### Index File Manipulation
255+
256+
// The [index file API][gi] allows you to read, traverse, update and write
257+
// the Git index file (sometimes thought of as the staging area).
258+
repo.getIndex(function(error, index) {
259+
if (error) throw error;
260+
261+
// For each entry in the index, you can get a bunch of information
262+
// including the SHA (oid), path and mode which map to the tree objects
263+
// that are written out. It also has filesystem properties to help
264+
// determine what to inspect for changes (ctime, mtime, dev, ino, uid,
265+
// gid, file_size and flags) All these properties are exported publicly in
266+
// the `git_index_entry` struct
267+
268+
index.entries().forEach(function(entry) {
269+
console.log(entry.path(), entry.mtime(), entry.size());
270+
});
271+
});
272+
273+
// ### References
274+
275+
// The [reference API][ref] allows you to list, resolve, create and update
276+
// references such as branches, tags and remote references (everything in
277+
// the .git/refs directory).
278+
279+
repo.getReferences(function(error, references) {
280+
if (error) throw error;
281+
282+
references.forEach(function(reference) {
283+
if (reference.type() == git.Reference.Oid) {
284+
console.log(oid.sha());
285+
} else if (reference.type() == git.Reference.Symbolic) {
286+
console.log(reference.symbolicTarget());
287+
}
288+
});
289+
});
290+
});
291+
292+

include/commit.h

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,6 @@ class GitCommit : public ObjectWrap {
4040
static Handle<Value> Author(const Arguments& args);
4141
static Handle<Value> TreeId(const Arguments& args);
4242
static Handle<Value> ParentCount(const Arguments& args);
43-
static Handle<Value> Parent(const Arguments& args);
44-
static void ParentWork(uv_work_t* req);
45-
static void ParentAfterWork(uv_work_t* req);
46-
47-
struct ParentBaton {
48-
uv_work_t request;
49-
int error_code;
50-
const git_error* error;
51-
git_commit * out;
52-
Persistent<Value> commitReference;
53-
git_commit * commit;
54-
Persistent<Value> nReference;
55-
unsigned int n;
56-
Persistent<Function> callback;
57-
};
5843
static Handle<Value> ParentId(const Arguments& args);
5944
static Handle<Value> NthGenAncestor(const Arguments& args);
6045
git_commit *raw;

include/odb.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* This code is auto-generated; unless you know what you're doing, do not modify!
3+
**/
4+
5+
#ifndef GITODB_H
6+
#define GITODB_H
7+
8+
#include <v8.h>
9+
#include <node.h>
10+
#include <string>
11+
12+
#include "git2.h"
13+
14+
using namespace node;
15+
using namespace v8;
16+
17+
class GitOdb : public ObjectWrap {
18+
public:
19+
20+
static Persistent<Function> constructor_template;
21+
static void Initialize (Handle<v8::Object> target);
22+
23+
git_odb *GetValue();
24+
25+
static Handle<Value> New(void *raw);
26+
27+
private:
28+
GitOdb(git_odb *raw);
29+
~GitOdb();
30+
31+
static Handle<Value> New(const Arguments& args);
32+
33+
34+
static Handle<Value> Create(const Arguments& args);
35+
static Handle<Value> Open(const Arguments& args);
36+
static Handle<Value> AddDiskAlternate(const Arguments& args);
37+
static Handle<Value> Read(const Arguments& args);
38+
static Handle<Value> ReadPrefix(const Arguments& args);
39+
static Handle<Value> ReadHeader(const Arguments& args);
40+
static Handle<Value> Exists(const Arguments& args);
41+
static Handle<Value> Refresh(const Arguments& args);
42+
static Handle<Value> Write(const Arguments& args);
43+
static Handle<Value> Hash(const Arguments& args);
44+
static Handle<Value> Hashfile(const Arguments& args);
45+
git_odb *raw;
46+
};
47+
48+
#endif

0 commit comments

Comments
 (0)