
\subsection{The problem(s)}

The currently dominant development model of the \textsc{Pencil Code} is

\begin{itemize}

\item \emph{unstructured:} Commits cannot be grouped predictably, because
  while you try pushing them, others could push some commits of their own;

\item \emph{opaque:} if commits are not grouped, it is hard to see what is
  going on;

\item \emph{hard to test:}
  \begin{itemize}
  \item Continuous-integration tests (= CI tests, which we sometimes call
    Pencil tests or autotests) have hard time constraints and thus cannot
    be thorough;
  \end{itemize}

\item \emph{fragile:} as a consequence of being hard to test;

\item \emph{obscuring responsibility:} If I made two commits, and A has
  pushed 3 commits in between (see \emph{unstructured} above), would I be
  testing my changes or theirs?

\end{itemize}


\subsection{Advantages of branch-oriented development}

\begin{itemize}

\item Much deeper testing
\begin{itemize}
\item You can take your time to run all tests before merging your branch
  back into \emph{main} (= \emph{master}). This allows us to have really
  thorough tests.
\item Independence from CI. CI is nice, but it is dangerous to rely on it
  (and it limits the amount of testing)
\end{itemize}

\item Clearer identification of responsibility

\item Isolates unrelated changes from each other until they really need to
  get dealt with

\item Friendly competition (survival of the most popular branch)

\item You can get new features running and ask interested others to test
  before you finalize them (instead of: everybody immediately has to live
  with your new feature, although it is not thoroughly tested yet -- you
  had to push it onto \emph{main} before asking the interested others).

\item Reduces stress level, because you can properly work on a feature
  without interfering with others and later do all the tests and push.
\end{itemize}


\subsection{Note}

\begin{itemize}
\item We have used branches before (e.g.\ the GPU branch)
\end{itemize}


\subsection{Feedback and criticism}

Here is the gist of some responses I got to an earlier version of the
proposal below.

\begin{itemize}

\item “Risk of fragmentation”
  \begin{itemize}
  \item But where is the problem if all branches are pushed to the server?
    \begin{itemize}
    \item If you need functionality from another branch on your own
      feature branch, you can (a) merge that branch, or (b) cherry-pick
      the relevant changes from there.
    \end{itemize}
  \item \emph{The important thing is to have all branches pushed to the
  server}.
    \begin{itemize}
    \item Currently: If you are not willing (yet) to push, your changes are
      only local, which is much worse.
    \end{itemize}
  \end{itemize}

\item “For short-lived branches which are not shared with anyone else, I
  would recommend rebasing, as it keeps the history cleaner (this helps
  later on if one is bisecting to find when a bug was introduced to the
  master branch).”
  \begin{itemize}
  \item I am open to that, though I personally find history with (even
    medium-sized) topic branches cleaner; and \texttt{git bisect} works
    across branches just as well.
  \end{itemize}

\item “I fear that if we start using more branching this will result in
  some branches never being merged back into main. This will eventually
  lead to several versions of the \textsc{Pencil Code}.”
  \begin{itemize}
  \item There will always be some branches not (yet) merged.
    If they are relevant, they will eventually get back into \emph{main},
    be it that they get merged or cherry-picked.
    (And if they are not, who cares?)
    Should there really appear two branches of the code that continue to
    be popular among users over a long time, we should strive to merge
    them.
  \end{itemize}

\item “\ldots other codes in which multiple groups maintained branches of
  code which were entirely incompatible with the main branch or each
  other.”
  \begin{itemize}
  \item Rule 6. below strongly encourages to not let branches diverge too
    far from \emph{main}. Being able to decide for yourself when exactly
    you reconcile your changes with \emph{main} is an enormous benefit.
  \end{itemize}
\end{itemize}


\subsection{Proposal}

Here is a set of rules that I would like to see implemented:

\begin{enumerate}

\item The main person responsible for a commit is its author.

\item The maintainers are important, as often only they know how a sample
  really works.
  However, it is not their responsibility to react to commits breaking an
  auto-test sample.

\item Ideally, any commit that ends up on \emph{main} (the main branch of
  the code) should not break any of the essential auto-test samples.

  If it turns out that a commit violates this rule, the broken tests need
  to be fixed swiftly.
  Either by the commit author committing a fix, or by others reverting the
  commit in question.

  \emph{Any commit that breaks an auto-test may be reverted by anybody
  without prior notice in order to fix that test.}

\item Keep individual commits focused on one logical unit (i.e.\ keep them
  small and do not conflate loosely related topics).
  This is crucial for identifying and reverting problematic commits.

\item For a sequence of commits that belong logically together, it is not
  very feasible, and also not necessary, to run the test suite for each of
  them.

  Instead, develop the feature on a branch.
  When you think the feature is ready, merge \emph{main} into your feature
  branch and run the tests.
  If they all run successfully, merge your branch back into \emph{main}.

  \emph{Never merge a branch into \emph{main} without having verified that
  the auto-tests work.}

\item Try to keep the lifetime of branches short, even though this will
  not always be possible.
  If your branch has to live longer, you should periodically merge
  \emph{main} into it.

\item
  \emph{Never quietly adjust reference results in an auto-test sample
  directory to fit your latest data.}

  If reference data need to be touched up, this must be agreed upon with
  the maintainer(s) of that test.

\item When making changes that will affect auto tests:

  \begin{enumerate}
  \item Discuss this with everybody before you commit the change.

  \item Isolate auto-tests against the change. E.g. if you are to change
    the default value of \texttt{lmassdiff\_fix} from \texttt{.false.} to
    \texttt{.true.}, make sure to explicitly set
    \texttt{lmassdiff\_fix = .false.} in all auto-test samples that would
    otherwise be affected by the change.
\end{enumerate}

\item Never rely on the automatic tests run after a commit on the GitHub
  server, or the bisection that is done. It is the committer's
  responsibility to run all officially accepted auto-tests.

\item Never rely on automatic emails to reach a maintainer of an auto-test
  (or in fact anybody else). If you need to discuss an auto-test, contact
  the maintainer directly and only assume that you reached them once they
  reply.

\end{enumerate}
