@@ -15,34 +15,34 @@ This article is about the portions of the code that deal with libgit2, so we'll
15
15
Let's skip the frontmatter, and jump straight to the meat of this thing.
16
16
The ` main ` function starts off with some boilerplate and a bit of command-line parsing noise, which we'll ignore for the purposes of this article.
17
17
18
- ``` c
18
+ ~~~ c
19
19
int main (int argc, char * argv[ ] )
20
20
{
21
21
git_repository * repo = NULL;
22
22
struct opts o = { 1, 0, 0, 0, GIT_REPOSITORY_INIT_SHARED_UMASK, 0, 0, 0 };
23
23
24
24
git_threads_init();
25
25
parse_opts(&o, argc, argv);
26
- ```
26
+ ~~~
27
27
28
28
Next we have a bit of a shortcut; if we were called with no options, we can use the simplest API for doing this, since its defaults match those of the command line.
29
29
That `check_lg2` utility checks the value passed in the first parameter, and if it's not zero, prints the other two parameters and exits the program.
30
30
Not the greatest error handling, but it'll do for these examples.
31
31
32
- ``` c
32
+ ~~~ c
33
33
if (o.no_options) {
34
34
check_lg2(git_repository_init(&repo, o.dir, 0),
35
35
"Could not initialize repository", NULL);
36
36
}
37
- ```
37
+ ~~~
38
38
39
39
If the situation is more complex, you can use the extended API to handle it.
40
40
The fields in [ the options structure] [ initopts ] are designed to provide much of what ` git init ` does.
41
41
Note that it's important to use the ` _INIT ` structure initializers; these structures have version numbers so future libgit2's can maintain backwards compatibility.
42
42
43
43
[ initopts ] : http://libgit2.github.com/libgit2/#HEAD/type/git_repository_init_options
44
44
45
- ``` c
45
+ ~~~ c
46
46
else {
47
47
git_repository_init_options initopts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
48
48
initopts.flags = GIT_REPOSITORY_INIT_MKPATH;
@@ -54,26 +54,26 @@ Note that it's important to use the `_INIT` structure initializers; these struct
54
54
initopts.flags |= GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE;
55
55
initopts.template_path = o.template;
56
56
}
57
- ```
57
+ ~~~
58
58
59
59
Libgit2's repository is always oriented at the `.git` directory, so specifying an external git directory turns things a bit upside-down:
60
60
61
- ``` c
61
+ ~~~ c
62
62
if (o.gitdir) {
63
63
initopts.workdir_path = o.dir;
64
64
o.dir = o.gitdir;
65
65
}
66
66
67
67
if (o.shared != 0)
68
68
initopts.mode = o.shared;
69
- ```
69
+ ~~~
70
70
71
71
Now the call that does all the work: [ ` git_repository_init_ext ` ] [ grie ] .
72
72
The output (if the call succeeds) lands in ` repo ` , which is a ` git_repository* ` , which we can then go on and use.
73
73
74
74
[ grie ] : http://libgit2.github.com/libgit2/#HEAD/group/repository/git_repository_init_ext
75
75
76
- ``` c
76
+ ~~~ c
77
77
check_lg2 (git_repository_init_ext(&repo, o.dir, &initopts),
78
78
"Could not initialize repository", NULL);
79
79
}
@@ -86,64 +86,64 @@ The output (if the call succeeds) lands in `repo`, which is a `git_repository*`,
86
86
87
87
printf("Initialized empty Git repository in %s\n", o.dir);
88
88
}
89
- ```
89
+ ~~~
90
90
91
91
If we get this far, the initialization is done.
92
92
This example goes one step farther than git, by providing an option to create an empty initial commit.
93
93
The body of this function is [below](#toc_2).
94
94
95
- ``` c
95
+ ~~~ c
96
96
if (o.initial_commit) {
97
97
create_initial_commit(repo);
98
98
printf("Created empty initial commit\n");
99
99
}
100
-
101
- ```
100
+
101
+ ~~~
102
102
103
103
Now to clean up our mess; C isn't your mother.
104
104
Unless the docs specifically say otherwise, any non-` const ` pointer that's filled in by libgit2 needs to be freed by the caller.
105
105
106
- ``` c
106
+ ~~~ c
107
107
git_repository_free (repo);
108
108
git_threads_shutdown();
109
109
110
110
return 0;
111
111
}
112
- ```
112
+ ~~~
113
113
114
114
## Creating the Initial Commit
115
115
116
116
First, we declare all of our variables, which might give you a clue as to what's coming.
117
117
118
- ``` c
118
+ ~~~ c
119
119
static void create_initial_commit(git_repository *repo)
120
120
{
121
121
git_signature *sig;
122
122
git_index *index;
123
123
git_oid tree_id, commit_id;
124
124
git_tree *tree;
125
- ```
125
+ ~~~
126
126
127
127
Next, we generate a commit signature using the values in the user's config, and timestamp of right now.
128
128
129
- ``` c
129
+ ~~~ c
130
130
if (git_signature_default(&sig, repo) < 0 )
131
131
fatal ("Unable to create a commit signature.",
132
132
"Perhaps 'user.name' and 'user.email' are not set");
133
- ```
133
+ ~~~
134
134
135
135
Now we store the index's tree into the ODB to use for the commit.
136
136
Since the repo was *just* initialized, the index has an empty tree.
137
137
138
- ``` c
138
+ ~~~ c
139
139
if (git_repository_index(&index, repo) < 0)
140
140
fatal("Could not open repository index", NULL);
141
141
142
142
if (git_index_write_tree(&tree_id, index) < 0)
143
143
fatal("Unable to write initial tree from index", NULL);
144
144
145
145
git_index_free(index);
146
- ```
146
+ ~~~
147
147
148
148
It's worth noting that this doesn't actually write the index to disk.
149
149
There's a separate call for that: [ ` git_index_write ` ] [ write ] .
@@ -153,34 +153,34 @@ All this code does is use the empty index to get the SHA-1 hash of the empty tre
153
153
154
154
Okay, now we have the empty tree's SHA-1 hash, but we need an actual ` git_tree ` object to create a commit.
155
155
156
- ``` c
156
+ ~~~ c
157
157
if (git_tree_lookup(&tree, repo, &tree_id) < 0 )
158
158
fatal ("Could not look up initial tree", NULL);
159
- ```
159
+ ~~~
160
160
161
161
**Now** we're ready to write the initial commit.
162
162
Normally you'd look up `HEAD` to use as the parent, but this commit will have no parents.
163
163
164
- ``` c
164
+ ~~~ c
165
165
if (git_commit_create_v(
166
166
&commit_id, repo, "HEAD", sig, sig,
167
167
NULL, "Initial commit", tree, 0) < 0)
168
168
fatal("Could not create the initial commit", NULL);
169
- ```
169
+ ~~~
170
170
171
171
And (of course) clean up our mess.
172
172
173
- ``` c
173
+ ~~~ c
174
174
git_tree_free (tree);
175
175
git_signature_free(sig);
176
176
}
177
- ```
177
+ ~~~
178
178
179
179
## Fin
180
180
181
181
If you compile and run this program, you'll get output something like this:
182
182
183
- ``` bash
183
+ ~~~ bash
184
184
$ ./init --initial-commit ./foo
185
185
Initialized empty Git repository in /tmp/foo/
186
186
Created empty initial commit
191
191
Date: Sat Oct 5 20:59:50 2013 -0700
192
192
193
193
Initial commit
194
- ```
194
+ ~~~
195
195
196
196
## What's next?
197
197
Go [ back to the Learning center] ( /docs ) for more, or check out [ the API documentation] ( http://libgit2.github.com/libgit2/ ) .
0 commit comments