We like to keep the source consistent and readable. Herein are some guidelines that should help with that.
All types and functions start with git_
, and all #define macros start with GIT_
.
Functions with a single output parameter should name that parameter out
.
Multiple outputs should be named foo_out
, bar_out
, etc.
Parameters of type git_oid
should be named id
, or foo_id
. Calls that
return an OID should be named git_foo_id
.
Where there is a callback passed in, the void *
that is passed into it should
be named “payload”.
Wherever possible, use typedef
. If a structure is just a collection of
function pointers, the pointer types don’t need to be separately typedef’d, but
loose function pointer types should be.
All exported functions must be declared as:
GIT_EXTERN(result_type) git_modulename_functionname(arg_list);
Functions whose modulename is followed by two underscores,
for example git_odb__read_packed
, are semi-private functions.
They are primarily intended for use within the library itself,
and may disappear or change their signature in a future release.
Out parameters come first.
Whenever possible, pass argument pointers as const
. Some structures (such
as git_repository
and git_index
) have internal structure that prevents
this.
Callbacks should always take a void *
payload as their last parameter.
Callback pointers are grouped with their payloads, and come last when passed as
arguments:
int foo(git_repository *repo, git_foo_cb callback, void *payload);
Some APIs allocate memory which the caller is responsible for freeing; others return a pointer into a buffer that’s owned by some other object. Make this explicit in the documentation.
Return an int
when a public API can fail in multiple ways. These may be
transformed into exception types in some bindings, so returning a semantically
appropriate error code is important. Check
errors.h
for the return codes already defined.
Use giterr_set
to provide extended error information to callers.
If an error is not to be propagated, use giterr_clear
to prevent callers from
getting the wrong error message later on.
Most types should be opaque, e.g.:
typedef struct git_odb git_odb;
…with allocation functions returning an “instance” created within the library, and not within the application. This allows the type to grow (or shrink) in size without rebuilding client code.
To preserve ABI compatibility, include an int version
field in all opaque
structures, and initialize to the latest version in the construction call.
Increment the “latest” version whenever the structure changes, and try to only
append to the end of the structure.
If a function’s parameter count is too high, it may be desirable to package up the options in a structure. Make them transparent, include a version field, and provide an initializer constant or constructor. Using these structures should be this easy:
git_foo_options opts = GIT_FOO_OPTIONS_INIT;
opts.baz = BAZ_OPTION_ONE;
git_foo(&opts);
Typedef all enumerated types. If each option stands alone, use the enum type
for passing them as parameters; if they are flags, pass them as unsigned int
.
Try to keep lines less than 80 characters long. Use common sense to wrap most code lines; public function declarations should use this convention:
GIT_EXTERN(int) git_foo_id(
git_oid **out,
int a,
int b);
Indentation is done with tabs; set your editor’s tab width to 3 for best effect.
All comments should conform to Doxygen “javadoc” style conventions for formatting the public API documentation. Try to document every parameter, and keep the comments up to date if you change the parameter list.
Use this template when creating a new public header.
#ifndef INCLUDE_git_${filename}_h__
#define INCLUDE_git_${filename}_h__
#include "git/common.h"
/**
* @file git/${filename}.h
* @brief Git some description
* @defgroup git_${filename} some description routines
* @ingroup Git
* @{
*/
GIT_BEGIN_DECL
/* ... definitions ... */
/** @} */
GIT_END_DECL
#endif
All inlined functions must be declared as:
GIT_INLINE(result_type) git_modulename_functionname(arg_list);
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
# Libgit2 Conventions
We like to keep the source consistent and readable. Herein are some guidelines
that should help with that.
## Naming Things
All types and functions start with `git_`, and all #define macros start with `GIT_`.
Functions with a single output parameter should name that parameter `out`.
Multiple outputs should be named `foo_out`, `bar_out`, etc.
Parameters of type `git_oid` should be named `id`, or `foo_id`. Calls that
return an OID should be named `git_foo_id`.
Where there is a callback passed in, the `void *` that is passed into it should
be named "payload".
## Typedef
Wherever possible, use `typedef`. If a structure is just a collection of
function pointers, the pointer types don't need to be separately typedef'd, but
loose function pointer types should be.
## Exports
All exported functions must be declared as:
```C
GIT_EXTERN(result_type) git_modulename_functionname(arg_list);
```
## Internals
Functions whose modulename is followed by two underscores,
for example `git_odb__read_packed`, are semi-private functions.
They are primarily intended for use within the library itself,
and may disappear or change their signature in a future release.
## Parameters
Out parameters come first.
Whenever possible, pass argument pointers as `const`. Some structures (such
as `git_repository` and `git_index`) have internal structure that prevents
this.
Callbacks should always take a `void *` payload as their last parameter.
Callback pointers are grouped with their payloads, and come last when passed as
arguments:
```C
int foo(git_repository *repo, git_foo_cb callback, void *payload);
```
## Memory Ownership
Some APIs allocate memory which the caller is responsible for freeing; others
return a pointer into a buffer that's owned by some other object. Make this
explicit in the documentation.
## Return codes
Return an `int` when a public API can fail in multiple ways. These may be
transformed into exception types in some bindings, so returning a semantically
appropriate error code is important. Check
[`errors.h`](https://github.com/libgit2/libgit2/blob/development/include/git2/errors.h)
for the return codes already defined.
Use `giterr_set` to provide extended error information to callers.
If an error is not to be propagated, use `giterr_clear` to prevent callers from
getting the wrong error message later on.
## Opaque Structs
Most types should be opaque, e.g.:
```C
typedef struct git_odb git_odb;
```
...with allocation functions returning an "instance" created within
the library, and not within the application. This allows the type
to grow (or shrink) in size without rebuilding client code.
To preserve ABI compatibility, include an `int version` field in all opaque
structures, and initialize to the latest version in the construction call.
Increment the "latest" version whenever the structure changes, and try to only
append to the end of the structure.
## Option Structures
If a function's parameter count is too high, it may be desirable to package up
the options in a structure. Make them transparent, include a version field,
and provide an initializer constant or constructor. Using these structures
should be this easy:
```C
git_foo_options opts = GIT_FOO_OPTIONS_INIT;
opts.baz = BAZ_OPTION_ONE;
git_foo(&opts);
```
## Enumerations
Typedef all enumerated types. If each option stands alone, use the enum type
for passing them as parameters; if they are flags, pass them as `unsigned int`.
## Code Layout
Try to keep lines less than 80 characters long. Use common sense to wrap most
code lines; public function declarations should use this convention:
```C
GIT_EXTERN(int) git_foo_id(
git_oid **out,
int a,
int b);
```
Indentation is done with tabs; set your editor's tab width to 3 for best effect.
## Documentation
All comments should conform to Doxygen "javadoc" style conventions for
formatting the public API documentation. Try to document every parameter, and
keep the comments up to date if you change the parameter list.
## Public Header Template
Use this template when creating a new public header.
```C
#ifndef INCLUDE_git_${filename}_h__
#define INCLUDE_git_${filename}_h__
#include "git/common.h"
/**
* @file git/${filename}.h
* @brief Git some description
* @defgroup git_${filename} some description routines
* @ingroup Git
* @{
*/
GIT_BEGIN_DECL
/* ... definitions ... */
/** @} */
GIT_END_DECL
#endif
```
## Inlined functions
All inlined functions must be declared as:
```C
GIT_INLINE(result_type) git_modulename_functionname(arg_list);
```