Tagging und Deployment

Mit der ersten einsatzbereiten Funktionalität können wir eine zweite langlebige Branch erstellen, die wir für den Stand des Produktivsystems nutzen. Diese heißt bei uns immer production. Anleitungen im Internet verwenden häufig development und master für die aktuelle und stabile Branch. Wir verwenden stattdessen master und production.

Zu deployenden Stand pushen

Das Erstellen einer neuen Branch machen wir wie gehabt:

$ git checkout -b production

Deployments auf das Produktivsystem sollten möglichst geordnet und nachvollziehbar geschehen. Aus diesem Grund werden alle deployten Stände vor dem Deployment getaggt, und auf dem Produktivsystem direkt die Tags ausgecheckt. Gits Tags sind einfach nur globale Namen, die auf einen bestimmten Commit zeigen. Dieser Commit kann nicht mehr geändert werden.

$ git tag -a prd/2019-11-27-hello-world

Das Flag -a ist kurz für --annotate und bewirkt, dass wir im gewohnten Editor-Fenster die Möglichkeit bekommen, dem Tag noch eine Message anzuheften. Der darauf folgende Tagname unterliegt ähnlichen Regeln wie Branch-Namen und sollte drei Bestandteile haben:

  1. Das Präfix prd/.
  2. Den aktuellen Datumsstempel (bei absehbar mehreren Deployments an einem Tag sollte ein voller Zeitstempel verwendet werden).
  3. Eine ganz kurze Zusammenfassung (zwei bis vier Wörter), damit der Inhalt des Deployments am Tag-Namen einfacher erkennbar ist.

Falls man sich verschrieben hat, kann mit git tag -d <tagname> der Tag direkt wieder gelöscht und dann einfach erneut angelegt werden.

Da unsere Branch neu ist, muss ihr beim ersten Push noch eine Remote-Branch zugeordnet werden:

$ git push --set-upstream origin production
Total 0 (delta 0), reused 0 (delta 0)
To git.honico.com:personal/sone/git-schulung.git
* [new branch] production -> production
Branch 'production' set up to track remote branch 'production' from 'origin'.

Tags werden nicht automatisch gepusht. Wir brauchen das zusätzliche Flag --tags:

$ git push
$ git push --tags
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 201 bytes | 201.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To git.honico.com:personal/sone/git-schulung.git
* [new tag] prd/2019-11-27-hello-world -> prd/2019-11-27-hello-world

Deployment durchführen

Das Deployment "simulieren" wir mit einem zweiten lokalen Repository in einem neuen Terminal-Fenster:

$ git clone --branch production git.honico.com:personal/sone/git-schulung.git deployment-repo
Cloning into 'deployment-repo'...
remote: Counting objects: 19, done.
remote: Compressing objects: 100% (18/18), done.
remote: Total 19 (delta 6), reused 0 (delta 0)
Receiving objects: 100% (19/19), done.
Resolving deltas: 100% (6/6), done.

Dort können wir nun den Tag auschecken (und gegenenfalls alle Tags auflisten lassen):

$ cd deployment-repo
$ git tag --list
prd/2019-11-27-hello-world
$ git checkout prd/2019-11-27-hello-world
Note: switching to 'prd/2019-11-27-hello-world'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:
git switch -c <new-branch-name>
Or undo this operation with:
git switch -
Turn off this advice by setting config variable advice.detachedHead to false
HEAD is now at e1b1f59 Merge branch 'change/more-innovative-greeting'

Git erwähnt nun etwas von einem "detached HEAD" state. Was damit gemeint ist, ist dass das Repository nun nicht mehr in einer Branch arbeitet, sondern auf einem einzelnen Commit. Das hat für unsere Zwecke die Folge, dass auch bei einem git pull keine Änderungen an den Dateien die Folge sind - ohne explizite Aufforderung ändert sich nichts am aktuellen Zustand des Verzeichnisses. Beim nächsten Deployment kann einfach nach einem Pull der dann aktuelle Deployment-Tag ausgecheckt werden.