How to contribute
=================

Introduction
------------

The purpose of this document is to help contributors get started with
the Tezos OCaml codebase.

First steps
-----------

First, make sure that you are proficient enough in OCaml. The community
Website http://www.ocaml.org below gives a few pointer for that. In
particular, we use a lot of functors, and a few GADTs in the codebase,
so you may want to make sure that you master these advanced concepts.

Then, if you don’t know well about the Lwt library, that’s what you want
to learn. This library is used extensively throughout the code base, as
that’s the one we use to handle concurrency, and Tezos is a very
concurrent system. You can use the online documentation. The `PDF
manual <https://ocsigen.org/download/lwt-manual.pdf>`__ is also quite
well written, but unfortunately not up to date, in particular the syntax
extension has changed. It is still a valid resource for the basic
concepts. The chapter on concurrency of `Real World
OCaml <https://github.com/dkim/rwo-lwt>`__ has also been ported to Lwt.

After that, it is a good idea to read the tutorials for
:ref:`error_monad<error_monad>` and
:ref:`data_encoding <data_encoding>`, two homegrown
libraries that we use pervasively.

Where to start
--------------

While you familiarize yourself with the basics as suggested above, you
can have a look at the :ref:`software architecture
<the_big_picture>` of Tezos. It will
give you the main components and their interactions, and links to the
documentations for the various parts.

Our git workflow
----------------

First, the repository is http://gitlab.com/tezos/tezos, the github one
is just a clone that exists for historical reasons. So if you want to
contribute, simply create an account there.

Then, there are many ways to use Git, here is ours.

We use almost only merge requests to push into master. Meaning, nobody
should push directly into master. Once a merge request is ready, it is
reviewed and approved, we merge it using the ``--fast-forward`` option
of Git, in order to maintain a linear history without merge patches.

For that to work, it means that merge requests must be direct suffixes
of the master branch. So whenever ``origin/master`` changes, you have to
rebase your branch on it, so that you patches always sit on top of
master. When that happens, you may have to edit your patches during the
rebase, and then use ``push -f`` in your branch to rewrite the history.

We also enforce a few hygiene rules, so make sure your MR respects them:

-  Prefer small atomic commits over a large one that do many things.
-  Don’t mix refactoring and new features.
-  Never mix reindentation, whitespace deletion, or other style changes
   with actual code changes.
-  Try as much as possible to make every patch compile, not only the
   last.
-  If you add new functions into a documented interface, don’t forget to
   extend the documentation for your addition.
-  For parts whose specification is in the repository (e.g. Michelson),
   make sure to keep it in sync with the implementation.
-  Try and mimic the style of commit messages, and for non trivial
   commits, add an extended commit message.

As per the hygiene of MRs themselves:

-  Give appropriate titles to the MRs, and when non trivial add a
   detailed motivated explanation.
-  Give meaningful and consistent names to branches.
-  Don’t forget to put a ``WIP:`` flag when it is a work in progress.
