]> juplo.de Git - demos/kafka/training/commitdiff
Skripte: einheitliche --name-value-Parameter, --help, Umstrukturierung
authorKai Moritz <kai.milan.moritz@googlemail.com>
Sun, 31 May 2026 17:32:37 +0000 (17:32 +0000)
committerKai Moritz <kai.milan.moritz@googlemail.com>
Sun, 31 May 2026 17:32:37 +0000 (17:32 +0000)
Parameter-Vereinheitlichung (alle Skripte):
- Alle Parameter verwenden --name value (Leerzeichen statt =, keine
  Positional-Argumente mehr): reset.sh --tag, diff.sh --tag/--from/--to,
  copy.sh --tag/--local
- Alle Skripte erhalten --help mit vollständiger Beschreibung

Umstrukturierung:
- build.sh und patch-nexus.sh aus scripting entfernt; beide operieren
  auf kopierten Übungsverzeichnissen und gehören zu technik-check--vorlage
- copy.sh: --nexus-url entfernt (patch-nexus.sh liegt jetzt in technik-check)
- copy.sh: RSYNC_OPTS-Excludes für entfernte Skripte bereinigt

CLAUDE.md:
- Skript-Tabelle aufgeteilt nach Branch (scripting vs. technik-check--vorlage)
- Parameter-Dokumentation entfernt (--help in jedem Skript)
- Hinweis ergänzt, dass technik-check-Skripte nach copy.sh bereitstehen

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CLAUDE.md
build.sh [deleted file]
copy.sh
diff.sh
patch-nexus.sh [deleted file]
push.sh
reset.sh

