## Skripte im Scripting-Branch
-Alle Skripte laden zuerst `branches.sh`, das die vollständige Branch-Liste definiert.
+Alle Skripte binden `lib.sh` ein, das seinerseits `branches.sh` lädt und gemeinsame Funktionen bereitstellt.
| 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>` |
- `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).
-- Der `grundlagen/docker`-Branch ist nicht in `$BRANCHES`, wird aber in mehreren Skripten explizit behandelt (`push.sh`, `diff.sh`, `reset.sh`).
+- 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.
#!/bin/bash
set -e
-source branches.sh
+source lib.sh
# Ohne --publish: nur bauen (kein Docker-Image veröffentlichen)
# Mit --publish: bauen und Docker-Image in die Registry schieben
LIVECODING=../training-exercises/livecoding
MUSTERLOESUNGEN=../training-exercises/spickzettel
-source branches.sh
+source lib.sh
# --tag=<suffix>: Kopiert den jeweiligen Tag-Stand statt den aktuellen Branch-HEAD
# --local: Kopiert lokale Branch-HEADs ohne Remote-Aktualisierung
--exclude=gradle/wrapper/gradle-wrapper.jar
--exclude=gradle/wrapper/.gradle-version
--exclude=branches.sh
+ --exclude=lib.sh
--exclude=build.sh
--exclude=copy.sh
--exclude=diff.sh
if [ "$TAG_SUFFIX" = "" ] && ! $LOCAL; then
echo "Kein Tag-Suffix angegeben — prüfe einheitliche Tags vor der Aktualisierung auf Remote-Stände..."
-
- _common_suffixes=""
- for i in grundlagen__docker $BRANCHES; do
- declare -n _bref=$i
- _suffixes=$(git tag -l "${_bref}--*" | sed "s|^${_bref}--||" | sort)
- if [ -z "$_suffixes" ]; then
- echo "Fehler: Branch '$_bref' hat keine Tags." >&2
- echo " Alle Branches müssen einheitlich getagged sein, bevor auf Remote-Stände aktualisiert wird." >&2
- exit 1
- fi
- if [ -z "$_common_suffixes" ]; then
- _common_suffixes="$_suffixes"
- else
- _common_suffixes=$(comm -12 <(echo "$_common_suffixes") <(echo "$_suffixes"))
- if [ -z "$_common_suffixes" ]; then
- echo "Fehler: Branch '$_bref' hat kein gemeinsames Tag mit allen vorhergehenden Branches." >&2
- echo " Alle Branches müssen einheitlich getagged sein, bevor auf Remote-Stände aktualisiert wird." >&2
- exit 1
- fi
- fi
- done
+ _common_suffixes=$(find_common_tag_suffixes) || {
+ echo " Alle Branches müssen einheitlich getagged sein, bevor auf Remote-Stände aktualisiert wird." >&2
+ exit 1
+ }
+ if [ -z "$_common_suffixes" ]; then
+ echo "Fehler: Kein gemeinsames Tag für alle Branches gefunden." >&2
+ echo " Alle Branches müssen einheitlich getagged sein, bevor auf Remote-Stände aktualisiert wird." >&2
+ exit 1
+ fi
echo "Einheitliche Tags vorhanden: $(echo "$_common_suffixes" | tr '\n' ' ')"
echo "Aktualisiere alle Branches auf Remote-Stand..."
git fetch origin
- for i in grundlagen__docker $BRANCHES; do
- declare -n _bref=$i
- git checkout "$_bref"
- git reset --hard "origin/$_bref"
- done
- git checkout scripting
+ reset_branches_to_remote
fi
EXPECTED=$(mktemp)
#!/bin/bash
set -e
-source branches.sh
+source lib.sh
# Kein Argument: lokaler Branch gegen origin/<branch>
# Ein Argument: lokaler Branch gegen <branch>--<suffix>
# Zwei Argumente: <branch>--<suffix1> gegen <branch>--<suffix2>
-for i in grundlagen__docker $BRANCHES; do
- declare -n branch=${i}
+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}"
--- /dev/null
+#!/bin/bash
+# Gemeinsame Hilfsfunktionen für alle Verwaltungsskripte.
+# Bindet branches.sh ein und stellt $BRANCH_NAMES sowie Hilfsfunktionen bereit.
+
+source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/branches.sh"
+
+# Array aller Branch-Namen als Strings (inkl. grundlagen/docker)
+BRANCH_NAMES=()
+for _i in grundlagen__docker $BRANCHES; do
+ declare -n _b=$_i
+ BRANCH_NAMES+=("$_b")
+ unset -n _b
+done
+
+# Gibt gemeinsame Tag-Suffixe aller Branches auf stdout aus (einen pro Zeile).
+# Schlägt mit Fehler fehl, wenn ein Branch keine Tags hat.
+# Gibt leere Ausgabe zurück, wenn kein gemeinsames Suffix existiert.
+find_common_tag_suffixes() {
+ local common="" branch suffixes
+ for branch in "${BRANCH_NAMES[@]}"; do
+ suffixes=$(git tag -l "${branch}--*" | sed "s|^${branch}--||" | sort)
+ if [ -z "$suffixes" ]; then
+ echo "Fehler: Branch '$branch' hat keine Tags." >&2
+ return 1
+ fi
+ if [ -z "$common" ]; then
+ common="$suffixes"
+ else
+ common=$(comm -12 <(echo "$common") <(echo "$suffixes"))
+ fi
+ done
+ [ -n "$common" ] && echo "$common"
+ return 0
+}
+
+# Setzt alle Branches auf origin/<branch> zurück.
+# Erwartet, dass origin aktuell ist — ggf. vorher git fetch origin aufrufen.
+# Kehrt am Ende zu scripting zurück.
+reset_branches_to_remote() {
+ local branch
+ for branch in "${BRANCH_NAMES[@]}"; do
+ echo -e "\nResetting $branch to origin/$branch"
+ git checkout "$branch"
+ git reset --hard "origin/$branch"
+ done
+ git checkout scripting
+}
#!/bin/bash
set -e
-source branches.sh
-
-# Build list of all branch names
-BRANCH_LIST=()
-for i in grundlagen__docker $BRANCHES; do
- declare -n _b=${i}
- BRANCH_LIST+=("$_b")
-done
+source lib.sh
# Fetch remote tags once to avoid repeated network calls
remote_tags=$(git ls-remote --tags origin)
# Step 1: Check if any branch would be rewritten (not just extended) and has no remote tag
need_timestamp_backup=false
-for branch in "${BRANCH_LIST[@]}"; do
+for branch in "${BRANCH_NAMES[@]}"; do
remote_commit=$(git rev-parse "refs/remotes/origin/$branch" 2>/dev/null) || continue
git rev-parse --verify "$branch" &>/dev/null || continue
# Skip if remote would only be extended (fast-forward)
if [ "$need_timestamp_backup" = true ]; then
TIMESTAMP=$(date +%Y%m%d%H%M%S)
echo -e "\nCreating backup tags with timestamp $TIMESTAMP in remote..."
- for branch in "${BRANCH_LIST[@]}"; do
+ for branch in "${BRANCH_NAMES[@]}"; do
remote_commit=$(git rev-parse "refs/remotes/origin/$branch" 2>/dev/null) || continue
tag_name="${branch}--${TIMESTAMP}"
echo " Tagging $branch -> $tag_name"
fi
# Step 3: Find common local tag suffixes (suffix S where every branch B has local tag B--S)
-common_suffixes=()
-first_branch="${BRANCH_LIST[0]}"
-while IFS= read -r tag; do
- prefix="${first_branch}--"
- [[ "$tag" == "$prefix"* ]] || continue
- suffix="${tag#$prefix}"
- all_have=true
- for branch in "${BRANCH_LIST[@]}"; do
- if ! git rev-parse --verify "${branch}--${suffix}" &>/dev/null; then
- all_have=false
- break
- fi
- done
- if [ "$all_have" = true ]; then
- common_suffixes+=("$suffix")
- fi
-done < <(git tag)
+mapfile -t common_suffixes < <(find_common_tag_suffixes 2>/dev/null || true)
# Step 4: Push all branches
-for branch in "${BRANCH_LIST[@]}"; do
+for branch in "${BRANCH_NAMES[@]}"; do
echo -e "\nPushing $branch over origin/$branch"
git push --force origin "$branch:$branch"
done
if [ ${#common_suffixes[@]} -gt 0 ]; then
echo ""
for suffix in "${common_suffixes[@]}"; do
- for branch in "${BRANCH_LIST[@]}"; do
+ for branch in "${BRANCH_NAMES[@]}"; do
tag_name="${branch}--${suffix}"
if ! echo "$remote_tags" | grep -qF "refs/tags/${tag_name}"; then
echo "Pushing tag: $tag_name"
#!/bin/bash
set -e
-source branches.sh
+source lib.sh
-[ "$1" = "" ] && echo "No Tag-Prefix specified: Resetting to remote branches"
-
-for i in grundlagen__docker $BRANCHES; do
- declare -n branch=${i}
- if [ "$1" = "" ]; then
- ref="origin/$branch"
- else
- ref="${branch}--$1"
- fi
- echo -e "\nResetting $branch to $ref"
- git checkout "$branch"
- git reset --hard "$ref"
-done
-
-git checkout scripting
+if [ "$1" = "" ]; then
+ echo "No Tag-Prefix specified: Resetting to remote branches"
+ reset_branches_to_remote
+else
+ for branch in "${BRANCH_NAMES[@]}"; do
+ echo -e "\nResetting $branch to ${branch}--$1"
+ git checkout "$branch"
+ git reset --hard "${branch}--$1"
+ done
+ git checkout scripting
+fi