Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'CONVENTIONS.md')
-rw-r--r--CONVENTIONS.md227
1 files changed, 227 insertions, 0 deletions
diff --git a/CONVENTIONS.md b/CONVENTIONS.md
new file mode 100644
index 000000000..59b41a2e6
--- /dev/null
+++ b/CONVENTIONS.md
@@ -0,0 +1,227 @@
+# Libgit2 Conventions
+
+We like to keep the source consistent and readable. Herein are some
+guidelines that should help with that.
+
+## Compatibility
+
+`libgit2` runs on many different platforms with many different compilers.
+It is written in [ANSI C](http://en.wikipedia.org/wiki/ANSI_C) (a.k.a. C89)
+with some specific standards for function and type naming, code formatting,
+and testing.
+
+We try to avoid more recent extensions to maximize portability. We also, to
+the greatest extent possible, try to avoid lots of `#ifdef`s inside the core
+code base. This is somewhat unavoidable, but since it can really hamper
+maintainability, we keep it to a minimum.
+
+## Match Surrounding Code
+
+If there is one rule to take away from this document, it is *new code should
+match the surrounding code in a way that makes it impossible to distinguish
+the new from the old.* Consistency is more important to us than anyone's
+personal opinion about where braces should be placed or spaces vs. tabs.
+
+If a section of code is being completely rewritten, it is okay to bring it
+in line with the standards that are laid out here, but we will not accept
+submissions that contain a large number of changes that are merely
+reformatting.
+
+## Naming Things
+
+All external types and functions start with `git_` and all `#define` macros
+start with `GIT_`. The `libgit2` API is mostly broken into related
+functional modules each with a corresponding header. All functions in a
+module should be named like `git_modulename_functioname()`
+(e.g. `git_repository_open()`).
+
+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 a callback function is used, the function should also include a
+user-supplied extra input that is a `void *` named "payload" that will be
+passed through to the callback at each invocation.
+
+## Typedefs
+
+Wherever possible, use `typedef`. In some cases, 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 mutable internal structure that
+prevents this.
+
+Callbacks should always take a `void *` payload as their last parameter.
+Callback pointers are grouped with their payloads, and typically come last
+when passed as arguments:
+
+```c
+int git_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
+
+Most public APIs should return an `int` error code. As is typical with most
+C library functions, a zero value indicates success and a negative value
+indicates failure.
+
+Some bindings will transform these returned error codes into exception
+types, so returning a semantically appropriate error code is important.
+Check
+[`include/git2/errors.h`](https://github.com/libgit2/libgit2/blob/development/include/git2/errors.h)
+for the return codes already defined.
+
+In your implementation, use `giterr_set()` to provide extended error
+information to callers.
+
+If a `libgit2` function internally invokes another function that reports an
+error, but the error is not propagated up, use `giterr_clear()` to prevent
+callers from getting the wrong error message later on.
+
+
+## Structs
+
+Most public 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 to be OR'ed together,
+pass them as `unsigned int` or `uint32_t` or some appropriate type.
+
+## Code Layout
+
+Try to keep lines less than 80 characters long. This is a loose
+requirement, but going significantly over 80 columns is not nice.
+
+Use common sense to wrap most code lines; public function declarations
+can use a couple of different styles:
+
+```c
+/** All on one line is okay if it fits */
+GIT_EXTERN(int) git_foo_simple(git_oid *id);
+
+/** Otherwise one argument per line is a good next step */
+GIT_EXTERN(int) git_foo_id(
+ git_oid **out,
+ int a,
+ int b);
+```
+
+Indent with tabs; set your editor's tab width to 4 for best effect.
+
+Avoid trailing whitespace and only commit Unix-style newlines (i.e. no CRLF
+in the repository - just set `core.autocrlf` to true if you are writing code
+on a Windows machine).
+
+## 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);
+```
+
+## Tests
+
+`libgit2` uses the [clar](https://github.com/vmg/clar) testing framework.
+
+All PRs should have corresponding tests.
+
+* If the PR fixes an existing issue, the test should fail prior to applying
+ the PR and succeed after applying it.
+* If the PR is for new functionality, then the tests should exercise that
+ new functionality to a certain extent. We don't require 100% coverage
+ right now (although we are getting stricter over time).
+
+When adding new tests, we prefer if you attempt to reuse existing test data
+(in `tests-clar/resources/`) if possible. If you are going to add new test
+repositories, please try to strip them of unnecessary files (e.g. sample
+hooks, etc).