index 5f31f24a05b14861baf7523a2cf2bfa5ce4e8b67..4bb7e3a0c390539165f96abb554df644e80148bc 100644 (file)
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -202,31 +202,34 @@ wobei `<artifactId>` mit `pom.xml`s `<artifactId>` (Maven) oder `settings.gradle
 
 **Beim Überprüfen oder Rebasen eines Branches immer verifizieren**, dass der Image-Name und die Version in `docker-compose.yml` mit dem übereinstimmen, was die Build-Dateien tatsächlich erzeugen. Abweichungen sind Implementierungsfehler und müssen gekennzeichnet und korrigiert werden.
 
-## Skripte im Scripting-Branch
+## Verwaltungsskripte
 
-Alle Skripte binden `lib.sh` ein, das seinerseits `branches.sh` lädt und gemeinsame Funktionen bereitstellt.
+### Skripte im `scripting`-Branch
+
+Alle Skripte binden `lib.sh` ein, das seinerseits `branches.sh` lädt und gemeinsame Funktionen bereitstellt. Alle Skripte unterstützen `--help`.
 
 | Skript | Zweck |
 |--------|-------|
 | `branches.sh` | Definiert alle Branch-Namen als Variablen und die Iterationsliste `$BRANCHES` |
-| `lib.sh` | Shared Library: bindet `branches.sh` ein, stellt `$BRANCH_NAMES`-Array (alle Branches inkl. `grundlagen/docker`) sowie `find_common_tag_suffixes()` und `reset_branches_to_remote()` bereit |
-| `push.sh` | Force-pusht alle Branches zu origin. Prüft vorab, ob umzuschreibende Remote-Stände bereits Tags im Remote haben; fehlt ein Tag, werden TIMESTAMP-Backup-Tags für alle Remote-Stände direkt im Remote angelegt. Existiert lokal ein gemeinsames Tag-Suffix für alle Branches (z.B. `--claude-5`), wird es ebenfalls gepusht, sofern noch nicht im Remote vorhanden. |
-| `reset.sh` | Ohne Argument: setzt alle Branches auf `origin/<branch>` zurück. Mit Argument: auf Tag `<branch>--<prefix>` |
-| `diff.sh` | Ohne Arg: lokaler Branch gegen `origin/<branch>`. Ein Arg: gegen `<branch>--<suffix>`. Zwei Args: `<branch>--<suffix1>` gegen `<branch>--<suffix2>` |
-| `build.sh` | Baut alle Branches (erkennt Maven/Gradle automatisch); `--vorlage`-Branches werden übersprungen. Mit `--publish`: Docker-Images veröffentlichen |
-| `copy.sh` | Kopiert Branches anhand ihres Suffix in `../training-exercises/vorlagen/`, `../training-exercises/livecoding/` oder `../training-exercises/spickzettel/` (siehe Suffix-Tabelle oben); `--livecoding--schritte`-Branches werden übersprungen. `rsync --delete` ist immer aktiv. Verzeichnisse zu nicht mehr gelisteten Branches werden automatisch bereinigt. Ohne Schalter: aktualisiert zuerst alle Branches auf Remote-Stand (erfordert Remote-Zugriff). Mit `--local`: kopiert lokale Branch-HEADs ohne Remote-Aktualisierung. Mit `--tag=<suffix>`: kopiert den jeweiligen Tag-Stand. Mit `--nexus-url=<url>` werden Gradle-Setups anschließend für einen internen Nexus gepatcht |
-| `patch-nexus.sh` | Patcht `build.gradle` (Nexus als Repository), `settings.gradle` (pluginManagement) und optional mit `--gradle-dist-url=<url>` auch `gradle-wrapper.properties`. Wird aus dem Zielverzeichnis (`../vorlagen/`) aufgerufen |
+| `lib.sh` | Shared Library mit `$BRANCH_NAMES`-Array und den Funktionen `find_common_tag_suffixes()` und `reset_branches_to_remote()` |
+| `push.sh` | Force-pusht alle Branches und gemeinsame Tags zu origin; legt bei Bedarf TIMESTAMP-Backup-Tags an |
+| `reset.sh` | Setzt alle Branches zurück — auf `origin/<branch>` oder auf einen Tag-Stand |
+| `diff.sh` | Zeigt Diffs aller Branches an — lokal gegen origin, gegen einen Tag-Stand, oder zwei Tag-Stände gegeneinander |
+| `copy.sh` | Kopiert alle Branches in die Übungsverzeichnisse (`vorlagen/`, `livecoding/`, `spickzettel/`); bereinigt veraltete Verzeichnisse automatisch |
 
 Nach Massenoperationen immer zu `scripting` zurückkehren — Skripte führen am Ende `git checkout scripting` aus.
 
 ### Skripte im `springkafka/technik-check--vorlage`-Branch
 
-Dieser Branch enthält zwei zusätzliche Skripte für die Schulungs-Initialisierung:
+Diese Skripte operieren auf den **kopierten** Übungsverzeichnissen (nicht auf den Quell-Branches) und liegen daher im `technik-check`-Branch. Nach einem Aufruf von `copy.sh` stehen sie unter `../training-exercises/vorlagen/springkafka/technik-check/` bereit. Alle Skripte unterstützen `--help`.
 
 | Skript | Zweck |
 |--------|-------|
-| `init-exercises.sh` | Initialisiert die mit `copy.sh` kopierten Übungsverzeichnisse (`training-exercises/vorlagen/`, `training-exercises/livecoding/`, `training-exercises/spickzettel/`). Standard: `--maven` (entfernt Gradle-Artefakte). Mit `--gradle`: verteilt Gradle-Wrapper (JAR, properties, gradlew) und entfernt Maven-Artefakte. Beide Modi löschen Build-Ausgaben und Caches. Scheitert mit Fehler, wenn `--gradle` verwendet wird, aber der Wrapper noch nicht bereit ist — dann zuerst `README-gradle.sh` ausführen. |
-| `README-gradle.sh` | Technik-Check für Gradle: stellt Gradle-Wrapper bereit (lädt ihn herunter, falls fehlend) und führt Build-Test durch. Ohne Schalter: scheitert laut, wenn installierte Version nicht zur benötigten passt. Mit `--update`: ersetzt veralteten Wrapper durch die benötigte Version. |
+| `README-maven.sh` | Technik-Check für Maven: führt vollständigen Build- und Starttest durch |
+| `README-gradle.sh` | Technik-Check für Gradle: stellt Gradle-Wrapper bereit und führt Build- und Starttest durch |
+| `init-exercises.sh` | Initialisiert alle kopierten Übungsverzeichnisse für die Schulung (Maven- oder Gradle-Modus) |
+| `build.sh` | Baut alle Musterlösungen aus `spickzettel/`; erkennt Maven/Gradle anhand des vorhandenen Build-Setups |
+| `patch-nexus.sh` | Patcht Gradle-Setups für einen internen Nexus-Mirror; Aufruf aus dem Vorlagen-Wurzelverzeichnis |
 
 `gradle-wrapper.jar` ist absichtlich nicht im Repository (wird von Unternehmens-Mail-Filtern blockiert). `gradlew` und `gradle/wrapper/gradle-wrapper.properties` sind versioniert und definieren die maßgebliche Gradle-Version für alle Übungen der Schulung. Der Versions-Marker `gradle/wrapper/.gradle-version` ist gitignoriert.
 
@@ -447,5 +450,5 @@ done
 ## Wesentliche Einschränkungen
 
 - `push.sh` force-pusht — das ist für diesen Schulungsworkflow absichtlich und erwartet.
-- `--vorlage`-Branches werden von Build-Skripten übersprungen (sie sind absichtlich unvollständig).
+- `--vorlage`-Branches werden von `copy.sh` in `vorlagen/` kopiert; das neue `build.sh` in `technik-check` baut nur Musterlösungen aus `spickzettel/` und überspringt diese damit automatisch.
 - Der `grundlagen/docker`-Branch ist nicht in `$BRANCHES`, ist aber in `$BRANCH_NAMES` (aus `lib.sh`) enthalten und wird so automatisch von `push.sh`, `diff.sh`, `reset.sh` und `copy.sh` mitbehandelt.
diff --git a/build.sh b/build.sh
deleted file mode 100755 (executable)
index 9c80335..0000000
--- a/build.sh
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/bash
-set -e
-
-source lib.sh
-
-# Ohne --publish: nur bauen (kein Docker-Image veröffentlichen)
-# Mit --publish: bauen und Docker-Image in die Registry schieben
-PUBLISH=false
-[ "$1" = "--publish" ] && PUBLISH=true
-
-for i in $BRANCHES; do
-  declare -n branch=${i}
-  git checkout "$branch"
-
-  if [[ "$branch" == *--vorlage ]]; then
-    echo -e "\nIgnoriere Vorlage: $branch\n"
-    continue
-  fi
-
-  if [ -e 'pom.xml' ]; then
-    echo -e "\nBaue $branch (Maven)"
-    mvn clean install
-    if $PUBLISH; then
-      echo -e "\nVeröffentliche Docker-Image für $branch"
-      if [[ "$branch" == grundlagen/* ]]; then
-        mvn jib:build
-      else
-        mvn spring-boot:build-image -Dspring-boot.build-image.publish=true
-      fi
-    fi
-  elif [ -e 'build.gradle' ]; then
-    echo -e "\nBaue $branch (Gradle)"
-    [ -f bootstrap-gradle.sh ] && ./bootstrap-gradle.sh
-    ./gradlew build
-    if $PUBLISH; then
-      echo -e "\nVeröffentliche Docker-Image für $branch"
-      ./gradlew bootBuildImage --publishImage
-    fi
-  else
-    echo -e "\nIgnoriere Branch ohne Build-Dateien: $branch\n"
-  fi
-done
-
-git checkout scripting
diff --git a/copy.sh b/copy.sh
index d221184b9a59c3ae07a9386741efcf20cdac0f51..3c44a9543ef259960a23b8cfc8a06746392d33e5 100755 (executable)
--- a/copy.sh
+++ b/copy.sh
@@ -7,23 +7,31 @@ MUSTERLOESUNGEN=../training-exercises/spickzettel
 
 source lib.sh
 
-# --tag=<suffix>:      Kopiert den jeweiligen Tag-Stand statt den aktuellen Branch-HEAD
-# --local:             Kopiert lokale Branch-HEADs ohne Remote-Aktualisierung
-# --nexus-url=<url>:   Ruft patch-nexus.sh auf die Vorlagen an
 TAG_SUFFIX=""
-NEXUS_URL=""
 LOCAL=false
-for arg in "$@"; do
-  case "$arg" in
-    --tag=*)       TAG_SUFFIX="${arg#--tag=}" ;;
-    --nexus-url=*) NEXUS_URL="${arg#--nexus-url=}" ;;
-    --local)       LOCAL=true ;;
-    *) echo "Unbekannter Parameter: $arg"; exit 1 ;;
+while [ $# -gt 0 ]; do
+  case "$1" in
+    --tag)
+      [ -n "$2" ] || { echo "Fehler: --tag erfordert einen Wert" >&2; exit 1; }
+      TAG_SUFFIX="$2"; shift 2 ;;
+    --local)
+      LOCAL=true; shift ;;
+    --help)
+      echo "Kopiert alle Branches in die Übungsverzeichnisse."
+      echo ""
+      echo "Verwendung: ./copy.sh [OPTIONEN] [--help]"
+      echo ""
+      echo "  --tag <suffix>   Kopiert den jeweiligen Tag-Stand statt den Branch-HEAD"
+      echo "  --local          Kopiert lokale Branch-HEADs ohne Remote-Aktualisierung"
+      echo "  --help           Diese Hilfe anzeigen"
+      echo ""
+      echo "Ohne --tag und ohne --local: Aktualisiert alle Branches zuerst auf Remote-Stand"
+      echo "(erfordert Remote-Zugriff und einheitliche Tags über alle Branches)."
+      exit 0 ;;
+    *) echo "Unbekannter Parameter: $1" >&2; exit 1 ;;
   esac
 done
 
-SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-
 RSYNC_OPTS=(
   rsync -av
   --delete
@@ -36,10 +44,8 @@ RSYNC_OPTS=(
   --exclude=gradle/wrapper/.gradle-version
   --exclude=branches.sh
   --exclude=lib.sh
-  --exclude=build.sh
   --exclude=copy.sh
   --exclude=diff.sh
-  --exclude=patch-nexus.sh
   --exclude=push.sh
   --exclude=reset.sh
 )
@@ -58,7 +64,7 @@ sync_to() {
 }
 
 if [ "$TAG_SUFFIX" = "" ] && ! $LOCAL; then
-  echo "Kein Tag-Suffix angegeben — prüfe einheitliche Tags vor der Aktualisierung auf Remote-Stände..."
+  echo "Kein --tag angegeben — prüfe einheitliche Tags vor der Aktualisierung auf Remote-Stände..."
   _common_suffixes=$(find_common_tag_suffixes) || {
     echo "  Alle Branches müssen einheitlich getagged sein, bevor auf Remote-Stände aktualisiert wird." >&2
     exit 1
@@ -115,9 +121,4 @@ for base in "$VORLAGEN" "$LIVECODING" "$MUSTERLOESUNGEN"; do
   done < <(find "$base" -mindepth 2 -maxdepth 2 -type d | sort)
 done
 
-if [ "$NEXUS_URL" != "" ]; then
-  echo -e "\nPatche Gradle-Setups für Nexus: $NEXUS_URL"
-  (cd "$VORLAGEN" && "$SCRIPT_DIR/patch-nexus.sh" "$NEXUS_URL")
-fi
-
 git checkout scripting
diff --git a/diff.sh b/diff.sh
index 6517ddf17061dd0894cc2c783d4882e206d88e23..8c22cc99a102e99652569f154f090f08473a6aea 100755 (executable)
--- a/diff.sh
+++ b/diff.sh
@@ -3,17 +3,51 @@ set -e
 
 source lib.sh
 
-# Kein Argument:      lokaler Branch gegen origin/<branch>
-# Ein Argument:       lokaler Branch gegen <branch>--<suffix>
-# Zwei Argumente:     <branch>--<suffix1> gegen <branch>--<suffix2>
+TAG=""
+FROM=""
+TO=""
+while [ $# -gt 0 ]; do
+  case "$1" in
+    --tag)
+      [ -n "$2" ] || { echo "Fehler: --tag erfordert einen Wert" >&2; exit 1; }
+      TAG="$2"; shift 2 ;;
+    --from)
+      [ -n "$2" ] || { echo "Fehler: --from erfordert einen Wert" >&2; exit 1; }
+      FROM="$2"; shift 2 ;;
+    --to)
+      [ -n "$2" ] || { echo "Fehler: --to erfordert einen Wert" >&2; exit 1; }
+      TO="$2"; shift 2 ;;
+    --help)
+      echo "Zeigt Diffs aller Branches an."
+      echo ""
+      echo "Verwendung: ./diff.sh [OPTIONEN] [--help]"
+      echo ""
+      echo "  Ohne Optionen:                     lokaler Branch gegen origin/<branch>"
+      echo "  --tag <suffix>                     lokaler Branch gegen <branch>--<suffix>"
+      echo "  --from <suffix1> --to <suffix2>    <branch>--<suffix1> gegen <branch>--<suffix2>"
+      echo "  --help                             Diese Hilfe anzeigen"
+      exit 0 ;;
+    *) echo "Unbekannter Parameter: $1" >&2; exit 1 ;;
+  esac
+done
+
+if [ -n "$FROM" ] && [ -z "$TO" ]; then
+  echo "Fehler: --from erfordert auch --to" >&2; exit 1
+fi
+if [ -n "$TO" ] && [ -z "$FROM" ]; then
+  echo "Fehler: --to erfordert auch --from" >&2; exit 1
+fi
+if [ -n "$TAG" ] && [ -n "$FROM" ]; then
+  echo "Fehler: --tag und --from/--to schließen sich aus" >&2; exit 1
+fi
 
 for branch in "${BRANCH_NAMES[@]}"; do
-  if [ "$1" != "" ] && [ "$2" != "" ]; then
-    echo -e "\nDiff ${branch}--${1} gegen ${branch}--${2}\n"
-    git diff "${branch}--${1}" "${branch}--${2}"
-  elif [ "$1" != "" ]; then
-    echo -e "\nDiff $branch gegen ${branch}--${1}\n"
-    git diff "${branch}--${1}" "$branch"
+  if [ -n "$FROM" ]; then
+    echo -e "\nDiff ${branch}--${FROM} gegen ${branch}--${TO}\n"
+    git diff "${branch}--${FROM}" "${branch}--${TO}"
+  elif [ -n "$TAG" ]; then
+    echo -e "\nDiff $branch gegen ${branch}--${TAG}\n"
+    git diff "${branch}--${TAG}" "$branch"
   else
     echo -e "\nDiff $branch gegen origin/$branch\n"
     git diff "origin/$branch" "$branch"
diff --git a/patch-nexus.sh b/patch-nexus.sh
deleted file mode 100755 (executable)
index 4a1a41b..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-#!/bin/bash
-set -e
-
-# Passt Gradle-Setups an einen internen Nexus-Mirror an.
-# Aufruf (aus dem Zielverzeichnis, z.B. ../vorlagen/):
-#
-#   patch-nexus.sh <nexus-maven-url> [--gradle-dist-url=<url>]
-#
-# Ohne --gradle-dist-url bleibt gradle-wrapper.properties unverändert.
-# Falls Gradle-Distributionen ebenfalls über Nexus bereitgestellt werden,
-# muss dort ein "raw proxy"-Repository auf services.gradle.org/distributions/
-# eingerichtet sein.
-
-if [ "$1" = "" ]; then
-  echo "Aufruf: $(basename "$0") <nexus-maven-url> [--gradle-dist-url=<url>]"
-  echo ""
-  echo "Beispiel:"
-  echo "  $(basename "$0") https://nexus.example.com/repository/maven-public/"
-  echo "  $(basename "$0") https://nexus.example.com/repository/maven-public/ \\"
-  echo "    --gradle-dist-url=https://nexus.example.com/repository/gradle-distributions/"
-  exit 1
-fi
-
-NEXUS_URL="$1"
-GRADLE_DIST_URL=""
-for arg in "${@:2}"; do
-  case "$arg" in
-    --gradle-dist-url=*) GRADLE_DIST_URL="${arg#--gradle-dist-url=}" ;;
-    *) echo "Unbekannter Parameter: $arg"; exit 1 ;;
-  esac
-done
-
-TMP_REPO_BLOCK=$(mktemp)
-TMP_PLUGIN_BLOCK=$(mktemp)
-
-cat > "$TMP_REPO_BLOCK" <<EOF
-  maven {
-      url '$NEXUS_URL'
-  }
-  maven {
-      name 'gradle plugins'
-      url 'https://plugins.gradle.org/m2/'
-  }
-EOF
-
-cat > "$TMP_PLUGIN_BLOCK" <<EOF
-pluginManagement {
-  repositories {
-    maven {
-      name 'Nexus-Internal Access'
-      url '$NEXUS_URL'
-    }
-  }
-}
-
-EOF
-
-echo "Bearbeite build.gradle-Dateien..."
-for file in */*/build.gradle; do
-  [ -f "$file" ] || continue
-  echo "  $file"
-  sed -i '/mavenCentral()/d' "$file"
-  if grep -q 'repositories *{' "$file"; then
-    awk -v insert="$(cat "$TMP_REPO_BLOCK")" '
-      BEGIN { added=0 }
-      /repositories[[:space:]]*{/ {
-        print
-        if (!added) { print insert; added=1; next }
-      }
-      { print }
-    ' "$file" > "$file.tmp" && mv "$file.tmp" "$file"
-  else
-    cat "$TMP_REPO_BLOCK" "$file" > "$file.tmp" && mv "$file.tmp" "$file"
-  fi
-done
-
-echo "Bearbeite settings.gradle-Dateien..."
-for file in */*/settings.gradle; do
-  [ -f "$file" ] || continue
-  echo "  $file"
-  if ! grep -q 'pluginManagement' "$file"; then
-    cat "$TMP_PLUGIN_BLOCK" "$file" > "$file.tmp" && mv "$file.tmp" "$file"
-  else
-    echo "    (pluginManagement bereits vorhanden -- uebersprungen)"
-  fi
-done
-
-if [ "$GRADLE_DIST_URL" != "" ]; then
-  echo "Bearbeite gradle-wrapper.properties-Dateien..."
-  for file in */*/gradle/wrapper/gradle-wrapper.properties; do
-    [ -f "$file" ] || continue
-    echo "  $file"
-    # In .properties-Dateien muss ':' als '\:' escaped werden; awk erledigt das sauber
-    awk -v url="$GRADLE_DIST_URL" '
-      BEGIN { gsub(/:/, "\\:", url) }
-      /^distributionUrl=/ { print "distributionUrl=" url; next }
-      { print }
-    ' "$file" > "$file.tmp" && mv "$file.tmp" "$file"
-  done
-fi
-
-rm -f "$TMP_REPO_BLOCK" "$TMP_PLUGIN_BLOCK"
-echo "Fertig."
diff --git a/push.sh b/push.sh
index d289c49c96cf171fc0364c827952a7cee3ebbd71..6d6dd80b2785258af86fefb766b46f9d33d9aff6 100755 (executable)
--- a/push.sh
+++ b/push.sh
@@ -3,6 +3,24 @@ set -e
 
 source lib.sh
 
+for arg in "$@"; do
+  case "$arg" in
+    --help)
+      echo "Force-pusht alle Branches zu origin."
+      echo "Prüft vorab, ob umzuschreibende Remote-Stände bereits gesichert sind;"
+      echo "fehlt ein Tag, werden TIMESTAMP-Backup-Tags für alle Remote-Stände im Remote angelegt."
+      echo "Gemeinsame lokale Tag-Suffixe (z.B. --claude-5 für alle Branches) werden ebenfalls gepusht,"
+      echo "sofern noch nicht im Remote vorhanden."
+      echo ""
+      echo "Verwendung: ./push.sh [--help]"
+      echo ""
+      echo "  --help   Diese Hilfe anzeigen"
+      exit 0
+      ;;
+    *) echo "Unbekannter Parameter: $arg" >&2; exit 1 ;;
+  esac
+done
+
 # Fetch remote tags once to avoid repeated network calls
 remote_tags=$(git ls-remote --tags origin)
 
index 0ad86566d113302b92c8203ce5d6b087b7158823..98f6daddc4680eed8aedeab32c6c2e582f0f6cc6 100755 (executable)
--- a/reset.sh
+++ b/reset.sh
@@ -3,14 +3,33 @@ set -e
 
 source lib.sh
 
-if [ "$1" = "" ]; then
-  echo "No Tag-Prefix specified: Resetting to remote branches"
+TAG=""
+while [ $# -gt 0 ]; do
+  case "$1" in
+    --tag)
+      [ -n "$2" ] || { echo "Fehler: --tag erfordert einen Wert" >&2; exit 1; }
+      TAG="$2"; shift 2 ;;
+    --help)
+      echo "Setzt alle Branches zurück."
+      echo ""
+      echo "Verwendung: ./reset.sh [--tag <suffix>] [--help]"
+      echo ""
+      echo "  --tag <suffix>   Setzt alle Branches auf <branch>--<suffix> zurück"
+      echo "                   Ohne --tag: Setzt auf origin/<branch> zurück (erfordert Remote-Zugriff)"
+      echo "  --help           Diese Hilfe anzeigen"
+      exit 0 ;;
+    *) echo "Unbekannter Parameter: $1" >&2; exit 1 ;;
+  esac
+done
+
+if [ -z "$TAG" ]; then
+  echo "Kein --tag angegeben: Setze alle Branches auf Remote-Stand zurück"
   reset_branches_to_remote
 else
   for branch in "${BRANCH_NAMES[@]}"; do
-    echo -e "\nResetting $branch to ${branch}--$1"
+    echo -e "\nResetting $branch to ${branch}--${TAG}"
     git checkout "$branch"
-    git reset --hard "${branch}--$1"
+    git reset --hard "${branch}--${TAG}"
   done
   git checkout scripting
 fi