]> git.proxmox.com Git - libgit2.git/blob - CONVENTIONS.md
Merge pull request #1728 from ivoire/small_fixes
[libgit2.git] / CONVENTIONS.md
1 # Libgit2 Conventions
2
3 We like to keep the source consistent and readable. Herein are some
4 guidelines that should help with that.
5
6 ## Compatibility
7
8 `libgit2` runs on many different platforms with many different compilers.
9 It is written in [ANSI C](http://en.wikipedia.org/wiki/ANSI_C) (a.k.a. C89)
10 with some specific standards for function and type naming, code formatting,
11 and testing.
12
13 We try to avoid more recent extensions to maximize portability. We also, to
14 the greatest extent possible, try to avoid lots of `#ifdef`s inside the core
15 code base. This is somewhat unavoidable, but since it can really hamper
16 maintainability, we keep it to a minimum.
17
18 ## Match Surrounding Code
19
20 If there is one rule to take away from this document, it is *new code should
21 match the surrounding code in a way that makes it impossible to distinguish
22 the new from the old.* Consistency is more important to us than anyone's
23 personal opinion about where braces should be placed or spaces vs. tabs.
24
25 If a section of code is being completely rewritten, it is okay to bring it
26 in line with the standards that are laid out here, but we will not accept
27 submissions that contain a large number of changes that are merely
28 reformatting.
29
30 ## Naming Things
31
32 All external types and functions start with `git_` and all `#define` macros
33 start with `GIT_`. The `libgit2` API is mostly broken into related
34 functional modules each with a corresponding header. All functions in a
35 module should be named like `git_modulename_functioname()`
36 (e.g. `git_repository_open()`).
37
38 Functions with a single output parameter should name that parameter `out`.
39 Multiple outputs should be named `foo_out`, `bar_out`, etc.
40
41 Parameters of type `git_oid` should be named `id`, or `foo_id`. Calls that
42 return an OID should be named `git_foo_id`.
43
44 Where a callback function is used, the function should also include a
45 user-supplied extra input that is a `void *` named "payload" that will be
46 passed through to the callback at each invocation.
47
48 ## Typedefs
49
50 Wherever possible, use `typedef`. In some cases, if a structure is just a
51 collection of function pointers, the pointer types don't need to be
52 separately typedef'd, but loose function pointer types should be.
53
54 ## Exports
55
56 All exported functions must be declared as:
57
58 ```c
59 GIT_EXTERN(result_type) git_modulename_functionname(arg_list);
60 ```
61
62 ## Internals
63
64 Functions whose *modulename* is followed by two underscores,
65 for example `git_odb__read_packed`, are semi-private functions.
66 They are primarily intended for use within the library itself,
67 and may disappear or change their signature in a future release.
68
69 ## Parameters
70
71 Out parameters come first.
72
73 Whenever possible, pass argument pointers as `const`. Some structures (such
74 as `git_repository` and `git_index`) have mutable internal structure that
75 prevents this.
76
77 Callbacks should always take a `void *` payload as their last parameter.
78 Callback pointers are grouped with their payloads, and typically come last
79 when passed as arguments:
80
81 ```c
82 int git_foo(git_repository *repo, git_foo_cb callback, void *payload);
83 ```
84
85 ## Memory Ownership
86
87 Some APIs allocate memory which the caller is responsible for freeing; others
88 return a pointer into a buffer that's owned by some other object. Make this
89 explicit in the documentation.
90
91 ## Return codes
92
93 Most public APIs should return an `int` error code. As is typical with most
94 C library functions, a zero value indicates success and a negative value
95 indicates failure.
96
97 Some bindings will transform these returned error codes into exception
98 types, so returning a semantically appropriate error code is important.
99 Check
100 [`include/git2/errors.h`](https://github.com/libgit2/libgit2/blob/development/include/git2/errors.h)
101 for the return codes already defined.
102
103 In your implementation, use `giterr_set()` to provide extended error
104 information to callers.
105
106 If a `libgit2` function internally invokes another function that reports an
107 error, but the error is not propagated up, use `giterr_clear()` to prevent
108 callers from getting the wrong error message later on.
109
110
111 ## Structs
112
113 Most public types should be opaque, e.g.:
114
115 ```C
116 typedef struct git_odb git_odb;
117 ```
118
119 ...with allocation functions returning an "instance" created within
120 the library, and not within the application. This allows the type
121 to grow (or shrink) in size without rebuilding client code.
122
123 To preserve ABI compatibility, include an `int version` field in all opaque
124 structures, and initialize to the latest version in the construction call.
125 Increment the "latest" version whenever the structure changes, and try to only
126 append to the end of the structure.
127
128 ## Option Structures
129
130 If a function's parameter count is too high, it may be desirable to package
131 up the options in a structure. Make them transparent, include a version
132 field, and provide an initializer constant or constructor. Using these
133 structures should be this easy:
134
135 ```C
136 git_foo_options opts = GIT_FOO_OPTIONS_INIT;
137 opts.baz = BAZ_OPTION_ONE;
138 git_foo(&opts);
139 ```
140
141 ## Enumerations
142
143 Typedef all enumerated types. If each option stands alone, use the enum
144 type for passing them as parameters; if they are flags to be OR'ed together,
145 pass them as `unsigned int` or `uint32_t` or some appropriate type.
146
147 ## Code Layout
148
149 Try to keep lines less than 80 characters long. This is a loose
150 requirement, but going significantly over 80 columns is not nice.
151
152 Use common sense to wrap most code lines; public function declarations
153 can use a couple of different styles:
154
155 ```c
156 /** All on one line is okay if it fits */
157 GIT_EXTERN(int) git_foo_simple(git_oid *id);
158
159 /** Otherwise one argument per line is a good next step */
160 GIT_EXTERN(int) git_foo_id(
161 git_oid **out,
162 int a,
163 int b);
164 ```
165
166 Indent with tabs; set your editor's tab width to 4 for best effect.
167
168 Avoid trailing whitespace and only commit Unix-style newlines (i.e. no CRLF
169 in the repository - just set `core.autocrlf` to true if you are writing code
170 on a Windows machine).
171
172 ## Documentation
173
174 All comments should conform to Doxygen "javadoc" style conventions for
175 formatting the public API documentation. Try to document every parameter,
176 and keep the comments up to date if you change the parameter list.
177
178 ## Public Header Template
179
180 Use this template when creating a new public header.
181
182 ```C
183 #ifndef INCLUDE_git_${filename}_h__
184 #define INCLUDE_git_${filename}_h__
185
186 #include "git/common.h"
187
188 /**
189 * @file git/${filename}.h
190 * @brief Git some description
191 * @defgroup git_${filename} some description routines
192 * @ingroup Git
193 * @{
194 */
195 GIT_BEGIN_DECL
196
197 /* ... definitions ... */
198
199 /** @} */
200 GIT_END_DECL
201 #endif
202 ```
203
204 ## Inlined functions
205
206 All inlined functions must be declared as:
207
208 ```C
209 GIT_INLINE(result_type) git_modulename_functionname(arg_list);
210 ```
211
212 ## Tests
213
214 `libgit2` uses the [clar](https://github.com/vmg/clar) testing framework.
215
216 All PRs should have corresponding tests.
217
218 * If the PR fixes an existing issue, the test should fail prior to applying
219 the PR and succeed after applying it.
220 * If the PR is for new functionality, then the tests should exercise that
221 new functionality to a certain extent. We don't require 100% coverage
222 right now (although we are getting stricter over time).
223
224 When adding new tests, we prefer if you attempt to reuse existing test data
225 (in `tests-clar/resources/`) if possible. If you are going to add new test
226 repositories, please try to strip them of unnecessary files (e.g. sample
227 hooks, etc).