Package: giit
The Git Iteratorgiitis a small tool for running commands on
branches and tags of a git repository.It’s original purpose was to allow Sphinx documentation to be easily
generated for all available tags of a bunch of different repositories. However,
should you find a different use for it - you should also be able to adapt it
to other scenarios.Table of Contents:Quick StartInstallationExample: C++ project documentationendiangiit.jsonlocationFilters and tasksbranches.regex.filtersbranches.source_branchtags.regex.filterstags.semver.filterstags.semver.relaxedworkingtreeNo filterCommand-line filteringContext and variablesExampleUser variablesOptional VariablesEscaping Variable Replacementsgiitcommand line argumentsArgument:STEPArgument:REPOSITORYOption:--build_pathOption:--giit_pathOption:--config_branchOption:--config_pathOption--variableOption-v/--verboseThecleanstepQuick StartTo usegiityou define agiit.jsonfile which contains the steps
you wantgiitto be able to run. Note, thegiit.jsonfile can
live in the root of the repository.Let’s say we want to generate the Sphinx documentation for a specific
repository.Installationgiitis a Python package so you canpip installit. If you just want to
try it out use a virtualenv or similar:$ virtualenv giit
$ source giit/bin/activateNow install thegiitpackage:$ pip install giitExample: C++ project documentationendiangiituses agiit.jsonfile to describe the different steps:{
    "docs": {
        "branches.regex.filters": [
            "origin/master"
        ],
        "scripts": [
            "sphinx-build -b html . ${build_path}"
        ],
        "cwd": "${source_path}/docs",
        "requirements": "${source_path}/docs/requirements.txt"
    }
}Lets build theendianSphinx documentation
(https://steinwurf-endian.netlify.app/latest/) by runninggiit:giit docs https://github.com/steinwurf/endian.git --config_path ./giit.jsonYou should now seem something like:Lets go: docs
Building into: /tmp/giit/data/build/endian-30a816
Using git version: 2.34.1
Using git repository: https://github.com/steinwurf/endian.git
Running: git clone into /tmp/giit/data/clones/endian-30a816
Using giit.json from path /tmp/giit_cwd/giit.json
Tasks generated 1
Running task [1/1]: scope 'branch' name 'master' checkout 'origin/master'
Python: sphinx-build -b html . /tmp/giit/data/build/endian-30a816If you visit/tmp/giit/data/build/endian-30a816with your web browser
you should be able to see theendianSphinx documentation.giit.jsonlocationSince the content of thegiit.jsonfile fully determines the steps
taken bygiitunderstanding how thegiit.jsonfile is found is
quite important.The following outlines the rules:Passing a path using--config_pathor passing a branch
using--config_branch.If no config path or branch is passed by the user andgiitis
invoked with an URL (like in theendianexample).Example:giit docs https://github.com/endian/endian.gitIn this casegiitwill look at the root of the repository inorigin/masterbranch for agiit.json.If no config path or branch is passed by the user andgiitis
invoked with a path:git docs ../path/to/repoIn this casegiitwill try to find agiit.jsonat../path/to/repo/giit.json.Filters and tasksAs we saw in theendianexample a single task is generated for building
theorigin/masterbranch. We can generate more tasks by setting up more
filters.As a quick note it is also possible to not specify any filters. In that case
a single task for running the specified scripts will be gererated (with a
limited context - see below).To specify the different filters here are the available options:branches.regex.filtersThis is a list of regular expressions that will be matched against the branch
name. If the regular expression matches a task will be generated.For example (ingiit.json):"branches.regex.filters": [
    "origin/master",
    "(\d+\.\d+.\d+)-LTS"
]branches.source_branchWhen invokinggiitwith a path to a repository e.g.:giit docs../path/repo.giitcan be instructed to build the
remote tracking branch currently checkout out in../path/repo.This is useful in continuous integration systems.For example (ingiit.json):"branches.source_branch": truetags.regex.filtersThis is a list of regular expressions that will be matched against
the tag name. If the regular expression matches a task will be
generated.For example (ingiit.json):"tags.regex.filters": [
    "(\d+\.\d+.\d+)"
]tags.semver.filtersIf a project uses sematic versioning the semver filter can be used.For example (ingiit.json):"tags.semver.filters": [
    ">=0.1.1", "<0.3.0"
]We usehttps://python-semanticversion.readthedocs.io/en/latest/you
can find more examples of requirement specifications there.tags.semver.relaxedIf a project uses “kind-of” semver, such as1.20, you can set the
semver filter in relaxed mode and still use the filters.For example (ingiit.json):"tags.semver.relaxed": trueworkingtreeTheworkingtreefilter is useful for quickly iterating on stuff.
It is similar to thesource_branchfilter. In that ifgiitis
invoked with a path, then that path will be theworkingtreethis
allows you to rungiitwithout commit’ing pushing changes.For example (ingiit.json):"workingtree": trueNo filterIf you pass no filter e.g.tags,branchesorworkingtree, giit
will generate a single task for just running the script.Command-line filteringPer defaultgiitwill run all tasks generated by the config file. By specifying
the task_filter argument you can filter which tasks are run.
Any tasks that doesn’t match the given shell-style wildcard
expression will not be run.
The special characters used in shell-style wildcards are:PatternMeaning*matches everything?matches any single character[seq]matches any character inseq[!seq]matches any character not inseqContext and variablesIn theendianexample you may have noticed what we used the${build_path}and${source_path}in thejsonconfiguration.These denote variables that will be substituted when running the
tasks. The following variables are always available:build_path: This points to the directory where the command
is expected to output any artifacts produced by the command. It is
up to thegiit.jsonauthor to ensure this happens.source_path: This is the path to where the current git
repository is checked out.checkout: This is the checkout of that was used.name: This is a shorter version of checkout. E.g. for branches
if the checkout isorigin/masterthe name will bemaster.
Also if thecheckoutcontains/that may result in
unwanted sub-directories. In thenamewe replace/with_.
So if a branch is calledorigin/bug/543the name will bebug_543.scope: This can be one of three values. Eithertag,branchorworkingtree.Note, only the${build_path}variable is available when running without
any filters.ExampleHere we will use the${name}variable to output documentation
for the different tags to different folders:{
    "docs": {
        "branches.regex.filters": [
            "origin/master"
        ],
        "tags.semver.filters": [
            ">=1.20"
        ],
        "tags.semver.relaxed": true,
        "scripts": [
            "sphinx-build -b html . ${build_path}/${name}"
        ],
        "python_path": "${source_path}/src",
        "cwd": "${source_path}/docs",
        "requirements": "${source_path}/docs/requirements.txt"
    }
}User variablesIn some cases we want to define our own variables according to some
simple rules.This is done either using thevariablesattribute in the json or by using
the--variable[name] [value]command line argument.User variables are define using the following syntax:scope:remote_branch:variable_nameWherescopeandremote_branchare optional.This can be used to customize e.g. the output of a command. Consider
the following example:{
    "docs": {
        ...
        "scripts": [
            "sphinx-build -b html . ${output_path}"
        ],
        "variables": {
            "branch:origin/master:output_path": "${build_path}/docs/latest",
            "branch:output_path": "${build_path}/sphinx/${name}",
            "tag:output_path": "${build_path}/docs/${name}",
            "workingtree:output_path": "${build_path}/workingtree/sphinx"
        }
    }
}When callinggiit docs ...we use the user definedoutput_pathvariable.Let walk though the different valuesoutput_pathcan take.If scope isbranchand the branch isorigin/masterthenoutput_pathwill be${build_path}/docs/latest.For all other branchesoutput_pathwill be${build_path}/sphinx/${name}where${name}will be the
branch name.For the tagsoutput_pathwill be${build_path}/docs/${name}where name is the tag value e.g.1.0.0etc.Finally if we are in theworkingtreescope theoutput_pathvariable will be${build_path}/workingtree/sphinxLets see how this could look (build_pathis/tmp/project):Tag 1.0.0 -----------> /tmp/project/docs/1.0.0
Tag 2.0.0 -----------> /tmp/project/docs/2.0.0
Tag 2.1.0 -----------> /tmp/project/docs/2.1.0
Tag 3.0.0 -----------> /tmp/project/docs/3.0.0
Branch master -------> /tmp/project/docs/latest
Branch trying_new ---> /tmp/project/sphinx/trying_new
Branch new_idea -----> /tmp/project/sphinx/new_idea
Workingtree ---------> /tmp/project/workingtreeOptional VariablesIn some cases you may want to have optional variables. These can be specified
in a similar way as with non optional variables, the only difference is that you
need to use the£character instead of the$character.
If the variable doesn’t exists it simply be removed.Escaping Variable ReplacementsIf you want to use either$or£as characters in the giit configuration
file, you need to escape them.
This is done using$$or££respectively.giitcommand line argumentsThegiittool takes two mandatory arguments and a number of options:giit STEP REPOSITORY [--options]Argument:STEPSelects the step in thegiit.jsonfile to run.Argument:REPOSITORYThe URL or path to the git repository.Option:--build_pathSets the build path (i.e. where the output artifacts/data) will be generated/
built. This argument is available in thegiit.jsonas the${build_path}variable.Option:--giit_pathThis path is where thegiittool will store configurations, virtualenvs
clones created while running the tool. It also serves as a cache, to speed up
builds.Option:--config_branchSpecifies the a branch where thegiit.jsonfile will be take from.Option:--config_pathSets the path to where thegiit.jsonfile.Option--variableExtends the variables set for each step.Option-v/--verboseAllows the verbosity level of the tool to be increased
generating more debug information on the command line.ThecleanstepThis step is always defined, in addition to the steps defined in
thegiit.jsonfile. Thecleanstep just remove thebuild_path.