Compare commits
13 commits
40232d50da
...
6c02ce982a
| Author | SHA1 | Date | |
|---|---|---|---|
| 6c02ce982a | |||
| 5ffa8712c4 | |||
| 1733c57d43 | |||
|
|
26c27dab6f | ||
| f0a188e892 | |||
| aa0ff378d4 | |||
| 1ed8752043 | |||
| 0e769947cb | |||
| a18bfd8ca2 | |||
| 9df9d134a3 | |||
| 4769086d28 | |||
| 5de7cf2c94 | |||
| b841b396c6 |
17 changed files with 2450 additions and 4 deletions
97
README.md
97
README.md
|
|
@ -1,2 +1,99 @@
|
||||||
# dotfiles-rene
|
# dotfiles-rene
|
||||||
|
|
||||||
|
Dotfiles und Skripte fuer macOS und Linux (Ubuntu auf MacBook Pro).
|
||||||
|
|
||||||
|
Wird automatisch von [macbook-setup](https://git.motocamp.de/rene/macbook-setup) deployed.
|
||||||
|
|
||||||
|
## Inhalt
|
||||||
|
|
||||||
|
```
|
||||||
|
bin/ Git-Werkzeuge (werden nach ~/ verlinkt)
|
||||||
|
micro/ Micro-Editor Konfiguration
|
||||||
|
nvim/ Neovim Konfiguration
|
||||||
|
oh-my-zsh/custom/ Powerlevel10k, zsh-syntax-highlighting
|
||||||
|
heic-scripts/ HEIC-zu-JPEG Konverter (h2j)
|
||||||
|
pi/ Raspberry Pi spezifische Configs
|
||||||
|
```
|
||||||
|
|
||||||
|
## Git-Werkzeuge (~/bin)
|
||||||
|
|
||||||
|
Alle Skripte in `bin/` werden von `setup-desktop.sh` automatisch nach `~/` verlinkt.
|
||||||
|
|
||||||
|
### gitsync - Repositories synchronisieren
|
||||||
|
|
||||||
|
Synchronisiert alle Git-Repositories in `~/git-projekte` mit dem Gitea-Server:
|
||||||
|
|
||||||
|
- Fehlende Repos werden geklont
|
||||||
|
- Repos mit Remote-Aenderungen werden gepullt (fast-forward)
|
||||||
|
- Repos mit lokalen Commits werden gepusht
|
||||||
|
- Repos mit uncommitteten Aenderungen werden markiert
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitsync # alles synchronisieren
|
||||||
|
gitsync --dry-run # nur anzeigen, nichts aendern
|
||||||
|
gitsync --path /foo # anderes Basisverzeichnis
|
||||||
|
```
|
||||||
|
|
||||||
|
Die Repo-Liste ist im Skript hinterlegt. Bei neuen Repos dort einen Eintrag ergaenzen.
|
||||||
|
|
||||||
|
### gitcheck - Repository-Status pruefen
|
||||||
|
|
||||||
|
Zeigt den Status aller Repositories (lokale Aenderungen, ungepushte/ungepullte Commits).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitcheck # nur Repos mit Aenderungen
|
||||||
|
gitcheck --all # alle Repos anzeigen
|
||||||
|
gitcheck --short # kompakte Ausgabe (Standard-Alias)
|
||||||
|
```
|
||||||
|
|
||||||
|
### gitupdate - Repositories aktualisieren
|
||||||
|
|
||||||
|
Pullt alle Repositories (ueberspringt Repos mit lokalen Aenderungen).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitupdate # alle Repos pullen
|
||||||
|
```
|
||||||
|
|
||||||
|
### cb - Clipboard bereinigen
|
||||||
|
|
||||||
|
Entfernt die 2 fuehrenden Leerzeichen pro Zeile aus der Zwischenablage, die Claude Code bei der Terminal-Ausgabe einfuegt. Nuetzlich beim Kopieren mehrzeiliger Befehle oder Codeblocks.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cb # Zwischenablage bereinigen, dann mit Cmd+V einfuegen
|
||||||
|
```
|
||||||
|
|
||||||
|
Verwendet `pbpaste`/`pbcopy` auf macOS und `xclip` auf Linux.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Automatisch (via macbook-setup)
|
||||||
|
|
||||||
|
`setup-desktop.sh` klont dieses Repo und verlinkt alles automatisch.
|
||||||
|
|
||||||
|
### Manuell (bestehender Mac)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://git.motocamp.de/rene/dotfiles-rene.git ~/git-projekte/dotfiles-rene
|
||||||
|
|
||||||
|
# Skripte verlinken
|
||||||
|
for script in ~/git-projekte/dotfiles-rene/bin/*; do
|
||||||
|
chmod +x "$script" && ln -sf "$script" ~/
|
||||||
|
done
|
||||||
|
|
||||||
|
# Aliases in ~/.zshrc
|
||||||
|
alias gitcheck="~/git-check-all.sh --short"
|
||||||
|
alias gitupdate="~/git-update-all.sh"
|
||||||
|
alias cb="pbpaste | sed 's/^ //' | pbcopy" # macOS
|
||||||
|
alias cb="xclip -selection clipboard -o | sed 's/^ //' | xclip -selection clipboard -i" # Linux
|
||||||
|
alias gitsync="~/git-sync-all.sh"
|
||||||
|
alias mac-sync="curl -fsSL https://git.motocamp.de/rene/dotfiles-rene/raw/branch/main/bin/git-sync-all.sh | bash"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Neuen Mac einrichten (Kurzfassung)
|
||||||
|
|
||||||
|
1. Auf einem bestehenden Mac: `gitsync` ausfuehren (pusht alles)
|
||||||
|
2. Auf dem neuen Mac (noch ohne .zshrc) einmalig:
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://git.motocamp.de/rene/dotfiles-rene/raw/branch/main/bin/git-sync-all.sh | bash
|
||||||
|
```
|
||||||
|
3. Danach reicht: `gitsync` (lokal) oder `mac-sync` (frisch vom Server)
|
||||||
|
|
|
||||||
159
bin/git-check-all.sh
Executable file
159
bin/git-check-all.sh
Executable file
|
|
@ -0,0 +1,159 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Default-Basisverzeichnis
|
||||||
|
BASE_DIR="$HOME/git-projekte"
|
||||||
|
SHOW_ALL=false
|
||||||
|
SHORT_MODE=false
|
||||||
|
|
||||||
|
# --- Farben ------------------------------------------------------------
|
||||||
|
if [ -t 1 ]; then
|
||||||
|
C_RED=$'\033[31m'
|
||||||
|
C_GREEN=$'\033[32m'
|
||||||
|
C_YELLOW=$'\033[33m'
|
||||||
|
C_CYAN=$'\033[36m'
|
||||||
|
C_BOLD=$'\033[1m'
|
||||||
|
C_RESET=$'\033[0m'
|
||||||
|
else
|
||||||
|
C_RED=""; C_GREEN=""; C_YELLOW=""; C_CYAN=""; C_BOLD=""; C_RESET=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- Argumente parsen --------------------------------------------------
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
-a|--all)
|
||||||
|
SHOW_ALL=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-s|--short)
|
||||||
|
SHORT_MODE=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-p|--path)
|
||||||
|
BASE_DIR="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
cat <<EOF
|
||||||
|
Usage: ${0##*/} [OPTIONEN]
|
||||||
|
|
||||||
|
Optionen:
|
||||||
|
-a, --all alle Repositories anzeigen (auch saubere)
|
||||||
|
-s, --short kompakte Ausgabe (eine Zeile pro Repo)
|
||||||
|
-p, --path DIR anderes Basisverzeichnis statt ~/git-projekte
|
||||||
|
-h, --help diese Hilfe anzeigen
|
||||||
|
|
||||||
|
Standard-Basisverzeichnis: $HOME/git-projekte
|
||||||
|
EOF
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unbekannte Option: $1" >&2
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# --- Checks ------------------------------------------------------------
|
||||||
|
if [ ! -d "$BASE_DIR" ]; then
|
||||||
|
echo "Verzeichnis $BASE_DIR existiert nicht – nichts zu prüfen."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Suche Git-Repositories unter: $BASE_DIR"
|
||||||
|
echo
|
||||||
|
|
||||||
|
find_git_dirs() {
|
||||||
|
find "$BASE_DIR" -type d -name ".git" -print 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- .git-Verzeichnisse einsammeln & sortieren ------------------------
|
||||||
|
gitdirs=()
|
||||||
|
while IFS= read -r gitdir; do
|
||||||
|
gitdirs+=( "$gitdir" )
|
||||||
|
done < <(find_git_dirs)
|
||||||
|
|
||||||
|
if [ ${#gitdirs[@]} -eq 0 ]; then
|
||||||
|
echo "Keine Git-Repositories gefunden."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
IFS=$'\n' sorted_gitdirs=( $(printf '%s\n' "${gitdirs[@]}" | sort) )
|
||||||
|
unset IFS
|
||||||
|
|
||||||
|
# --- Auswertung --------------------------------------------------------
|
||||||
|
total=0
|
||||||
|
dirty=0
|
||||||
|
clean=0
|
||||||
|
|
||||||
|
for gitdir in "${sorted_gitdirs[@]}"; do
|
||||||
|
repo_dir="${gitdir%/.git}"
|
||||||
|
((total++))
|
||||||
|
|
||||||
|
cd "$repo_dir" || continue
|
||||||
|
|
||||||
|
# Lokale, nicht committete Änderungen?
|
||||||
|
status_output="$(git status --porcelain 2>/dev/null || echo "")"
|
||||||
|
has_local_changes=false
|
||||||
|
if [[ -n "$status_output" ]]; then
|
||||||
|
has_local_changes=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Commits vor/nach Upstream?
|
||||||
|
ahead=0
|
||||||
|
behind=0
|
||||||
|
if upstream_info=$(git rev-list --left-right --count "@{u}...HEAD" 2>/dev/null); then
|
||||||
|
read -r behind ahead <<<"$upstream_info"
|
||||||
|
fi
|
||||||
|
|
||||||
|
is_dirty=false
|
||||||
|
$has_local_changes && is_dirty=true
|
||||||
|
((ahead > 0)) && is_dirty=true
|
||||||
|
((behind > 0)) && is_dirty=true
|
||||||
|
|
||||||
|
if $is_dirty; then
|
||||||
|
((dirty++))
|
||||||
|
else
|
||||||
|
((clean++))
|
||||||
|
$SHOW_ALL || continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Zusammenfassungstext bauen
|
||||||
|
summary=""
|
||||||
|
$has_local_changes && summary+="lokale Änderungen; "
|
||||||
|
((ahead > 0)) && summary+="$ahead nicht gepushte Commits; "
|
||||||
|
((behind > 0)) && summary+="$behind nicht gepullte Commits; "
|
||||||
|
summary="${summary%; }"
|
||||||
|
[ -z "$summary" ] && summary="clean"
|
||||||
|
|
||||||
|
if $SHORT_MODE; then
|
||||||
|
# eine Zeile pro Repo
|
||||||
|
if $is_dirty; then
|
||||||
|
printf "%sDIRTY%s %s - %s\n" "$C_RED" "$C_RESET" "$repo_dir" "$summary"
|
||||||
|
else
|
||||||
|
printf "%sCLEAN%s %s - %s\n" "$C_GREEN" "$C_RESET" "$repo_dir" "$summary"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# detailliertere Ausgabe
|
||||||
|
if $is_dirty; then
|
||||||
|
printf "%s▸ %s%s\n" "$C_RED" "$repo_dir" "$C_RESET"
|
||||||
|
else
|
||||||
|
printf "%s▸ %s%s\n" "$C_GREEN" "$repo_dir" "$C_RESET"
|
||||||
|
fi
|
||||||
|
printf " %s%s%s\n\n" "$C_CYAN" "$summary" "$C_RESET"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# --- Zusammenfassung ---------------------------------------------------
|
||||||
|
echo "${C_BOLD}Gesamt:${C_RESET} $total Repositories"
|
||||||
|
echo "${C_GREEN}Clean:${C_RESET} $clean"
|
||||||
|
echo "${C_RED}Dirty:${C_RESET} $dirty"
|
||||||
|
echo
|
||||||
|
|
||||||
|
if ((dirty == 0)); then
|
||||||
|
echo "Alle gefundenen Git-Repositories in $BASE_DIR sind sauber. ✅"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "$dirty Repository(s) mit offenen Änderungen. ⚠️"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
190
bin/git-sync-all.sh
Executable file
190
bin/git-sync-all.sh
Executable file
|
|
@ -0,0 +1,190 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -uo pipefail
|
||||||
|
|
||||||
|
BASE_DIR="${BASE_DIR:-$HOME/git-projekte}"
|
||||||
|
GITEA_BASE="https://git.motocamp.de/rene"
|
||||||
|
|
||||||
|
# Alle Repos auf dem Gitea-Server.
|
||||||
|
# Bei neuen Repos hier einen Eintrag ergaenzen.
|
||||||
|
REPO_NAMES=(
|
||||||
|
balkonsteuerung
|
||||||
|
berechnungstabellen
|
||||||
|
claude-skills
|
||||||
|
comfy
|
||||||
|
dotfiles-rene
|
||||||
|
esp32
|
||||||
|
ki-agenten
|
||||||
|
macbook-setup
|
||||||
|
Pi_pico_2w
|
||||||
|
portainer
|
||||||
|
skripte
|
||||||
|
test
|
||||||
|
web
|
||||||
|
zellenhalter-generator
|
||||||
|
)
|
||||||
|
|
||||||
|
# --- Farben ----------------------------------------------------------------
|
||||||
|
if [ -t 1 ]; then
|
||||||
|
C_RED=$'\033[31m'
|
||||||
|
C_GREEN=$'\033[32m'
|
||||||
|
C_YELLOW=$'\033[33m'
|
||||||
|
C_CYAN=$'\033[36m'
|
||||||
|
C_BOLD=$'\033[1m'
|
||||||
|
C_RESET=$'\033[0m'
|
||||||
|
else
|
||||||
|
C_RED=""; C_GREEN=""; C_YELLOW=""; C_CYAN=""; C_BOLD=""; C_RESET=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- Argumente -------------------------------------------------------------
|
||||||
|
DRY_RUN=false
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
-p|--path) BASE_DIR="$2"; shift 2 ;;
|
||||||
|
-n|--dry-run) DRY_RUN=true; shift ;;
|
||||||
|
-h|--help)
|
||||||
|
cat <<EOF
|
||||||
|
Usage: ${0##*/} [OPTIONEN]
|
||||||
|
|
||||||
|
Synchronisiert alle Git-Repositories mit dem Gitea-Server:
|
||||||
|
- Fehlende Repos werden geklont
|
||||||
|
- Repos mit Remote-Aenderungen werden gepullt
|
||||||
|
- Repos mit lokalen Commits werden gepusht
|
||||||
|
- Repos mit uncommitteten Aenderungen werden markiert
|
||||||
|
|
||||||
|
Optionen:
|
||||||
|
-p, --path DIR anderes Basisverzeichnis statt ~/git-projekte
|
||||||
|
-n, --dry-run nur anzeigen, nichts aendern
|
||||||
|
-h, --help diese Hilfe anzeigen
|
||||||
|
EOF
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*) echo "Unbekannte Option: $1" >&2; exit 2 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
mkdir -p "$BASE_DIR"
|
||||||
|
|
||||||
|
echo "${C_BOLD}Git-Sync: $BASE_DIR${C_RESET}"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# --- Zaehler ---------------------------------------------------------------
|
||||||
|
total=0
|
||||||
|
cloned=0
|
||||||
|
pulled=0
|
||||||
|
pushed=0
|
||||||
|
dirty=0
|
||||||
|
uptodate=0
|
||||||
|
failed=0
|
||||||
|
|
||||||
|
# --- Repos durchgehen ------------------------------------------------------
|
||||||
|
for NAME in "${REPO_NAMES[@]}"; do
|
||||||
|
URL="${GITEA_BASE}/${NAME}.git"
|
||||||
|
TARGET="$BASE_DIR/$NAME"
|
||||||
|
((total++))
|
||||||
|
|
||||||
|
# 1) Repo fehlt -> klonen
|
||||||
|
if [ ! -d "$TARGET/.git" ]; then
|
||||||
|
if [ -d "$TARGET" ]; then
|
||||||
|
printf "${C_YELLOW}SKIP${C_RESET} %-25s Verzeichnis existiert, kein Git-Repo\n" "$NAME"
|
||||||
|
((failed++))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if $DRY_RUN; then
|
||||||
|
printf "${C_CYAN}CLONE${C_RESET} %-25s (dry-run)\n" "$NAME"
|
||||||
|
else
|
||||||
|
if git clone --quiet "$URL" "$TARGET" 2>/dev/null; then
|
||||||
|
printf "${C_CYAN}CLONE${C_RESET} %-25s geklont\n" "$NAME"
|
||||||
|
((cloned++))
|
||||||
|
else
|
||||||
|
printf "${C_RED}FAIL${C_RESET} %-25s Klonen fehlgeschlagen\n" "$NAME"
|
||||||
|
((failed++))
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ab hier: Repo existiert
|
||||||
|
cd "$TARGET" || continue
|
||||||
|
|
||||||
|
# Remote fetch
|
||||||
|
git fetch --quiet 2>/dev/null || true
|
||||||
|
|
||||||
|
# 2) Uncommittete Aenderungen?
|
||||||
|
has_changes=false
|
||||||
|
if [[ -n "$(git status --porcelain 2>/dev/null)" ]]; then
|
||||||
|
has_changes=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 3) Ahead/Behind
|
||||||
|
ahead=0
|
||||||
|
behind=0
|
||||||
|
upstream_info="$(git rev-list --left-right --count "@{u}...HEAD" 2>/dev/null || true)"
|
||||||
|
if [[ -n "$upstream_info" ]]; then
|
||||||
|
read -r behind ahead <<<"$upstream_info"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 4) Aktionen
|
||||||
|
did_something=false
|
||||||
|
|
||||||
|
# Pull wenn behind
|
||||||
|
if ((behind > 0)); then
|
||||||
|
if $has_changes; then
|
||||||
|
printf "${C_YELLOW}DIRTY${C_RESET} %-25s %d neue Remote-Commits + lokale Aenderungen\n" "$NAME" "$behind"
|
||||||
|
((dirty++))
|
||||||
|
if ((ahead > 0)); then
|
||||||
|
printf " %-25s + %d lokale Commits nicht gepusht\n" "" "$ahead"
|
||||||
|
fi
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if $DRY_RUN; then
|
||||||
|
printf "${C_GREEN}PULL${C_RESET} %-25s %d Commits (dry-run)\n" "$NAME" "$behind"
|
||||||
|
else
|
||||||
|
if git pull --ff-only --quiet 2>/dev/null; then
|
||||||
|
printf "${C_GREEN}PULL${C_RESET} %-25s %d Commits geholt\n" "$NAME" "$behind"
|
||||||
|
((pulled++))
|
||||||
|
else
|
||||||
|
printf "${C_RED}FAIL${C_RESET} %-25s Pull fehlgeschlagen (evtl. diverged)\n" "$NAME"
|
||||||
|
((failed++))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
did_something=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Push wenn ahead
|
||||||
|
if ((ahead > 0)); then
|
||||||
|
if $DRY_RUN; then
|
||||||
|
printf "${C_GREEN}PUSH${C_RESET} %-25s %d Commits (dry-run)\n" "$NAME" "$ahead"
|
||||||
|
else
|
||||||
|
if git push --quiet 2>/dev/null; then
|
||||||
|
printf "${C_GREEN}PUSH${C_RESET} %-25s %d Commits gepusht\n" "$NAME" "$ahead"
|
||||||
|
((pushed++))
|
||||||
|
else
|
||||||
|
printf "${C_RED}FAIL${C_RESET} %-25s Push fehlgeschlagen\n" "$NAME"
|
||||||
|
((failed++))
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
did_something=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! $did_something; then
|
||||||
|
if $has_changes; then
|
||||||
|
printf "${C_YELLOW}DIRTY${C_RESET} %-25s uncommittete Aenderungen\n" "$NAME"
|
||||||
|
((dirty++))
|
||||||
|
else
|
||||||
|
printf "${C_GREEN}OK${C_RESET} %-25s aktuell\n" "$NAME"
|
||||||
|
((uptodate++))
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# --- Zusammenfassung -------------------------------------------------------
|
||||||
|
echo
|
||||||
|
echo "${C_BOLD}Gesamt:${C_RESET} $total Repositories"
|
||||||
|
((cloned > 0)) && echo "${C_CYAN}Geklont:${C_RESET} $cloned"
|
||||||
|
((pulled > 0)) && echo "${C_GREEN}Gepullt:${C_RESET} $pulled"
|
||||||
|
((pushed > 0)) && echo "${C_GREEN}Gepusht:${C_RESET} $pushed"
|
||||||
|
((dirty > 0)) && echo "${C_YELLOW}Dirty:${C_RESET} $dirty"
|
||||||
|
((failed > 0)) && echo "${C_RED}Fehlgeschlagen:${C_RESET} $failed"
|
||||||
|
((uptodate > 0)) && echo "${C_GREEN}Aktuell:${C_RESET} $uptodate"
|
||||||
|
echo
|
||||||
106
bin/git-update-all.sh
Executable file
106
bin/git-update-all.sh
Executable file
|
|
@ -0,0 +1,106 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
BASE_DIR="$HOME/git-projekte"
|
||||||
|
|
||||||
|
# --- Farben ------------------------------------------------------------
|
||||||
|
if [ -t 1 ]; then
|
||||||
|
C_RED=$'\033[31m'
|
||||||
|
C_GREEN=$'\033[32m'
|
||||||
|
C_YELLOW=$'\033[33m'
|
||||||
|
C_BOLD=$'\033[1m'
|
||||||
|
C_RESET=$'\033[0m'
|
||||||
|
else
|
||||||
|
C_RED=""; C_GREEN=""; C_YELLOW=""; C_BOLD=""; C_RESET=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- Argumente ----------------------------------------------------------
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
-p|--path) BASE_DIR="$2"; shift 2 ;;
|
||||||
|
-h|--help)
|
||||||
|
cat <<EOF
|
||||||
|
Usage: ${0##*/} [OPTIONEN]
|
||||||
|
|
||||||
|
Synchronisiert alle Git-Repositories (git pull).
|
||||||
|
Repos mit lokalen Aenderungen werden uebersprungen.
|
||||||
|
|
||||||
|
Optionen:
|
||||||
|
-p, --path DIR anderes Basisverzeichnis statt ~/git-projekte
|
||||||
|
-h, --help diese Hilfe anzeigen
|
||||||
|
EOF
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*) echo "Unbekannte Option: $1" >&2; exit 2 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -d "$BASE_DIR" ]; then
|
||||||
|
echo "Verzeichnis $BASE_DIR existiert nicht."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "${C_BOLD}Git-Repositories aktualisieren: $BASE_DIR${C_RESET}"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# --- Repos finden und sortieren -----------------------------------------
|
||||||
|
gitdirs=()
|
||||||
|
while IFS= read -r gitdir; do
|
||||||
|
gitdirs+=( "$gitdir" )
|
||||||
|
done < <(find "$BASE_DIR" -type d -name ".git" -print 2>/dev/null)
|
||||||
|
|
||||||
|
if [ ${#gitdirs[@]} -eq 0 ]; then
|
||||||
|
echo "Keine Git-Repositories gefunden."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
IFS=$'\n' sorted_gitdirs=( $(printf '%s\n' "${gitdirs[@]}" | sort) )
|
||||||
|
unset IFS
|
||||||
|
|
||||||
|
# --- Pull ---------------------------------------------------------------
|
||||||
|
total=0
|
||||||
|
updated=0
|
||||||
|
skipped=0
|
||||||
|
failed=0
|
||||||
|
|
||||||
|
for gitdir in "${sorted_gitdirs[@]}"; do
|
||||||
|
repo_dir="${gitdir%/.git}"
|
||||||
|
repo_name="${repo_dir#$BASE_DIR/}"
|
||||||
|
((total++))
|
||||||
|
|
||||||
|
cd "$repo_dir" || continue
|
||||||
|
|
||||||
|
# Lokale Aenderungen? -> ueberspringen
|
||||||
|
if [[ -n "$(git status --porcelain 2>/dev/null)" ]]; then
|
||||||
|
printf "${C_YELLOW}SKIP${C_RESET} %s (lokale Aenderungen)\n" "$repo_name"
|
||||||
|
((skipped++))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Kein Remote? -> ueberspringen
|
||||||
|
if ! git remote | grep -q .; then
|
||||||
|
printf "${C_YELLOW}SKIP${C_RESET} %s (kein Remote)\n" "$repo_name"
|
||||||
|
((skipped++))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Pull
|
||||||
|
if output=$(git pull --ff-only 2>&1); then
|
||||||
|
if echo "$output" | grep -q "Already up to date"; then
|
||||||
|
printf "${C_GREEN}OK${C_RESET} %s (aktuell)\n" "$repo_name"
|
||||||
|
else
|
||||||
|
printf "${C_GREEN}PULL${C_RESET} %s (aktualisiert)\n" "$repo_name"
|
||||||
|
((updated++))
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
printf "${C_RED}FAIL${C_RESET} %s\n" "$repo_name"
|
||||||
|
((failed++))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# --- Zusammenfassung ----------------------------------------------------
|
||||||
|
echo
|
||||||
|
echo "${C_BOLD}Gesamt:${C_RESET} $total Repositories"
|
||||||
|
echo "${C_GREEN}Aktualisiert:${C_RESET} $updated"
|
||||||
|
echo "${C_YELLOW}Uebersprungen:${C_RESET} $skipped"
|
||||||
|
echo "${C_RED}Fehlgeschlagen:${C_RESET} $failed"
|
||||||
43
heic-scripts/h2j
Executable file
43
heic-scripts/h2j
Executable file
|
|
@ -0,0 +1,43 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# h2j — HEIC zu JPG konvertieren
|
||||||
|
# Usage: h2j [-r] [-d] [-rd]
|
||||||
|
# -r Resize auf max. 1920px
|
||||||
|
# -d HEIC-Originale löschen
|
||||||
|
# -rd Beides
|
||||||
|
|
||||||
|
RESIZE=false
|
||||||
|
DELETE=false
|
||||||
|
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
-r) RESIZE=true ;;
|
||||||
|
-d) DELETE=true ;;
|
||||||
|
-rd|-dr) RESIZE=true; DELETE=true ;;
|
||||||
|
-h|--help)
|
||||||
|
echo "h2j — HEIC zu JPG konvertieren"
|
||||||
|
echo ""
|
||||||
|
echo "Usage: h2j [-r] [-d] [-rd] [-h]"
|
||||||
|
echo ""
|
||||||
|
echo "Flags:"
|
||||||
|
echo " -r Auf max. 1920px verkleinern"
|
||||||
|
echo " -d HEIC-Originale loeschen"
|
||||||
|
echo " -rd Verkleinern + loeschen"
|
||||||
|
echo " -h Diese Hilfe anzeigen"
|
||||||
|
echo ""
|
||||||
|
echo "Konvertiert alle *.heic/*.HEIC im aktuellen Verzeichnis."
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
count=0
|
||||||
|
for file in *.{heic,HEIC}; do
|
||||||
|
[[ -f "$file" ]] || continue
|
||||||
|
output="${file%.*}.jpg"
|
||||||
|
heif-convert -q 90 "$file" "$output" || continue
|
||||||
|
((count++))
|
||||||
|
[[ "$RESIZE" == true ]] && [[ -f "$output" ]] && mogrify -resize 1920x1920\> "$output"
|
||||||
|
[[ "$DELETE" == true ]] && rm "$file"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "$count Bild(er) konvertiert."
|
||||||
0
heic-scripts/heic2jpg
Normal file → Executable file
0
heic-scripts/heic2jpg
Normal file → Executable file
0
heic-scripts/heic2jpg_delete
Normal file → Executable file
0
heic-scripts/heic2jpg_delete
Normal file → Executable file
0
heic-scripts/heic2jpg_resize
Normal file → Executable file
0
heic-scripts/heic2jpg_resize
Normal file → Executable file
0
heic-scripts/heic2jpg_resize_delete
Normal file → Executable file
0
heic-scripts/heic2jpg_resize_delete
Normal file → Executable file
0
heic-scripts/jpg_resize
Normal file → Executable file
0
heic-scripts/jpg_resize
Normal file → Executable file
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
REPO_URL="https://dsm.motocamp.de:3051/rene/dotfiles-rene.git"
|
REPO_URL="https://git.motocamp.de/rene/dotfiles-rene.git"
|
||||||
BASE_DIR="$HOME/git-projekte"
|
BASE_DIR="$HOME/git-projekte"
|
||||||
REPO_NAME="dotfiles-rene"
|
REPO_NAME="dotfiles-rene"
|
||||||
REPO_DIR="$BASE_DIR/$REPO_NAME"
|
REPO_DIR="$BASE_DIR/$REPO_NAME"
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ sudo apt install neovim ripgrep fd-find nodejs npm
|
||||||
### Dotfiles installieren
|
### Dotfiles installieren
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone git@dsm.motocamp.de:3051/rene/dotfiles-rene.git ~/git-projekte/dotfiles-rene
|
git clone https://git.motocamp.de/rene/dotfiles-rene.git ~/git-projekte/dotfiles-rene
|
||||||
cd ~/git-projekte/dotfiles-rene/nvim
|
cd ~/git-projekte/dotfiles-rene/nvim
|
||||||
chmod +x install-nvim-dotfiles.sh
|
chmod +x install-nvim-dotfiles.sh
|
||||||
./install-nvim-dotfiles.sh
|
./install-nvim-dotfiles.sh
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 5eb677bb0fa9a3e60f0eff031dc13926e093df92
|
Subproject commit 1d85c692615a25fe2293bdd44b34c217d5d2bf04
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 36f3045d69d1ba402db09d09eb12b42eebe0fa3b
|
Subproject commit 8ed1f58e082e1cce85e1d69235d1a906cf3c643e
|
||||||
82
zsh/.zshrc
Normal file
82
zsh/.zshrc
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
# ----------------------------------------------------------
|
||||||
|
# Zsh-Konfiguration fuer Rene (Linux / MacBook Pro)
|
||||||
|
# Oh My Zsh + Powerlevel10k + Micro
|
||||||
|
# ----------------------------------------------------------
|
||||||
|
|
||||||
|
# 1) Powerlevel10k Instant Prompt (muss sehr weit oben stehen)
|
||||||
|
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
|
||||||
|
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2) Oh My Zsh Basis
|
||||||
|
export ZSH="$HOME/.oh-my-zsh"
|
||||||
|
ZSH_THEME="powerlevel10k/powerlevel10k"
|
||||||
|
|
||||||
|
plugins=(
|
||||||
|
git
|
||||||
|
zsh-syntax-highlighting
|
||||||
|
zoxide
|
||||||
|
)
|
||||||
|
|
||||||
|
source "$ZSH/oh-my-zsh.sh"
|
||||||
|
|
||||||
|
# 3) Powerlevel10k-Konfiguration
|
||||||
|
[[ -f "$HOME/.p10k.zsh" ]] && source "$HOME/.p10k.zsh"
|
||||||
|
|
||||||
|
# 4) Standard-Editor (lokal: micro, SSH: nicht erzwingen)
|
||||||
|
if [[ -z "$SSH_CONNECTION" ]]; then
|
||||||
|
export EDITOR="micro"
|
||||||
|
export VISUAL="micro"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 5) Pfade
|
||||||
|
export PATH="$HOME/bin:$HOME/.local/bin:$HOME/.npm-global/bin:$PATH"
|
||||||
|
|
||||||
|
# 6) Aliases
|
||||||
|
|
||||||
|
# ls-Varianten
|
||||||
|
alias ll='ls -lha'
|
||||||
|
alias la='ls -A'
|
||||||
|
alias l='ls -lh'
|
||||||
|
|
||||||
|
# Verzeichnisse
|
||||||
|
alias ..='cd ..'
|
||||||
|
alias ...='cd ../..'
|
||||||
|
alias ....='cd ../../..'
|
||||||
|
|
||||||
|
# Konfigdateien
|
||||||
|
alias zshconfig='micro ~/.zshrc'
|
||||||
|
alias p10kconfig='micro ~/.p10k.zsh'
|
||||||
|
|
||||||
|
# Git-Kurzbefehle
|
||||||
|
alias gs='git status'
|
||||||
|
alias ga='git add'
|
||||||
|
alias gc='git commit'
|
||||||
|
alias gp='git push'
|
||||||
|
alias gl='git log --oneline --graph --decorate'
|
||||||
|
alias gitcheck="~/git-check-all.sh --short"
|
||||||
|
alias gitupdate="~/git-update-all.sh"
|
||||||
|
alias cb="xclip -selection clipboard -o | sed 's/^ //' | xclip -selection clipboard -i"
|
||||||
|
alias gitsync="~/git-sync-all.sh"
|
||||||
|
alias mac-sync="curl -fsSL https://git.motocamp.de/rene/dotfiles-rene/raw/branch/main/bin/git-sync-all.sh | bash"
|
||||||
|
|
||||||
|
# 7) History
|
||||||
|
HISTFILE="$HOME/.zsh_history"
|
||||||
|
HISTSIZE=5000
|
||||||
|
SAVEHIST=5000
|
||||||
|
setopt HIST_IGNORE_DUPS
|
||||||
|
setopt HIST_IGNORE_SPACE
|
||||||
|
setopt SHARE_HISTORY
|
||||||
|
|
||||||
|
# 8) Zsh-Optionen
|
||||||
|
setopt AUTO_CD
|
||||||
|
|
||||||
|
# 9) Fenster-/Tab-Titel
|
||||||
|
precmd() { print -Pn "\e]0;%n@%m: %~\a" }
|
||||||
|
export COLORTERM=truecolor
|
||||||
|
|
||||||
|
# Terminal-Screensaver: cmatrix nach 5 Min Idle
|
||||||
|
if command -v cmatrix &>/dev/null; then
|
||||||
|
TMOUT=300
|
||||||
|
TRAPALRM() { cmatrix -sab }
|
||||||
|
fi
|
||||||
31
zsh/install-zsh-dotfiles.sh
Executable file
31
zsh/install-zsh-dotfiles.sh
Executable file
|
|
@ -0,0 +1,31 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Zsh Dotfiles Installer
|
||||||
|
# Erstellt Symlink ~/.zshrc -> dotfiles-rene/zsh/.zshrc
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
ZSHRC_SOURCE="$SCRIPT_DIR/.zshrc"
|
||||||
|
ZSHRC_TARGET="$HOME/.zshrc"
|
||||||
|
|
||||||
|
echo "=== Zsh Dotfiles Installer ==="
|
||||||
|
|
||||||
|
# Backup falls .zshrc existiert und kein Symlink ist
|
||||||
|
if [ -e "$ZSHRC_TARGET" ] && [ ! -L "$ZSHRC_TARGET" ]; then
|
||||||
|
local_backup="$ZSHRC_TARGET.bak.$(date +%Y%m%d%H%M%S)"
|
||||||
|
echo "Bestehende .zshrc gefunden, erstelle Backup: $local_backup"
|
||||||
|
mv "$ZSHRC_TARGET" "$local_backup"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Entferne alten Symlink falls vorhanden
|
||||||
|
if [ -L "$ZSHRC_TARGET" ]; then
|
||||||
|
echo "Entferne alten Symlink..."
|
||||||
|
rm "$ZSHRC_TARGET"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Symlink erstellen
|
||||||
|
echo "Erstelle Symlink: $ZSHRC_TARGET -> $ZSHRC_SOURCE"
|
||||||
|
ln -s "$ZSHRC_SOURCE" "$ZSHRC_TARGET"
|
||||||
|
|
||||||
|
echo "=== Zsh Dotfiles installiert ==="
|
||||||
Loading…
Add table
Add a link
Reference in a new issue