IT-Wissen/git/README.md
Roger Rutishauser b1e3a10586 update README
2026-02-10 09:07:24 +01:00

1154 lines
22 KiB
Markdown

---
gitea: none
include_toc: true
---
# Git
## Grundlagen
### Repository initialisieren
Ein neues Git-Repository erstellen:
```bash
git init
```
Oder ein bestehendes Repository klonen:
```bash
git clone <repository-url>
# Beispiel mit HTTPS
git clone https://github.com/user/repository.git
# Beispiel mit SSH
git clone git@github.com:user/repository.git
# Mit spezifischem Verzeichnisnamen
git clone <repository-url> <verzeichnisname>
```
### Git Konfiguration
Grundlegende Konfiguration nach der Installation:
```bash
# Benutzername global setzen
git config --global user.name "Dein Name"
# E-Mail global setzen
git config --global user.email "deine.email@example.com"
# Standard-Editor festlegen
git config --global core.editor "code --wait" # für VS Code
# Aktuelle Konfiguration anzeigen
git config --list
# Nur lokale Konfiguration (für aktuelles Repo)
git config user.name "Anderer Name"
# Spezifischen Wert abfragen
git config user.email
```
### Remote Repositories verwalten
```bash
# Remote-Repositories anzeigen
git remote -v
# Neues Remote-Repository hinzufügen
git remote add <name> <url>
git remote add origin https://github.com/user/repo.git
# Remote-URL ändern
git remote set-url origin <neue-url>
# Remote-Repository entfernen
git remote remove <name>
# Remote-Repository umbenennen
git remote rename <alter-name> <neuer-name>
```
## Dateien hinzufügen und committen
### Staging Area
```bash
# Einzelne Datei zur Staging Area hinzufügen
git add dateiname.txt
# Alle geänderten Dateien hinzufügen
git add .
# Alle Dateien eines bestimmten Typs hinzufügen
git add *.js
# Interaktives Staging (wähle aus, was gestaged werden soll)
git add -p
# Dateien aus der Staging Area entfernen (unstage)
git reset HEAD dateiname.txt
# oder mit neuerer Git-Version
git restore --staged dateiname.txt
```
### Commits erstellen
```bash
# Commit mit Message erstellen
git commit -m "Beschreibung der Änderungen"
# Alle geänderten, bereits getrackten Dateien committen (überspringt git add)
git commit -a -m "Commit-Message"
# Letzten Commit ändern (Message oder Dateien ergänzen)
git commit --amend -m "Neue Commit-Message"
# Leeren Commit erstellen (nützlich für CI/CD Trigger)
git commit --allow-empty -m "Trigger rebuild"
```
### Status und Unterschiede anzeigen
```bash
# Status des Working Directory anzeigen
git status
# Kurze Statusanzeige
git status -s
# Unterschiede im Working Directory anzeigen (noch nicht gestaged)
git diff
# Unterschiede in der Staging Area anzeigen
git diff --staged
# oder
git diff --cached
# Unterschiede zwischen zwei Commits
git diff <commit1> <commit2>
# Nur Dateinamen der geänderten Dateien anzeigen
git diff --name-only
# Unterschiede einer bestimmten Datei anzeigen
git diff dateiname.txt
```
## Branches
### Branch-Grundlagen
```bash
# Alle lokalen Branches anzeigen
git branch
# Alle Branches (lokal und remote) anzeigen
git branch -a
# Nur Remote-Branches anzeigen
git branch -r
# Neuen Branch erstellen
git branch <branch-name>
# Neuen Branch erstellen und direkt dorthin wechseln
git checkout -b <branch-name>
# oder mit neuerer Syntax
git switch -c <branch-name>
# Zu einem Branch wechseln
git checkout <branch-name>
# oder
git switch <branch-name>
# Branch umbenennen
git branch -m <alter-name> <neuer-name>
# Aktuellen Branch umbenennen
git branch -m <neuer-name>
```
### Branch löschen
Lokal Branch löschen, z.B. wenn er auf Remote in master/main gemergt wurde:
```bash
# Lokal löschen (nur wenn bereits gemergt)
git branch -d <branch-name>
# Lokal löschen (erzwingen, auch wenn nicht gemergt)
git branch -D <branch-name>
# Remote löschen
git push origin --delete <branch-name>
# Alternative Syntax
git push origin :<branch-name>
```
**Beispiel:**
```bash
# Feature-Branch nach Merge löschen
git checkout main
git branch -d feature/neue-funktion
git push origin --delete feature/neue-funktion
```
### Remote Branch als neuen lokalen Branch auschecken
```bash
# Remote-Änderungen holen (ohne zu mergen)
git fetch origin
# Alle Branches anzeigen
git branch -a
# Remote-Branch als lokalen Branch auschecken
git checkout -b <lokaler-name> origin/<remote-branch>
# Wenn lokaler und remote Name gleich sind (ab Git 2.23)
git checkout --track origin/<branch-name>
# oder einfach
git checkout <branch-name> # Git erstellt automatisch tracking branch
```
**Beispiel:**
```bash
git fetch origin
git branch -a
git checkout -b INITIATIVE-242_Ru origin/INITIATIVE-242_Ru
```
### Branch mit anderem Branch aktualisieren
Eigenen Feature-Branch mit den neuesten Änderungen aus main/master aktualisieren:
#### Mit Rebase (empfohlen für saubere History)
```bash
# Zuerst main/master aktualisieren
git checkout main
git pull
# Zum Feature-Branch wechseln
git checkout feature/mein-branch
# Rebase durchführen
git rebase main
# Bei Konflikten: Konflikte in den Dateien lösen, dann:
git add .
git rebase --continue
# Falls zu komplex: Rebase abbrechen
git rebase --abort
# Nach erfolgreichem Rebase: Force-Push (mit Sicherheitsnetz)
git push --force-with-lease
```
#### Interaktives Rebase für mehr Kontrolle
```bash
git checkout main
git pull
git checkout feature/mein-branch
git rebase -i main
# Im Editor: Commits anpassen (pick, squash, edit, drop, etc.)
# Nach dem Speichern: Konflikte lösen falls nötig
git add .
git rebase --continue
git push --force-with-lease
```
#### Mit Merge (behält alle Commits)
```bash
git checkout feature/mein-branch
git merge main
# Konflikte lösen falls nötig, dann:
git add .
git commit # Merge-Commit erstellen
git push
```
### Neuer Branch aus falschem Branch erstellt
#### Ausgangslage
Ein neuer Branch (feature-b) wurde fälschlicherweise aus einem anderen Branch (feature-a) anstatt aus main/master erstellt. Die Commits aus feature-a erscheinen nun auch in feature-b.
#### Problemlösung
```bash
# Main aktualisieren
git checkout main
git pull
# Zum problematischen Branch wechseln
git checkout feature-b
git pull
# Interaktives Rebase auf main
git rebase -i main
# Im Editor: Bei den Commits aus feature-a, die nicht in feature-b gehören:
# Ändere "pick" zu "drop" (oder lösche die Zeile komplett)
# Speichern und schließen
# Prüfen ob alles korrekt ist
git log --oneline
# Force-Push mit Sicherheitsnetz
git push --force-with-lease
```
**Alternative: Branch neu erstellen**
```bash
# Neuen Branch vom richtigen Ausgangspunkt erstellen
git checkout main
git pull
git checkout -b feature-b-neu
# Nur die gewünschten Commits cherry-picken
git cherry-pick <commit-hash-1>
git cherry-pick <commit-hash-2>
# Alten Branch löschen
git branch -D feature-b
git push origin --delete feature-b
# Neuen Branch umbenennen und pushen
git branch -m feature-b
git push -u origin feature-b
```
## Merging und Integration
### Feature-Branch in main/master mergen
Vorgehensweise ohne Pull-Request-Workflow:
```bash
# 1. Auf main/master wechseln (lokal)
git checkout main
# 2. Aktuellste Änderungen holen und synchronisieren
git pull origin main
# 3. Feature-Branch in lokalen main mergen
git merge feature/mein-branch
# 4. Bei Merge-Konflikten: Konflikte in den Dateien beheben
# Konfliktmarkierungen (<<<<<<<, =======, >>>>>>>) im Code auflösen
# Dann Dateien stagen:
git add <konflikt-dateien>
# Merge abschließen:
git commit
# 5. Änderungen auf Remote pushen
git push origin main
```
**Alternative mit Fast-Forward vermeiden:**
```bash
# Merge-Commit erzwingen (auch wenn Fast-Forward möglich wäre)
git merge --no-ff feature/mein-branch
```
### Merge abbrechen
```bash
# Falls während eines Merges etwas schiefgeht
git merge --abort
```
## Cherry-Pick
Einzelne Commits aus einem Branch in einen anderen übernehmen:
```bash
# Einzelnen Commit cherry-picken
git cherry-pick <commit-hash>
# Mehrere Commits cherry-picken
git cherry-pick <commit-hash-1> <commit-hash-2>
# Bereich von Commits cherry-picken (exklusiv start, inklusiv end)
git cherry-pick <start-commit>..<end-commit>
# Cherry-Pick ohne automatischen Commit
git cherry-pick -n <commit-hash>
# Bei Konflikten: Konflikte lösen, dann
git add .
git cherry-pick --continue
# Cherry-Pick abbrechen
git cherry-pick --abort
```
**Beispiel:**
```bash
# Commit aus feature-a in feature-b übernehmen
git checkout feature-b
git cherry-pick abc123
```
## Stash - Änderungen temporär speichern
```bash
# Aktuelle Änderungen in den Stash speichern
git stash
# oder mit Beschreibung
git stash save "WIP: Feature XY"
# Stash mit untracked Dateien
git stash -u
# oder mit allen Dateien (auch ignored)
git stash -a
# Alle Stashes anzeigen
git stash list
# Stash anwenden (behält Stash)
git stash apply
# Spezifischen Stash anwenden
git stash apply stash@{2}
# Stash anwenden und entfernen
git stash pop
# Spezifischen Stash poppen
git stash pop stash@{2}
# Stash-Inhalt anzeigen
git stash show
git stash show -p # mit diff
# Stash löschen
git stash drop stash@{0}
# Alle Stashes löschen
git stash clear
# Branch aus Stash erstellen
git stash branch <branch-name>
```
**Typisches Szenario:**
```bash
# Arbeit unterbrechen für dringenden Bugfix
git stash
git checkout main
git checkout -b hotfix/bug
# Bugfix durchführen...
git checkout feature/meine-arbeit
git stash pop
```
## History und Logs
### Commit-History anzeigen
```bash
# Standard Log
git log
# Kompakte einzeilige Darstellung
git log --oneline
# Mit Grafik der Branches
git log --graph --oneline --all
# Letzten N Commits anzeigen
git log -n 5
git log -5
# Logs mit Änderungen
git log -p
# Logs eines bestimmten Autors
git log --author="Name"
# Logs in einem Zeitraum
git log --since="2024-01-01" --until="2024-12-31"
git log --since="2 weeks ago"
# Logs für eine bestimmte Datei
git log -- pfad/zur/datei.txt
# Commits finden, die einen bestimmten String ändern
git log -S "suchtext"
# Schöne formatierte Ausgabe
git log --pretty=format:"%h - %an, %ar : %s"
```
### Commit-Details anzeigen
```bash
# Details eines bestimmten Commits
git show <commit-hash>
# Dateien in einem Commit
git show --name-only <commit-hash>
# Statistiken eines Commits
git show --stat <commit-hash>
```
### Reflog - History der HEAD-Bewegungen
```bash
# Alle HEAD-Bewegungen anzeigen (auch bei reset, rebase, etc.)
git reflog
# Nützlich um "verlorene" Commits wiederzufinden
git reflog show
# Zu einem früheren Zustand zurückkehren
git reset --hard HEAD@{2}
```
## Commits rückgängig machen
### Reset - History zurücksetzen
```bash
# Einen Commit zurück (Änderungen bleiben im Working Directory)
git reset --soft HEAD~1
# Einen Commit zurück (Änderungen bleiben unstaged)
git reset HEAD~1
# oder
git reset --mixed HEAD~1
# Einen Commit zurück (ACHTUNG: Änderungen werden gelöscht!)
git reset --hard HEAD~1
# Mehrere Commits zurück
git reset --hard HEAD~3
# Zu einem bestimmten Commit zurück
git reset --hard <commit-hash>
# Nach einem Reset: Remote überschreiben (Vorsicht!)
git push --force
# Sicherer: Mit force-with-lease (schützt vor Überschreiben anderer Änderungen)
git push --force-with-lease
```
### Revert - Commit rückgängig machen (sicher für Shared Branches)
```bash
# Einen Commit rückgängig machen (erstellt neuen Commit)
git revert <commit-hash>
# Mehrere Commits rückgängig machen
git revert <commit-hash-1> <commit-hash-2>
# Letzten Commit rückgängig machen
git revert HEAD
# Revert ohne automatischen Commit
git revert -n <commit-hash>
```
**Unterschied Reset vs. Revert:**
- `reset`: Ändert die History (problematisch bei Shared Branches)
- `revert`: Erstellt neuen Commit (sicher für Shared Branches)
### Einzelne Datei auf älteren Stand zurücksetzen
```bash
# Datei aus einem bestimmten Commit wiederherstellen
git checkout <commit-hash> -- pfad/zur/datei.txt
# Datei auf Stand von HEAD (letzter Commit) zurücksetzen
git checkout HEAD -- datei.txt
# oder mit neuerer Syntax
git restore datei.txt
# Datei auf Stand von Remote zurücksetzen
git checkout origin/main -- datei.txt
```
## Lokale History mit Remote überschreiben
```bash
# Alle Remote-Änderungen holen
git fetch --all
# Lokalen Branch komplett mit Remote überschreiben
git reset --hard origin/<branch-name>
# Beispiel für main
git fetch --all
git reset --hard origin/main
```
**Wichtig:** Alle lokalen Änderungen gehen verloren!
## Main/Master auf Stand von origin aktualisieren
```bash
# Standard-Methode
git checkout main
git pull
# Falls lokale Änderungen verworfen werden sollen
git checkout main
git fetch origin
git reset --hard origin/main
# Alternative: Zuerst fetch, dann pull
git checkout main
git fetch origin
git pull origin main
```
## Tags
### Tags erstellen
```bash
# Lightweight Tag erstellen
git tag v1.0.0
# Annotated Tag erstellen (empfohlen)
git tag -a v1.0.0 -m "Version 1.0.0 Release"
# Tag für einen bestimmten Commit
git tag -a v1.0.0 <commit-hash> -m "Release"
# Tags auf Remote pushen
git push origin v1.0.0
# Alle Tags auf Remote pushen
git push origin --tags
```
### Tags anzeigen
```bash
# Alle Tags anzeigen
git tag
# Tags mit Muster suchen
git tag -l "v1.0.*"
# Tag-Details anzeigen
git show v1.0.0
```
### Tags löschen
```bash
# Lokal löschen
git tag -d <tag-name>
# Remote löschen
git push --delete origin <tag-name>
# Alternative Syntax
git push origin :refs/tags/<tag-name>
```
**Beispiel:**
```bash
git tag -d v1.0.0
git push --delete origin v1.0.0
```
## .gitignore
Dateien und Verzeichnisse von der Versionskontrolle ausschließen:
```bash
# .gitignore Datei im Root-Verzeichnis erstellen
touch .gitignore
```
**Beispiel .gitignore:**
```gitignore
# Kompilierte Dateien
*.class
*.o
*.pyc
__pycache__/
# Build-Verzeichnisse
/build/
/dist/
/target/
# Abhängigkeiten
node_modules/
vendor/
# IDE-spezifische Dateien
.vscode/
.idea/
*.swp
*.swo
*~
# Betriebssystem-Dateien
.DS_Store
Thumbs.db
# Umgebungsvariablen und Secrets
.env
.env.local
secrets.yml
# Logs
*.log
logs/
# Temporäre Dateien
tmp/
temp/
*.tmp
# Spezifische Datei ignorieren
config/database.yml
# Alle Dateien eines Typs in einem Verzeichnis
docs/**/*.pdf
# Negation: Datei NICHT ignorieren
!wichtig.log
```
### Bereits getrackte Dateien ignorieren
```bash
# Datei aus Git entfernen, aber lokal behalten
git rm --cached dateiname
# Verzeichnis aus Git entfernen, aber lokal behalten
git rm -r --cached verzeichnis/
# Dann .gitignore aktualisieren und committen
```
## Synchronisation mit Remote
### Pull und Fetch
```bash
# Änderungen holen und mergen
git pull
# Von spezifischem Remote und Branch
git pull origin main
# Fetch: Nur Änderungen holen (ohne zu mergen)
git fetch
git fetch origin
# Mit Rebase statt Merge
git pull --rebase
# Alle Remotes fetchen
git fetch --all
# Remote-Branches prunen (gelöschte entfernen)
git fetch --prune
```
### Push
```bash
# Zum konfigurierten Remote pushen
git push
# Zu spezifischem Remote und Branch
git push origin main
# Neuen Branch auf Remote erstellen und tracken
git push -u origin neuer-branch
# oder
git push --set-upstream origin neuer-branch
# Force Push (Vorsicht!)
git push --force
# Sicherer Force Push
git push --force-with-lease
# Alle Branches pushen
git push --all
# Tags mit pushen
git push --tags
```
## Arbeiten mit Patches
```bash
# Patch aus Commits erstellen
git format-patch -1 HEAD
git format-patch HEAD~3..HEAD
# Patch anwenden
git apply patch-datei.patch
# Patch mit Commit-Informationen anwenden
git am < patch-datei.patch
# Prüfen ob Patch anwendbar ist
git apply --check patch-datei.patch
```
## Submodules
```bash
# Submodule hinzufügen
git submodule add <repository-url> pfad/zum/submodule
# Repository mit Submodules klonen
git clone --recurse-submodules <repository-url>
# Submodules in bestehendem Repo initialisieren
git submodule init
git submodule update
# Alle Submodules aktualisieren
git submodule update --remote
# Submodule entfernen
git submodule deinit pfad/zum/submodule
git rm pfad/zum/submodule
rm -rf .git/modules/pfad/zum/submodule
```
## Nützliche Aliase
Git-Aliase in der Konfiguration einrichten:
```bash
# Kurzformen für häufige Befehle
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
# Log mit Graph
git config --global alias.lg "log --graph --oneline --all --decorate"
# Undo letzter Commit (behält Änderungen)
git config --global alias.undo "reset HEAD~1"
# Kurzform für Status
git config --global alias.s "status -s"
# Branch mit letztem Commit anzeigen
git config --global alias.branches "branch -v"
```
## Troubleshooting
### Merge-Konflikte lösen
```bash
# Status der Konflikte anzeigen
git status
# Konflikte in den Dateien manuell lösen (<<<<<<, ======, >>>>>>)
# Dann:
git add <gelöste-dateien>
git commit
# Merge abbrechen und zurück zum Ursprung
git merge --abort
# Mergetool verwenden
git mergetool
```
### Versehentlich gelöschte Dateien wiederherstellen
```bash
# Datei aus letztem Commit wiederherstellen
git restore datei.txt
# oder
git checkout HEAD -- datei.txt
# Gelöschte Dateien finden
git log --diff-filter=D --summary | grep delete
# Datei aus History wiederherstellen
git checkout <commit-hash>^ -- datei.txt
```
### Commit an falschen Branch
```bash
# Szenario: Commit versehentlich an main statt an Feature-Branch
# 1. Neuen Branch vom aktuellen Stand erstellen
git branch feature/neuer-branch
# 2. Main zurücksetzen
git reset --hard HEAD~1
# 3. Zum neuen Branch wechseln
git checkout feature/neuer-branch
```
### Große Dateien aus History entfernen
```bash
# Git filter-branch (alte Methode, nicht empfohlen)
git filter-branch --tree-filter 'rm -f grosse-datei.zip' HEAD
# BFG Repo-Cleaner (empfohlen, schneller)
# Zuerst BFG installieren, dann:
bfg --delete-files grosse-datei.zip
# Git filter-repo (moderner Ersatz für filter-branch)
git filter-repo --path grosse-datei.zip --invert-paths
```
### Detached HEAD State
```bash
# Zu einem Branch zurückkehren
git checkout main
# Änderungen aus Detached HEAD in neuem Branch speichern
git checkout -b neuer-branch
```
### Versehentlich überschriebene Änderungen wiederherstellen
```bash
# Reflog verwenden um verlorene Commits zu finden
git reflog
# Zu einem früheren Zustand zurückkehren
git reset --hard HEAD@{5}
```
## Best Practices
### Commit-Messages
Gute Commit-Messages folgen diesem Format:
```
<Typ>: <Kurzbeschreibung (max 50 Zeichen)>
<Detaillierte Beschreibung (optional, 72 Zeichen pro Zeile)>
<Footer (optional): Issue-Referenzen, Breaking Changes, etc.>
```
**Typen:**
- `feat`: Neues Feature
- `fix`: Bugfix
- `docs`: Dokumentation
- `style`: Formatierung, kein Code-Change
- `refactor`: Code-Refactoring
- `test`: Tests hinzufügen oder anpassen
- `chore`: Build-Prozess, Dependencies, etc.
**Beispiele:**
```
feat: Benutzer-Login mit OAuth implementieren
fix: Null-Pointer Exception beim Speichern
docs: README mit Installationsanleitung aktualisiert
refactor: Datenbankzugriff in separate Klasse ausgelagert
```
### Workflow-Empfehlungen
1. **Häufig committen**: Kleine, logische Commits sind besser als große
2. **Branch-Strategie**: Feature-Branches für neue Entwicklungen
3. **Pull Requests**: Code-Review vor dem Merge
4. **Main/Master schützen**: Direkte Commits vermeiden
5. **Rebase vor Merge**: Saubere, lineare History
6. **Tests vor Push**: Lokale Tests durchführen
7. **Force-Push vermeiden**: Besonders bei Shared Branches
8. **Regelmäßig pullen**: Konflikte früh erkennen
### Branch-Naming-Konventionen
```
feature/kurze-beschreibung
bugfix/issue-nummer-beschreibung
hotfix/kritischer-bug
release/version-nummer
```
**Beispiele:**
```
feature/user-authentication
bugfix/login-validation
hotfix/security-patch
release/v1.2.0
```
## Fortgeschrittene Befehle
### Bisect - Buggy Commit finden
```bash
# Bisect starten
git bisect start
# Aktuellen Commit als "bad" markieren
git bisect bad
# Bekannten guten Commit markieren
git bisect good <commit-hash>
# Git checked automatisch Commits aus
# Nach jedem Test:
git bisect good # wenn OK
git bisect bad # wenn Bug vorhanden
# Bisect beenden
git bisect reset
```
### Worktree - Mehrere Branches gleichzeitig
```bash
# Neuen Worktree erstellen
git worktree add ../projekt-feature feature/neue-funktion
# Alle Worktrees anzeigen
git worktree list
# Worktree entfernen
git worktree remove ../projekt-feature
# Aufräumen
git worktree prune
```
### Blame - Änderungen pro Zeile anzeigen
```bash
# Zeigt wer welche Zeile wann geändert hat
git blame dateiname.txt
# Mit Zeilennummern
git blame -L 10,20 dateiname.txt
# Ignore Whitespace-Änderungen
git blame -w dateiname.txt
```
### Clean - Untracked Files entfernen
```bash
# Anzeigen was gelöscht würde (Dry-Run)
git clean -n
# Untracked Files löschen
git clean -f
# Auch Verzeichnisse löschen
git clean -fd
# Auch ignored Files löschen
git clean -fdx
```
## Git Hooks
Hooks sind Skripte die bei bestimmten Git-Events ausgeführt werden:
```bash
# Hooks befinden sich in:
.git/hooks/
# Beispiel: pre-commit Hook
# Datei: .git/hooks/pre-commit
#!/bin/bash
npm run lint
npm test
# Ausführbar machen
chmod +x .git/hooks/pre-commit
```
**Wichtige Hooks:**
- `pre-commit`: Vor jedem Commit
- `pre-push`: Vor jedem Push
- `post-merge`: Nach jedem Merge
- `post-checkout`: Nach Branch-Wechsel
## Nützliche Tipps
### Farbige Ausgabe aktivieren
```bash
git config --global color.ui auto
```
### Automatisches Stash bei Rebase
```bash
git config --global rebase.autoStash true
```
### Default Branch Name
```bash
git config --global init.defaultBranch main
```
### Pull Strategie festlegen
```bash
# Rebase als Standard beim Pull
git config --global pull.rebase true
# Fast-Forward only
git config --global pull.ff only
```
### Editor für Commit-Messages
```bash
git config --global core.editor "nano"
# oder für VS Code
git config --global core.editor "code --wait"
```
### Globales .gitignore
```bash
# Erstellen
touch ~/.gitignore_global
# Konfigurieren
git config --global core.excludesfile ~/.gitignore_global
# Beispiel-Inhalt: IDE und OS-spezifische Dateien
echo ".DS_Store" >> ~/.gitignore_global
echo ".vscode/" >> ~/.gitignore_global
echo "*.swp" >> ~/.gitignore_global
```