#!/bin/bash # # Git-Helper für Ubuntu Touch Entwicklung # Version: 1.7 # Autor: darklithium # # Zweck: Narrensicheres Git für Entwickler # - Einfache Befehle für häufige Git-Operationen # - Automatische Branch-Naming # - Konsistente Workflows # # Verwendung: # ./git-helper.sh [argumente] # # Beispiele: # ./git-helper.sh status # ./git-helper.sh new-feature login-system # ./git-helper.sh merge-stable # --- KONFIGURATION --- REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) if [[ -z "$REPO_ROOT" ]]; then echo "❌ Nicht in einem Git-Repository!" echo " → cd /pfad/zu/deinem/git/repo" exit 1 fi CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | sed 's/refs\/heads\///') MAINTAINER="darklithium " # Farben RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # --- FUNKTIONEN --- # Hilfstext anzeigen show_help() { cat << EOF 📖 Git-Helper v1.7 - Hilfstext Verfügbare Befehle: 📊 STATUS & INFO status Zeigt Git-Status an branches Liste alle Branches log Zeigt Commit-Historie diff Zeigt unstaged Änderungen diff-staged Zeigt staged Änderungen 🌿 BRANCHES new-feature Erstellt Feature-Branch (Basis: testing) new-bugfix Erstellt Bugfix-Branch (Basis: testing) new-hotfix Erstellt Hotfix-Branch (Basis: stable) switch Wechselt zu Branch delete Löscht Branch (lokal) 🔄 MERGE & REBASE merge-stable Merged testing → stable merge-testing Merged feature/* → testing rebase-testing Rebase aktuellen Branch auf testing 📤 PUSH & PULL push Pushed aktuellen Branch pull Pullt Änderungen push-all Pushed alle Branches fetch Fetched alle Remote-Branches 🏷️ TAGS tag Erstellt Tag (z. B. v1.0.0) tag-push Pushed Tag zum Remote tags Liste alle Tags 📝 COMMITS commit Erstellt Commit mit Message amend Ändert letzten Commit revert Revertet einen Commit 🧹 AUFRÄUMEN cleanup Löscht gemergte Branches cleanup-all Löscht alle lokalen Branches außer stable/testing 📋 REVIEW review Zeigt Commits zur Review review-last Zeigt letzten Commit detailliert ❓ HILFE help Zeigt diesen Hilfstext version Zeigt Version Beispiele: ./git-helper.sh new-feature login-system ./git-helper.sh switch testing ./git-helper.sh merge-stable ./git-helper.sh push EOF } # Zeigt aktuellen Status cmd_status() { echo "" echo -e "${BLUE}=== Git-Status ===${NC}" echo "" echo -e "${YELLOW}Repository:${NC} $REPO_ROOT" echo -e "${YELLOW}Aktueller Branch:${NC} $CURRENT_BRANCH" echo "" # Branch-Status if [[ "$CURRENT_BRANCH" == "stable" || "$CURRENT_BRANCH" == "testing" ]]; then echo -e "${GREEN}✅ Haupt-Branch${NC}" elif [[ "$CURRENT_BRANCH" =~ ^feature/ ]]; then echo -e "${BLUE}📌 Feature-Branch${NC}" elif [[ "$CURRENT_BRANCH" =~ ^bugfix/ ]]; then echo -e "${RED}🐛 Bugfix-Branch${NC}" elif [[ "$CURRENT_BRANCH" =~ ^hotfix/ ]]; then echo -e "${RED}🚨 Hotfix-Branch${NC}" else echo -e "${YELLOW}⚠️ Unbekannter Branch-Typ${NC}" fi echo "" echo -e "${YELLOW}Änderungen:${NC}" git status --short echo "" echo -e "${YELLOW}Remote-Status:${NC}" git remote -v echo "" } # Liste alle Branches cmd_branches() { echo "" echo -e "${BLUE}=== Alle Branches ===${NC}" echo "" echo -e "${GREEN}🟢 Haupt-Branches:${NC}" git branch | grep -E '^\*?\s*(stable|testing|main|master)$' | sed 's/^[ *]//' echo "" echo -e "${BLUE}📌 Feature-Branches:${NC}" git branch | grep -E '^\*?\s*feature/' | sed 's/^[ *]//' echo "" echo -e "${RED}🐛 Bugfix-Branches:${NC}" git branch | grep -E '^\*?\s*bugfix/' | sed 's/^[ *]//' echo "" echo -e "${RED}🚨 Hotfix-Branches:${NC}" git branch | grep -E '^\*?\s*hotfix/' | sed 's/^[ *]//' } # Zeigt Commit-Historie cmd_log() { echo "" echo -e "${BLUE}=== Commit-Historie ===${NC}" echo "" git log --oneline --graph --all -20 echo "" } # Zeigt unstaged Änderungen cmd_diff() { echo "" echo -e "${BLUE}=== Unstaged Änderungen ===${NC}" echo "" git diff } # Zeigt staged Änderungen cmd_diff_staged() { echo "" echo -e "${BLUE}=== Staged Änderungen ===${NC}" echo "" git diff --cached } # Erstellt Feature-Branch cmd_new_feature() { local branch_name="feature/$1" if [[ -z "$1" ]]; then echo -e "${RED}❌ Fehlender Branch-Name!${NC}" echo " → ./git-helper.sh new-feature " exit 1 fi # Prüfe ob Branch schon existiert if git show-ref --verify --quiet refs/heads/"$branch_name"; then echo -e "${RED}❌ Branch '$branch_name' existiert bereits!${NC}" exit 1 fi # Basis-Branch prüfen (sollte testing sein) if git show-ref --verify --quiet refs/heads/testing; then BASE_BRANCH="testing" elif git show-ref --verify --quiet refs/heads/stable; then BASE_BRANCH="stable" echo -e "${YELLOW}⚠️ testing-Branch nicht gefunden, verwende stable${NC}" else echo -e "${RED}❌ Basis-Branch (testing oder stable) nicht gefunden!${NC}" exit 1 fi # Branch erstellen und wechseln git checkout -b "$branch_name" "$BASE_BRANCH" echo -e "${GREEN}✅ Feature-Branch '$branch_name' erstellt (Basis: $BASE_BRANCH)${NC}" echo " → git push --set-upstream origin $branch_name" } # Erstellt Bugfix-Branch cmd_new_bugfix() { local branch_name="bugfix/$1" if [[ -z "$1" ]]; then echo -e "${RED}❌ Fehlender Branch-Name!${NC}" echo " → ./git-helper.sh new-bugfix " exit 1 fi # Prüfe ob Branch schon existiert if git show-ref --verify --quiet refs/heads/"$branch_name"; then echo -e "${RED}❌ Branch '$branch_name' existiert bereits!${NC}" exit 1 fi # Basis-Branch prüfen if git show-ref --verify --quiet refs/heads/testing; then BASE_BRANCH="testing" elif git show-ref --verify --quiet refs/heads/stable; then BASE_BRANCH="stable" echo -e "${YELLOW}⚠️ testing-Branch nicht gefunden, verwende stable${NC}" else echo -e "${RED}❌ Basis-Branch (testing oder stable) nicht gefunden!${NC}" exit 1 fi git checkout -b "$branch_name" "$BASE_BRANCH" echo -e "${GREEN}✅ Bugfix-Branch '$branch_name' erstellt (Basis: $BASE_BRANCH)${NC}" echo " → git push --set-upstream origin $branch_name" } # Erstellt Hotfix-Branch cmd_new_hotfix() { local branch_name="hotfix/$1" if [[ -z "$1" ]]; then echo -e "${RED}❌ Fehlender Branch-Name!${NC}" echo " → ./git-helper.sh new-hotfix " exit 1 fi # Prüfe ob Branch schon existiert if git show-ref --verify --quiet refs/heads/"$branch_name"; then echo -e "${RED}❌ Branch '$branch_name' existiert bereits!${NC}" exit 1 fi # Hotfix muss von stable kommen if ! git show-ref --verify --quiet refs/heads/stable; then echo -e "${RED}❌ stable-Branch nicht gefunden!${NC}" echo " → Hotfix-Branches müssen von stable ausgehen" exit 1 fi git checkout -b "$branch_name" stable echo -e "${GREEN}✅ Hotfix-Branch '$branch_name' erstellt (Basis: stable)${NC}" echo " → git push --set-upstream origin $branch_name" } # Wechselt Branch cmd_switch() { if [[ -z "$1" ]]; then echo -e "${RED}❌ Fehlender Branch-Name!${NC}" echo " → ./git-helper.sh switch " exit 1 fi # Branch-Namen validieren case "$1" in stable|testing|feature/*|bugfix/*|hotfix/*|release/*) git checkout "$1" echo -e "${GREEN}✅ Zu Branch '$1' gewechselt${NC}" ;; *) echo -e "${RED}❌ Ungültiger Branch-Name: '$1'${NC}" echo " → Erlaubt: stable, testing, feature/*, bugfix/*, hotfix/*" exit 1 ;; esac } # Löscht Branch cmd_delete() { if [[ -z "$1" ]]; then echo -e "${RED}❌ Fehlender Branch-Name!${NC}" echo " → ./git-helper.sh delete " exit 1 fi # Nicht stable oder testing löschen if [[ "$1" == "stable" || "$1" == "testing" ]]; then echo -e "${RED}❌ Cannot delete main branches (stable/testing)!${NC}" exit 1 fi # Prüfe ob Branch existiert if ! git show-ref --verify --quiet refs/heads/"$1"; then echo -e "${RED}❌ Branch '$1' existiert nicht!${NC}" exit 1 fi # Prüfe ob Branch aktuell aktiv ist if [[ "$1" == "$CURRENT_BRANCH" ]]; then echo -e "${RED}❌ Kann aktiven Branch nicht löschen!${NC}" echo " → Wechsle zuerst zu einem anderen Branch" exit 1 fi git branch -D "$1" echo -e "${GREEN}✅ Branch '$1' gelöscht (lokal)${NC}" } # Merged testing → stable cmd_merge_stable() { # Prüfe ob auf stable Branch if [[ "$CURRENT_BRANCH" != "stable" ]]; then echo -e "${RED}❌ Nicht auf stable-Branch!${NC}" echo " → git checkout stable" exit 1 fi # Prüfe ob testing existiert if ! git show-ref --verify --quiet refs/heads/testing; then echo -e "${RED}❌ testing-Branch existiert nicht!${NC}" exit 1 fi echo -e "${YELLOW}🔍 Prüfe ob testing in stable gemerged ist...${NC}" if git merge --no-commit --no-ff testing 2>/dev/null; then echo -e "${GREEN}✅ testing kann in stable gemerged werden${NC}" git merge --no-ff testing -m "merge: testing → stable" echo "" echo -e "${GREEN}✅ testing erfolgreich in stable gemerged!${NC}" echo " → git push origin stable" echo " → git push origin testing" else echo -e "${RED}❌ Merge-Konflikte!${NC}" echo " → Konflikte manuell lösen und dann:" echo " → git commit" echo " → git merge --continue" exit 1 fi } # Merged feature/* → testing cmd_merge_testing() { # Prüfe ob auf testing Branch if [[ "$CURRENT_BRANCH" != "testing" ]]; then echo -e "${RED}❌ Nicht auf testing-Branch!${NC}" echo " → git checkout testing" exit 1 fi # Zeige alle Feature-Branches echo -e "${YELLOW}Verfügbare Feature-Branches:${NC}" git branch | grep -E '^\s*feature/' | sed 's/^[ *]//' | sed 's/feature\///' echo "" # Branch-Namen abfragen read -p "Welchen Feature-Branch möchtest du mergen? (Name ohne 'feature/')? " branch_name FULL_BRANCH="feature/$branch_name" # Prüfe ob Branch existiert if ! git show-ref --verify --quiet refs/heads/"$FULL_BRANCH"; then echo -e "${RED}❌ Branch '$FULL_BRANCH' existiert nicht!${NC}" exit 1 fi echo -e "${YELLOW}🔍 Prüfe ob $FULL_BRANCH in testing gemerged ist...${NC}" if git merge --no-commit --no-ff "$FULL_BRANCH" 2>/dev/null; then echo -e "${GREEN}✅ $FULL_BRANCH kann in testing gemerged werden${NC}" git merge --no-ff "$FULL_BRANCH" -m "merge: $FULL_BRANCH → testing" echo "" echo -e "${GREEN}✅ $FULL_BRANCH erfolgreich in testing gemerged!${NC}" echo " → git push origin testing" else echo -e "${RED}❌ Merge-Konflikte!${NC}" echo " → Konflikte manuell lösen und dann:" echo " → git commit" echo " → git merge --continue" exit 1 fi } # Rebase auf testing cmd_rebase_testing() { if ! git show-ref --verify --quiet refs/heads/testing; then echo -e "${RED}❌ testing-Branch existiert nicht!${NC}" exit 1 fi echo -e "${YELLOW}🔍 Rebase $CURRENT_BRANCH auf testing...${NC}" if git rebase testing; then echo -e "${GREEN}✅ $CURRENT_BRANCH auf testing gerebased!${NC}" echo " → git push --force-with-lease" else echo -e "${RED}❌ Rebase-Konflikte!${NC}" echo " → Konflikte lösen mit:" echo " → git rebase --continue (wenn gelöst)" echo " → git rebase --abort (zum Abbrechen)" exit 1 fi } # Push cmd_push() { if [[ -z "$1" ]]; then # Push aktuellen Branch git push echo -e "${GREEN}✅ $CURRENT_BRANCH gepusht${NC}" else git push origin "$1" echo -e "${GREEN}✅ Branch '$1' gepusht${NC}" fi } # Pull cmd_pull() { git pull echo -e "${GREEN}✅ Änderungen gepullt${NC}" } # Push alle Branches cmd_push_all() { git push --all echo -e "${GREEN}✅ Alle Branches gepusht${NC}" } # Fetch cmd_fetch() { git fetch --all echo -e "${GREEN}✅ Alle Remote-Branches gefetched${NC}" } # Erstellt Tag cmd_tag() { if [[ -z "$1" ]]; then echo -e "${RED}❌ Fehlende Versionsnummer!${NC}" echo " → ./git-helper.sh tag v1.0.0" exit 1 fi # Prüfe Format (sollte wie v1.0.0 aussehen) if ! [[ "$1" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo -e "${YELLOW}⚠️ Tag-Format sollte vMAJOR.MINOR.PATCH sein (z. B. v1.0.0)${NC}" read -p "Fortfahren mit '$1'? (j/n): " -n 1 -r echo if [[ ! $REPLY =~ ^[JjYy]$ ]]; then exit 1 fi fi git tag -a "$1" -m "Release $1" echo -e "${GREEN}✅ Tag '$1' erstellt${NC}" echo " → git-helper.sh tag-push $1" } # Pushed Tag cmd_tag_push() { if [[ -z "$1" ]]; then echo -e "${RED}❌ Fehlender Tag-Name!${NC}" echo " → ./git-helper.sh tag-push v1.0.0" exit 1 fi git push origin "$1" echo -e "${GREEN}✅ Tag '$1' gepusht${NC}" } # Liste alle Tags cmd_tags() { echo "" echo -e "${BLUE}=== Alle Tags ===${NC}" echo "" git tag -l } # Erstellt Commit cmd_commit() { if [[ -z "$1" ]]; then echo -e "${RED}❌ Fehlende Commit-Message!${NC}" echo " → ./git-helper.sh commit 'feat: neue Funktion'" exit 1 fi # Prüfe Format (sollte Typ: Beschreibung sein) if ! [[ "$1" =~ ^[a-z]+:\ .+ ]]; then echo -e "${YELLOW}⚠️ Commit-Message sollte Format : haben${NC}" echo " Beispiel: feat: neue Funktion" echo "" read -p "Fortfahren mit '$1'? (j/n): " -n 1 -r echo if [[ ! $REPLY =~ ^[JjYy]$ ]]; then exit 1 fi fi git commit -m "$1" echo -e "${GREEN}✅ Commit erstellt: $1${NC}" } # Ändert letzten Commit cmd_amend() { if [[ -z "$1" ]]; then git commit --amend --no-edit echo -e "${GREEN}✅ Letzter Commit geändert (gleiche Message)${NC}" else git commit --amend -m "$1" echo -e "${GREEN}✅ Letzter Commit geändert: $1${NC}" fi } # Revertet Commit cmd_revert() { if [[ -z "$1" ]]; then echo -e "${RED}❌ Fehlende Commit-ID!${NC}" echo " → ./git-helper.sh revert " exit 1 fi git revert "$1" echo -e "${GREEN}✅ Commit $1 revertet${NC}" } # Löscht gemergte Branches cmd_cleanup() { echo -e "${YELLOW}🔍 Suche gemergte Branches...${NC}" # Alle Branches außer stable und testing MERGED_BRANCHES=$(git branch --merged stable | grep -v -E '^\*?\s*(stable|testing|main|master)$' | sed 's/^[ *]//' | sed 's/^[[:space:]]*//') if [[ -z "$MERGED_BRANCHES" ]]; then echo -e "${GREEN}✅ Keine gemergten Branches zum Löschen gefunden${NC}" exit 0 fi echo -e "${YELLOW}Gemergte Branches:${NC}" echo "$MERGED_BRANCHES" echo "" read -p "Alle gemergten Branches löschen? (j/n): " -n 1 -r echo if [[ $REPLY =~ ^[JjYy]$ ]]; then for branch in $MERGED_BRANCHES; do git branch -D "$branch" echo -e "${GREEN}✅ Gelöscht: $branch${NC}" done echo -e "${GREEN}✅ Alle gemergten Branches gelöscht${NC}" else echo -e "${YELLOW}❌ Abgebrochen${NC}" fi } # Löscht alle lokalen Branches außer stable/testing cmd_cleanup_all() { echo -e "${RED}⚠️ WARNING: Dies löscht ALLE lokalen Branches außer stable und testing!${NC}" echo "" read -p "Fortfahren? (j/n): " -n 1 -r echo if [[ ! $REPLY =~ ^[JjYy]$ ]]; then echo -e "${YELLOW}❌ Abgebrochen${NC}" exit 0 fi # Alle Branches außer stable und testing ALL_BRANCHES=$(git branch | grep -v -E '^\*?\s*(stable|testing|main|master)$' | sed 's/^[ *]//' | sed 's/^[[:space:]]*//') if [[ -z "$ALL_BRANCHES" ]]; then echo -e "${GREEN}✅ Keine zusätzlichen Branches gefunden${NC}" exit 0 fi for branch in $ALL_BRANCHES; do git branch -D "$branch" echo -e "${GREEN}✅ Gelöscht: $branch${NC}" done echo -e "${GREEN}✅ Alle lokalen Branches (außer stable/testing) gelöscht${NC}" } # Zeigt Commits zur Review cmd_review() { echo "" echo -e "${BLUE}=== Commits zur Review (nicht gepusht) ===${NC}" echo "" git log --oneline origin/$CURRENT_BRANCH..$CURRENT_BRANCH echo "" if [[ $? -eq 0 && -n "$(git log --oneline origin/$CURRENT_BRANCH..$CURRENT_BRANCH 2>/dev/null)" ]]; then echo -e "${YELLOW}📝 Tipp: Nutze diese Commits für Code-Review${NC}" fi } # Zeigt letzten Commit detailliert cmd_review_last() { echo "" echo -e "${BLUE}=== Letzter Commit ===${NC}" echo "" git show HEAD --stat echo "" } # Zeigt Version cmd_version() { echo "Git-Helper v1.7" echo "Framework: START-UT-DEV 1.7" echo "Maintainer: darklithium " echo "Stand: 30.05.2026" } # --- HAUPTPROGRAMM --- # Keine Argumente → Hilfe anzeigen if [[ $# -eq 0 ]]; then show_help exit 0 fi # Command Dispatch COMMAND="$1" shift case "$COMMAND" in status) cmd_status ;; branches) cmd_branches ;; log) cmd_log ;; diff) cmd_diff ;; diff-staged) cmd_diff_staged ;; new-feature) cmd_new_feature "$1" ;; new-bugfix) cmd_new_bugfix "$1" ;; new-hotfix) cmd_new_hotfix "$1" ;; switch) cmd_switch "$1" ;; delete) cmd_delete "$1" ;; merge-stable) cmd_merge_stable ;; merge-testing) cmd_merge_testing ;; rebase-testing) cmd_rebase_testing ;; push) cmd_push "$1" ;; pull) cmd_pull ;; push-all) cmd_push_all ;; fetch) cmd_fetch ;; tag) cmd_tag "$1" ;; tag-push) cmd_tag_push "$1" ;; tags) cmd_tags ;; commit) cmd_commit "$*" ;; amend) cmd_amend "$*" ;; revert) cmd_revert "$1" ;; cleanup) cmd_cleanup ;; cleanup-all) cmd_cleanup_all ;; review) cmd_review ;; review-last) cmd_review_last ;; help) show_help ;; version) cmd_version ;; *) echo -e "${RED}❌ Unbekannter Befehl: $COMMAND${NC}" echo "" show_help exit 1 ;; esac