Design Goals and Principles
===========================

Consistency and tool unification
--------------------------------

One measure of success for git-ubuntu is to reduce or eliminate the occasions
where an experienced Ubuntu developer has to say "that package is special" when
a new developer or drive-by contributor is asking for help on performing a
routine task.

Another measure is the amount of setup required before a developer can perform
a task, such as test building a package from a source tree in a reproducible
way.

For example, in answer to the following questions, git-ubuntu already
eliminates the "this package is special" excuse for packages covered by
git-ubuntu repositories:

* "Where can I clone the git tree for package X"? Without git-ubuntu, "this
  package is special" is needed when a Vcs-Git header doesn't exist, or does
  exist but no git branch is maintained for the Ubuntu delta, or does exist but
  the header hasn't been updated to point to it.

The following are medium term goals:

* "How do I build package X"? Right now, the recommended "sbuild" method
  involves setting up chroots, arranging sbuild group membership, and sbuild's
  default configuration expects an MTA that also requires setting up.

* "How do I patch the version of package X that Ubuntu ships in release Y"?
  Right now, this usually involves knowledge of quilt and the "3.0 (quilt)"
  Debian source package format.

Because git-ubuntu uses a single scheme to represent package source trees in
git, and also a single schema for all branch and tag names, automation that
operates on package sources is easier to write, including automation that needs
visibility across multiple package versions at once. For example, it's easier
to write automation to help validate SRUs since such automation can easily
inspect the current state of different releases and pockets. Instead of using
the Launchpad API for this kind of inspection, the tooling can inspect this
state using the same mechanism it can use to inspect the existing published
source tree and the source trees in Launchpad's queues. git is the single tool
that can be used for all of this.

Single source of truth
----------------------

Uploads arrive into Ubuntu regardless of git-ubuntu, such as via syncs from
Debian or just direct uploads using ``dput`` without git-ubuntu. Launchpad is
the authority that publishes Ubuntu packages via apt. So Launchpad, not
git-ubuntu, is the authority and "single source of truth" of what the source
tree is for a particular package, and what they were historically.

git-ubuntu is designed to be able to guarantee that its git repositories do
actually represent this single source of truth. Therefore, its git repositories
are necessarily derived from and form a view onto Launchpad's single source of
truth, and cannot define it.

Integrity requirements
----------------------

Since git-ubuntu's git repositories are merely a view of Launchpad's single
source of truth, its refs (branches, tags, etc) must also be derived from that
truth and therefore must be read-only from the git perspective. Otherwise,
developers would be able to push a different truth to the git repositories that
do not reflect the truth in Launchpad, and that would defeat the purpose of
git-ubuntu in the first place.

Similarly, the commits that correspond to specific published source package
versions must match what was uploaded exactly, so that developers can trust
that what they see in the git repository corresponds to what was actually
published.

How uploads map to commits
--------------------------

In the common case, git-ubuntu achieves this by synthesizing a commit from what
was uploaded to Launchpad as a package upload. In this case, all the changes
from the previous upload are "squashed" into a single commit.

However, the integrity requirement is just that the specific commits that
correspond to package uploads match. Intermediate commits are permitted, and
these need not be restricted for integrity purposes.

Therefore, this schema allows for developers to provide a "richer" path that
describes how they arrived at their upload in more granular detail, in the
git usual way by providing intermediate commits. In git-ubuntu, since we aren't
the single source of truth, we must handle this specially to maintain our other
integrity requirements, and call this concept "rich history".

.. _rich-history-explanation:

Rich History
------------

git-ubuntu's rich history mechanism has some requirements:

 1. The developer must provide rich history commits at the time of the
    dput-based (non-git) upload.

 2. These commits must remain available to the git-ubuntu importer until after
    it has imported them.

 3. The tree of the final rich history commit provided must precisely match the
    tree of the upload. There exist some edge cases necessary to maintain a
    lossless mapping from source package to git tree where git-ubuntu defines
    exactly what should happen to the tree; the rich history commit must do
    precisely the same to meet this requirement.

 4. The specification defines some further requirements; the general idea
    is that the rich history commits must be based on a commit that corresponds
    to a previous import and your upload must preserve the old
    ``debian/changelog`` entries in the usual way.

If these requirements are met, then git-ubuntu will use your commits for its
import instead of synthesizing one.

See :doc:`/howto/upload` for instructions to provide rich history to the
importer.

Determining the parent
----------------------

Trust the uploader to base it correctly by looking at debian/changelog.
This leads to "force pushes".
