Skip to content
This repository was archived by the owner on Aug 5, 2019. It is now read-only.

How does SimpleGitVersion work?

Olivier Spinelli edited this page Nov 11, 2015 · 18 revisions

#Git Basics CSemVer (http://csemver.org) can be applied to Git repository: this is the goal of the SimpleGitVersion project. To understand it, try to forget the Git branches and consider the basics of Git:

  • A commit point has a ‘content’: its ‘File tree’ is our ‘base of code’.
  • A commit can have tags: in our case, when a commit is tagged with ‘v4.5.0-rc.2’ this means that the ‘File tree’ of this commit contains and defines everything we need to build this exact version of our product/artefact.
  • Tags are unique across the repository: there can be only one commit tagged with ‘v4.5.0-rc.2’.
  • More than one commits can contain identical File trees and this is easy to detect: these File trees share the same SHA1 that we call ContentSHA.
  • A commit point is either:
    • An orphan (the initial commit in ‘master’ commit for instance)
    • Based on a commit: it carries the differences between itself and its Parent.
    • Based on 2 (or more) commits: it merges its 2 (or more) Parents’ File tree into one File tree.
  • There can not be cycles in the graph. This is a classic DAG.

This is our playground for Git, no more no less. You may wonder where the branches are in this picture. We don’t use branches. Of course, branches help, they are important to organize the repository (and the work), but we consider them to live at a higher level of organization. We are claiming that proper versioning can, and should, be achieved by considering only the commits and the topology of the repository.

#The algorithm SimpleGitVersion computes a set of PossibleVersions for any commit (let's call it C) in the repository with the following (rouggly formalized) algorithm:

  • Considering the set of existing versions that exist in the repository (all existing versions excluding the version applied to C if it exists): EV
  • Considering P(C), all the parent commits of C.
  • Computes the Base Versions Bv of C based on:
    • Tc = The Maximal Version Tag that appears in P(C).
    • Mc = The Maximal Version Tag or Content Tag that appears in P(C).
    • 0v = The special no-version Tag.
    • Base Versions are: Bv = {Tc, Mc} or {Tc} or {Mc} or {0v} (when there is no Tc nor Cc).
  • For each vBase version in Bv, computes the successors of vBase
    • Consider the nearest next released: NNr = smallest version in EV greater than vBase.
    • Initializes S with the set of direct successors of vBase.
    • If NNr exists:
      • Keep in S only the versions that are patches (PatchRelease & PatchPreRelease).
      • Keep in S only the versions that are smaller than NNr.
  • The possible versions for C is the union of the one or two S sets previously obtained.

This is a simple algorithm that relies on the fact that the repository is 'valid': any tagged commit must be tagged with a version greater than any version appearing among its parent commits.

Clone this wiki locally