Erste Entwicklungs-Branch
Nun können wir mit tatsächlicher Entwicklungsarbeit beginnen. Nachdem wir unseren master-root-Commit erstellt haben sollte die Arbeit in einer Branch erstellt werden. Wir erstellen sie und wechseln von master zu ihr:
$ git branch feature/simple-build-system$ git checkout feature/simple-build-systemSwitched to branch 'feature/simple-build-system'
Branch-Namen dürfen viele Zeichen enthalten, es ist aber Empfehlenswert sich auf die Kleinbuchstaben des lateinischen Alphabets, Zahlen, das Minus - und Schrägstriche zu beschränken. Die Schrägstriche können als Hierarchieebenen-Trenner verwendet werden. Es empfiehlt sich, eine begrenzte Zahl von Hierarchie-Prefixen zu verwenden. Für unsere Zwecke sind das:
workflow/für Workflow-Neuentwicklungen.feature/für neu hinzugefügte Logiken.fix/für Korrekturen von Fehlern.change/für Änderungen an bestehenden Logiken.
Die git-branch-git-checkout-Kombination wird häufig genug gebraucht dass es dafür einen Shortcut gibt: git checkout -b <branch>. Dieser wird im Folgenden verwendet werden.
In unserer neuen Branch erstellen wir nun eine erste Quellcode-Datei, mit der wir unser Build-System testen können.
$ vim Main.java
public class Main {public static void main(String[] args) {System.out.println("Hello, World!");}}
Inhalt Main.java
Im Anschluss wird die Datei wie gehabt committed:
$ git add Main.java$ git commit
Add a source file for testing compilation
Um nicht javac von Hand bedienen zu müssen erstellen wir uns ein kleines Makefile. Hierbei muss aufgepasst werden, dass Einrückung mittels Tab-Zeichen stattfindet. Ein Texteditor, der Makefile-Dateitypen kennt, sollte das automatisch berücksichtigen.
$ vim Makefile
JC=javacJAVA=javaCLASSES = \Main.java.SUFFIXES: .java .class.java.class:$(JC) $*.java.PHONY: compilecompile: $(CLASES:.java=.class).PHONY: cleanclean:-$(RM) *.class.PHONY: runrun: compile@$(JAVA) Main.PHONY: alldefault: compile
Inhalt Makefile
Auch diese Datei können wir nun wieder committen:
$ git add Makefile$ git commit
Add Makefile for compiling and runinng
Vielleicht wäre aber ein Test vor dem Commit angebracht gewesen. Holen wir dies nach:
$ makemake: Nothing to be done for `compile'.$ make runError: Could not find or load main class Mainmake: *** [run] Error 1
Das sieht nicht gut aus. Bei genauem Hinsehen offenbart sich ein fehlendes "S" in Zeile 12 des Makefiles (CLASES → CLASSES). Nach dieser Korrektur sieht es besser aus:
$ make runjavac Main.javaHello, World!
Wir könnten die Korrektur in einem neuen Commit hinzufügen. Da unsere lokale Entwicklungsbranch, und insbesondere der initiale Makefile-Commit, aber noch nicht veröffentlicht wurden, können wir den letzten Commit aber alternativ auch anpassen:
$ git add Makefile$ git commit --amend
Es öffnet sich wieder ein Editor, dieses Mal aber mit der Commit-Message vom letzten Commit bereits vorhanden. Speichern, schließen, und niemand hat wird unseren voreiligen ersten Commit jemals sehen!
Dass es keinen dritten Commit gibt, lässt sich auch mithilfe der Historie prüfen:
$ git logcommit 822c56d6760226203d76014fcc489998233ded64 (HEAD -> feature/simple-build-system)Author: Some One <some.one@proclane.com>Date: Mon Nov 25 13:43:34 2019 +0100Add Makefile for compiling and runinngcommit 062eda185e8b66aed570cba0fb9b12279a22c110Author: Some One <some.one@proclane.com>Date: Mon Nov 25 13:26:17 2019 +0100Add a source file for testing compilationcommit ad65f62c553c0bff5e63725c868cf1938ed32742 (master)Author: Some One <some.one@proclane.com>Date: Mon Nov 25 11:45:51 2019 +0100Initial commit, add .gitignore and empty README
Leider hat sich beim Verfassen der Message ein Fehler eingeschlichen. Auch so ein Fehler lässt sich via --amend korrigieren. Ohne eine Datei zu stagen wird der folgende Befehl erneut ausgeführt:
$ git commit --amend
Nun korrigieren wir "runinng" zu "running" und sollten damit unseren Makefile-Commit endlich fertig haben.
Die Tests haben jedoch Dateien erzeugt, die wir nicht committen wollen:
$ git statusOn branch feature/simple-build-systemUntracked files:(use "git add <file>..." to include in what will be committed)Main.classnothing added to commit but untracked files present (use "git add" to track)
Wir könnten die .class-Datei zwar löschen, aber jedes Kompilieren würde die Datei neu anlegen. Wir sollten stattdessen alle Dateien dieser Art ignorieren. Dafür fügen wir einen neuen Eintrag in unserer .gitignore ein, dieses Mal kommentiert und direkt von der Kommandozeile:
$ echo > .gitignore$ echo '# Build artifacts' >> .gitignore$ echo '*.class' >> .gitignore
Git ignoriert schon jetzt die .class-Datei, die Änderungen in der .gitignore müssen allerdings noch committed werden.
$ git statusOn branch feature/simple-build-systemChanges not staged for commit:(use "git add <file>..." to update what will be committed)(use "git restore <file>..." to discard changes in working directory)modified: .gitignoreno changes added to commit (use "git add" and/or "git commit -a")
Ein solcher Commit passt inhaltlich zu unserer aktuellen Branch, also machen wir das auch hier. Bevor wir die Datei stagen, gucken wir noch einmal schnell welche Änderungen aus Gits Sicht gemacht wurden:
$ git diffdiff --git a/.gitignore b/.gitignoreindex 956ec59..9b4caac 100644--- a/.gitignore+++ b/.gitignore@@ -1,3 +1,3 @@-%SystemDrive%-Thumbs.db-.DS_Store++# Build artifacts+*.class
Die drei mit + beginnenden Zeilen wurden neu hinzugefügt. Die drei Zeilen, die mit - beginnen wurden entfernt - das war nicht unser Ziel. Der erste der drei echo-Befehle hätte auch "append" (>>) statt "overwrite" (>) verwenden müssen. Zum Glück war die Datei schon committed, wir können sie einfach wieder herstellen. Um unsere Änderungen nicht doppelt machen zu müssen, sichern wir sie kurz weg, fügen sie an die wiederhergestellte Datei an, und löschen die Kopie danach:
$ cp .gitignore bak$ git restore .gitignore$ cat bak >> .gitignore$ rm bak$ git diffdiff --git a/.gitignore b/.gitignoreindex 956ec59..ac75306 100644--- a/.gitignore+++ b/.gitignore@@ -1,3 +1,6 @@%SystemDrive%Thumbs.db.DS_Store++# Build artifacts+*.class
Das sieht schon besser aus. Es folgt ein Commit.
$ git add .gitignore$ git commit
Ignore .class files
Hinweis: git diff liefert die nicht gestageden Änderungen, git diff --cached stattdessen alles, was schon mit git add hinzugefügt wurde.