subcomponent 0.1.0

A components orchestrator
# Git Fetcher Algorithm

Through this document, we will associate pseudo-variable to subcomponent properties:

| Property              | Shell Variable        |
|-----------------------|-----------------------|
| tag                   | `$TAG`                |
| commit                | `$COMMIT`             |
| url                   | `$URL`                |
| branch                | `$BRANCH`             |
| tag or commit         | `$REVISION`           |
| path                  | `$PATH`               |
| clone-recursive       | `$SUB`                |
| remote                | `$REMOTE`             `

The remote `$REMOTE` is expected to be entirely used by subcomponent. It must
has exclusive access to this remote.

## Cloning a new repository

### Cloning a new branch

```bash
git clone --quiet --origin=$REMOTE --branch $BRANCH $ARGS $URL $PATH
```

- `$ARGS` are defined from the following table:

| Property                      | Git Flag              |
|-------------------------------|-----------------------|
| shallow: true                 | --depth=1             |
| shallow-submodules: true      | --shallow-submodules  |
| clone-recursive: true         | --recursive           |


### Cloning a new tag/commit

```bash
git clone --quiet --origin=$REMOTE --no-checkout $URL $PATH
git -C $PATH checkout --quiet $REVISION
if [ $SUB ] ; then git -C $PATH submodule update --quiet --init --recursive $ARGS ; fi
```

- `$ARGS` are defined from the following table:

| Property                      | Git Flag              |
|-------------------------------|-----------------------|
| shallow-submodules: true      | --depth=1             |



## Updating an already existing repository

Obviously the first check is to verify that the git repository to be updated
is actually a git repository...

We must ensure that the `$REMOTE` remote is controlled by subcomponent. If
a `$REMOTE` remote exists, it must be updated to the URL that subcomponent
tries to retrieve the repository from.

```bash
REMOTES=$(git -C $PATH remote)
if "subcomponent" in $REMOTES: git -C $PATH remote set-url $REMOTE $URL
else git -C $PATH remote add $REMOTE $URL
```

If the repository is shallow (presence of `$GIT_DIR/shallow`), and is its current revision
is different from the new one, it must be unshallowed first:

```bash
git -C config --unset --local remote.$REMOTE.fetch
git -C config --local remote.$REMOTE.fetch "+refs/heads/*:refs/remotes/$REMOTE/*"
git -C $PATH fetch --unshallow $REMOTE
```

```bash
git -C $PATH fetch --tags $REMOTE
git -C $PATH checkout ${REVISION|BRANCH}
```