1git-series internals
  2====================
  3
  4Requirements
  5------------
  6
  7The format git-series uses to store each patch series ensures that standard git
  8tools can always handle a git-series repository.  In particular:
  9
 10- All commits and objects in the history and metadata of every series must
 11  remain reachable via git's normal object reachability algorithms, so that git
 12  will never discard the history or metadata of a series.
 13- Transferring a git-series repository via git's standard protocols must
 14  transfer all series including history and metadata, without any extensions to
 15  the git protocols.
 16
 17Refs
 18----
 19
 20git-series stores the series ref for a patch series named `NAME` in
 21`refs/heads/git-series/NAME`.  This will appear to git as a branch named
 22`git-series/NAME`.  From that ref, git can reach all the information git-series
 23tracks about a patch series, so sending or receiving that ref brings along all
 24the information git-series needs.
 25
 26git-series maintains a symbolic ref `refs/SHEAD` pointing to the current
 27series.  If a repository does not have a current series, SHEAD will not exist.
 28
 29git-series commits
 30------------------
 31
 32git-series stores each version of a patch series as one commit object.  The
 33`git-series/NAME` ref refers to commit corresponding to the current version of
 34the patch series NAME.  The tree object within each git-series commit acts like
 35a key-value store, with tree entry names as keys; the tree entry `series`
 36references the last commit of the patch series itself.
 37
 38In this documentation, a "git-series commit" refers to a commit corresponding
 39to a version of an entire patch series, as distinguished from a commit
 40corresponding to one patch within a patch series.
 41
 42The first parent of each git-series commit always points to the previous
 43version of the patch series, if any.  The remaining parents of each git-series
 44commit correspond to commits referenced as gitlinks (tree entries with mode
 45160000) within the commit's tree.  This ensures that git can reach all of those
 46commits.  (Note that git's traversal algorithm does not follow gitlink commits
 47within tree objects, so without these additional parent links, git would
 48consider these gitlink commits unreachable and discard them.)
 49
 50The second and subsequent parents of each git-series commit do not appear in
 51any particular order; do not assume that the `series` object or any other
 52gitlink appears at any particular position within the parents list.  These
 53parents exist only to make commits reachable and transferable by git.  Always
 54look up commits via named tree entries within the git-series commit's tree
 55object.
 56
 57In the root git-series commit, all the parent commits correspond to gitlinks
 58within the tree.  This will not occur for any non-root commit of a git-series.
 59Algorithms trying to walk from a git-series commit to its root should detect
 60the root git-series commit by checking if the first parent appears in the
 61git-series commit's tree.  (This does not require a recursive tree walk; the
 62first parent of the git-series root will always appear in the top-level tree
 63object.)
 64
 65git-series tree entries
 66-----------------------
 67
 68The tree within a git-series commit can contain the following entries:
 69
 70- `series`: Every git-series tree must contain this entry, as a gitlink with
 71  mode 160000.  This identifies the last commit in the patch series.
 72- `base`: If this exists, it must refer to a gitlink with mode 160000.  This
 73  identifies the base commit for the patch series.  The patch series consists
 74  of the commits reachable from `series` and not reachable from `base`:
 75  `base`..`series`.  Many git-series commands require `base`, but a patch
 76  series does not have to have a `base`.
 77- `cover`: If this exists, it must refer to a blob with mode 100644.  This
 78  provides a cover letter for the patch series.  This blob should contain UTF-8
 79  text.
 80
 81git-series staged changes and "working directory"
 82-------------------------------------------------
 83
 84Like git, git-series allows staging part of all of the changes to the patch
 85series for a commit, or committing all the changes directly via `git series
 86commit -a`.  However, git-series does not maintain a "working directory"
 87directly.  Instead, git-series tracks the staged and unstaged changes to a
 88patch series named NAME via commits referenced by
 89`refs/git-series-internals/staged/NAME` and
 90`refs/git-series-internals/working/NAME`.  The tree of each of those commits
 91may contain any of the standard git-series tree entries.  (If the series has
 92nothing staged, the "staged" ref will not exist.)  These commits will also have
 93all of the corresponding gitlink entries as parents, to keep them reachable by
 94git.
 95
 96The `working` commit for a patch series tracks the current state of the patch
 97series.  For example, setting a base with `git series base` or a cover letter
 98with `git series cover` will store the new base or cover letter as `base` or
 99`cover` in the tree of the commit referenced from the working ref.  git-series
100commands will keep the `series` entry of the working tree referring to the
101current HEAD.
102
103The `staged` commit for a patch series, if present, tracks the staged changes
104to the patch series.  `git series add` adds changes from `working` to `staged`,
105and `git series unadd` removes changes from `staged`.
106
107If a series does not have a series ref `refs/git-series/NAME`, but has a staged
108or working ref, the series still exists, with no series commits.  This can
109happen by running `git series start NAME`, making some changes without
110committing, and then running `git series detach`.  git-series treats that as an
111existing series, and allows checking it out.  This preserves work in progress
112on an un-started series.