diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..856179481 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,47 @@ +# Welcome to libgit2! + +We're making it easy to do interesting things with git, and we'd love to have +your help. + +## Discussion & Chat + +We hang out in the #libgit2 channel on irc.freenode.net. + +## Reporting Bugs + +First, know which version of libgit2 your problem is in. Compile and test +against the `development` branch to avoid re-reporting an issue that's already +been fixed. + +It's *incredibly* helpful to be able to reproduce the problem. Please include +a bit of code and/or a zipped repository (if possible). Note that some of the +developers are employees of GitHub, so if your repository is private, find us +on IRC and we'll figure out a way to help you. + +## Pull Requests + +Life will be a lot easier for you if you create a named branch for your +contribution, rather than just using your fork's `development`. + +It's helpful if you include a nice description of your change with your PR; if +someone has to read the whole diff to figure out why you're contributing in the +first place, you're less likely to get feedback and have your change merged in. + +## Porting Code From Other Open-Source Projects + +The most common case here is porting code from core Git. Git is a GPL project, +which means that in order to port code to this project, we need the explicit +permission of the author. Check the +[`git.git-authors`](https://github.com/libgit2/libgit2/blob/development/git.git-authors) +file for authors who have already consented; feel free to add someone if you've +obtained their consent. + +Other licenses have other requirements; check the license of the library you're +porting code *from* to see what you need to do. + +## Styleguide + +We like to keep the source code consistent and easy to read. Maintaining this +takes some discipline, but it's been more than worth it. Take a look at the +[conventions file](https://github.com/libgit2/libgit2/blob/development/CONVENTIONS.md). + diff --git a/CONVENTIONS b/CONVENTIONS deleted file mode 100644 index f082d8e6c..000000000 --- a/CONVENTIONS +++ /dev/null @@ -1,107 +0,0 @@ -libgit2 conventions -=================== - -Namespace Prefixes ------------------- - -All types and functions start with 'git_'. - -All #define macros start with 'GIT_'. - - -Type Definitions ----------------- - -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. - - -Public Exported Function Definitions ------------------------------------- - -All exported functions must be declared as: - ----- - GIT_EXTERN(result_type) git_modulename_functionname(arg_list); ----- - - -Semi-Private Exported Functions -------------------------------- - -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. - - -Calling Conventions -------------------- - -Functions should prefer to return a 'int' to indicate success or -failure and supply any output through the first argument (or first -few arguments if multiple outputs are supplied). - -int status codes are 0 for GIT_OK and < 0 for an error. -This permits common POSIX result testing: - ----- - if (git_odb_open(&odb, path)) - abort("odb open failed"); ----- - -Functions returning a pointer may return NULL instead of an int -if there is only one type of failure (GIT_ENOMEM). - -Functions returning a pointer may also return NULL if the common -case needed by the application is strictly success/failure and a -(possibly slower) function exists that the caller can use to get -more detailed information. Parsing common data structures from -on-disk formats is a good example of this pattern; in general a -"corrupt" entity can be treated as though it does not exist but -a more sophisticated "fsck" support function can report how the -entity is malformed. - - -Documentation Fomatting ------------------------ - -All comments should conform to Doxygen "javadoc" style conventions -for formatting the public API documentation. - - -Public Header Format --------------------- - -All public headers defining types, functions or macros must use -the following form, where ${filename} is the name of the file, -after replacing non-identifier characters with '_'. - ----- - #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 ----- diff --git a/CONVENTIONS.md b/CONVENTIONS.md new file mode 100644 index 000000000..ea5e40ee6 --- /dev/null +++ b/CONVENTIONS.md @@ -0,0 +1,163 @@ +# 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); +``` + +Public headers are indented with spaces, three to a tab. Internal code is +indented 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 +``` + +