diff --git a/testworm/Archiv/README.md b/testworm/Archiv/README.md new file mode 100644 index 0000000..969a43e --- /dev/null +++ b/testworm/Archiv/README.md @@ -0,0 +1,29 @@ +# worm + +Write once, read many-Speicher + +## Ablauf ## +### Projektverzeichnisse vorbereiten ### +~~~ +mkdir mein_repo +cd mein_repo +git init +mkdir Archiv # Das ist dein WORM-Speicher im Git-Repo +mkdir Neu # Hier legst du temporär neue Dateien ab +~~~ + +### pre-commit-hook einrichten ### +Der Hook verhindert, dass Dateien in das Archiv aufgenommen werden, wenn dort bereits eine Datei mit gleichem Namen gespeichert ist. Siehe Datei "pre-commit". Sie __muss__ im Verzeichnis Projektverzeichnis/.git/hooks mit dem Dateinamen "pre-commit" gespeichert werden. +Der Hook muss ausführbar gemacht werden: +~~~ +chmod +x .git/hooks/pre-commit +~~~ + +### Die Scripte ### +> Beide Scripte verfügen nicht über einen _push_. + +#### Das Cron-Script einrichten #### +Um automatisiert Dateien dem WORM-Speicher zuzuführen, werden sie im Verzeichnis "Neu" gespeichert (auch Unterverzeichnisse). Cron sorgt für die Übertragung der Dateien von "Neu" nach "Archiv", die noch nicht im WORM-Speicher vorhanden sind (commit-wrapper.sh). Übertragene Dateien werden aus dem Verzeichnis "Neu/" gelöscht, nicht übertragene Dateien verbleiben dort. + +#### Interaktive Änderungen #### +Das Script commit-interactiv.sh macht das gleiche wie commit-wrapper.sh, allerdings fragt es bei jeder Datei, die schon im Archiv vorhanden ist, ob die Datei aus Neu/ mit einer Versionsnummer zusätzlich gespeichert werden soll. Diese Version des Scripts eignet sich nicht für einen cronjob. \ No newline at end of file diff --git a/testworm/archiv.log b/testworm/archiv.log new file mode 100644 index 0000000..3ac3afe --- /dev/null +++ b/testworm/archiv.log @@ -0,0 +1,3 @@ +[2025-06-25 20:42:36] ➔ Starte Archivierungslauf (cron-tauglich, rekursiv)... +[2025-06-25 20:42:36] ✅ 'Neu/README.md' nach 'Archiv/README.md' kopiert. +[2025-06-25 20:42:36] 🛋 'Neu/README.md' gelöscht. diff --git a/testworm/commit-interaktiv.sh b/testworm/commit-interaktiv.sh new file mode 100644 index 0000000..d43599d --- /dev/null +++ b/testworm/commit-interaktiv.sh @@ -0,0 +1,90 @@ +### 3 commit-interaktiv.sh (manuelle Nutzung) + +#!/bin/bash +set -euo pipefail + +cd "$(dirname "$0")" + +LOGFILE="archiv.log" +TIMESTAMP() { date '+%Y-%m-%d %H:%M:%S'; } + +log() { + echo "[$(TIMESTAMP)] $1" | tee -a "$LOGFILE" +} + +RESTORE_SCRIPT="./restore-archiv.sh" + +log "➔ Starte interaktive Archivierung..." + +find Neu/ -type f | while read -r file; do + relative_path="${file#Neu/}" + target="Archiv/$relative_path" + + base=$(basename "$file") + target_dir=$(dirname "$target") + mkdir -p "$target_dir" + + if [ -e "$target" ]; then + echo "⚠️ Datei '$relative_path' existiert bereits im Archiv." + + base_name="${base%.*}" + ext="${base##*.}" + if [ "$base_name" = "$ext" ]; then ext=""; else ext=".$ext"; fi + + version=2 + new_base="${base_name}_v${version}${ext}" + new_target="$target_dir/$new_base" + while [ -e "$new_target" ]; do + version=$((version + 1)) + new_base="${base_name}_v${version}${ext}" + new_target="$target_dir/$new_base" + done + + echo "Vorschlag zum Umbenennen: '$new_base'" + read -rp "▶️ Umbenennen? (j = ja, n = nein, sonst abbrechen): " answer + + if [[ "$answer" =~ ^[Jj]$ ]]; then + cp "$file" "$new_target" + log "✅ '$file' → '$new_target' (umbenannt)" + elif [[ "$answer" =~ ^[Nn]$ ]]; then + read -rp "Neuer Dateiname eingeben (ohne Pfad): " user_input + [ -z "$user_input" ] && log "⚠️ Abbruch durch Benutzer." && continue + custom_target="$target_dir/$user_input" + if [ -e "$custom_target" ]; then + echo "⚠️ '$user_input' existiert ebenfalls. Übersprungen." + log "⚠️ '$file' nicht archiviert (Name doppelt)." + continue + fi + cp "$file" "$custom_target" + log "✅ '$file' → '$custom_target' (benutzerdefiniert)" + else + log "⚠️ Abbruch durch Benutzer." + continue + fi + else + cp "$file" "$target" + log "✅ '$file' → '$target'" + fi + +done + +# Aufräumen +find Neu/ -type f -delete +find Neu/ -mindepth 1 -type d -empty -delete +log "🛋 Neu-Verzeichnis aufgeräumt." + +# Staging + Commit +git add --all +if git status --porcelain | grep . >/dev/null; then + if git commit -m "Manuelle Archivierung am $(TIMESTAMP)"; then + log "✅ Commit erfolgreich." + else + log "❌ Commit fehlgeschlagen. Starte Restore." + if [ -x "$RESTORE_SCRIPT" ]; then + "$RESTORE_SCRIPT" + log "♻️ Restore ausgeführt." + fi + fi +else + log "📥 Keine Änderungen zum Committen." +fi diff --git a/testworm/commit-wrapper.sh b/testworm/commit-wrapper.sh new file mode 100644 index 0000000..139b963 --- /dev/null +++ b/testworm/commit-wrapper.sh @@ -0,0 +1,60 @@ +### commit-wrapper.sh (für Cron) + +#!/bin/bash +set -euo pipefail + +cd "$(dirname "$0")" + +LOGFILE="archiv.log" +TIMESTAMP() { date '+%Y-%m-%d %H:%M:%S'; } + +log() { + echo "[$(TIMESTAMP)] $1" | tee -a "$LOGFILE" +} + +RESTORE_SCRIPT="./restore-archiv.sh" + +log "➔ Starte Archivierungslauf (cron-tauglich, rekursiv)..." + +# 1. Dateien rekursiv aus Neu nach Archiv kopieren, falls sie nicht existieren +find Neu/ -type f | while read -r file; do + relative_path="${file#Neu/}" + target="Archiv/$relative_path" + + if [ -e "$target" ]; then + log "⚠️ Datei '$relative_path' existiert bereits im Archiv. Übersprungen." + continue + fi + + mkdir -p "$(dirname "$target")" + cp "$file" "$target" + log "✅ '$file' nach '$target' kopiert." + rm "$file" + log "🛋 '$file' gelöscht." + +done + +# 2. Aufräumen leerer Unterverzeichnisse, aber nicht Neu/ selbst +find Neu/ -mindepth 1 -type d -empty -delete + +# 3. Alles zum Commit vormerken +git add --all +log "📍 Alle Änderungen vorgemerkt." + +# 4. Commit-Versuch +if git status --porcelain | grep . >/dev/null; then + if git commit -m "Archivierung automatisch am $(TIMESTAMP)"; then + log "✅ Commit erfolgreich." + else + log "❌ Commit fehlgeschlagen. Starte Restore." + if [ -x "$RESTORE_SCRIPT" ]; then + "$RESTORE_SCRIPT" + log "♻️ Restore ausgeführt." + else + log "⚠️ Restore-Skript nicht gefunden." + fi + exit 1 + fi +else + log "📥 Keine Änderungen zum Committen." +fi diff --git a/testworm/restore-archiv.sh b/testworm/restore-archiv.sh new file mode 100755 index 0000000..4789d66 --- /dev/null +++ b/testworm/restore-archiv.sh @@ -0,0 +1,37 @@ +#!/bin/bash +cd "$(dirname "$0")" + +LOGFILE="archiv.log" + +log() { + local TIMESTAMP + TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') + echo "[$TIMESTAMP] $1" | tee -a "$LOGFILE" +} + +log "🔄 Starte Wiederherstellung von Archiv-Dateien..." + +# Alle geänderten oder gelöschten Dateien (im Arbeitsverzeichnis oder Index) +changed_files=$(git diff --name-only Archiv) +staged_files=$(git diff --cached --name-only Archiv) + +all_files=$(echo -e "$changed_files\n$staged_files" | sort -u) + +if [[ -z "$all_files" ]]; then + log "ℹ️ Keine Änderungen an Archiv-Dateien gefunden." +else + for file in $all_files; do + if [[ ! -f "$file" ]]; then + # Datei wurde gelöscht -> Wiederherstellen + log "⏪ Stelle gelöschte Datei '$file' wieder her" + git restore --staged "$file" + git restore "$file" + else + # Datei existiert (modifiziert) -> zurücksetzen + log "⏪ Setze geänderte Datei '$file' zurück" + git restore --staged "$file" + git restore "$file" + fi + done + log "✅ Alle Änderungen an Archiv-Dateien wurden rückgängig gemacht." +fi