Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 56 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,17 @@ git volume status

## 📖 Commands

| Command | Description |
| ------------------- | -------------------------------------------------------- |
| `git volume init` | Create global directory and sample configuration file |
| `git volume sync` | Mount volumes to current worktree based on configuration |
| `git volume unsync` | Remove mounted volumes (modified files are preserved) |
| `git volume status` | Display current volume status |
| Command | Description |
| -------------------------- | -------------------------------------------------------- |
| `git volume init` | Create global directory and sample configuration file |
| `git volume sync` | Mount volumes to current worktree based on configuration |
| `git volume unsync` | Remove mounted volumes (modified files are preserved) |
| `git volume status` | Display current volume status |
| `git volume global add` | Copy files to global storage (`~/.git-volume`) |
| `git volume global list` | List files in global storage (tree view) |
| `git volume global edit` | Edit a file in global storage with `$EDITOR` |
| `git volume global remove` | Remove files from global storage (alias: `rm`) |
| `git volume version` | Print version information |

## ⚙️ Configuration File (`git-volume.yaml`)

Expand All @@ -76,6 +81,12 @@ volumes:
- mount: "secrets/prod.key:config/prod.key"
mode: "copy" # link (default) or copy

# Mount from global storage (~/.git-volume)
- "@global/secrets/prod.key:config/key"

# Directory mount (copies entire directory)
- mount: "configs:app/configs"
mode: "copy"
```

### Mode Comparison
Expand All @@ -102,12 +113,48 @@ cd ../feature-branch
git volume sync # uses parent's git-volume.yaml
```

## 🌐 Global Storage

Global storage (`~/.git-volume`) allows sharing files across multiple projects using the `@global/` prefix.

```bash
# Add files to global storage
git volume global add .env
git volume global add .env.local --as .env
git volume global add .env config.json --path myproject

# List, edit, and remove
git volume global list
git volume global edit config.json
git volume global remove old-secret.key
```

Use `@global/` in your configuration to reference these files:

```yaml
volumes:
- "@global/.env:.env"
- mount: "@global/secrets/prod.key:config/key"
mode: "copy"
```

## 🔧 CLI Options

| Flag | Commands | Description |
| ----------------- | ---------------- | ---------------------------------------------- |
| `--dry-run` | `sync`, `unsync` | Show what would be done without making changes |
| `--relative` | `sync` | Create relative symlinks instead of absolute |
| `--verbose`, `-v` | All | Verbose output |
| `--quiet`, `-q` | All | Suppress non-error output |
| `--config`, `-c` | All | Custom config file path |

## 🛡️ Safety Features

- **Symlink Source Rejection**: `sync` and `global add` reject symlink sources for security
- **Change Detection on Unsync**: Files copied in copy mode are preserved if modified
- **Change Detection on Status (Copy Mode)**: `status` reports `MODIFIED` when copied targets differ from source
- **Idempotent**: Running `sync` multiple times is safe
- **Path Traversal Prevention**: All paths are validated to prevent directory escape attacks
- **Change Detection on Unsync**: Copied files and directories are preserved if modified
- **Change Detection on Status**: `status` reports `MODIFIED` when copied targets differ from source
- **Idempotent Sync**: Running `sync` multiple times always produces the same result

## 📄 License

Expand Down
1 change: 0 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ var rootCmd = &cobra.Command{
by dynamically mounting them using a git-volume.yaml manifest.

"Keep code in Git, mount environments as volumes."`,
SilenceErrors: true,
}

// Execute adds all child commands to the root command and sets flags appropriately.
Expand Down
6 changes: 3 additions & 3 deletions cmd/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

var (
dryRun bool
syncDryRun bool
relativeLinks bool
)

Expand All @@ -34,14 +34,14 @@ it looks for it in the main Git worktree (inheritance).`,
}

return gv.Sync(gitvolume.SyncOptions{
DryRun: dryRun,
DryRun: syncDryRun,
RelativeLinks: relativeLinks,
})
},
}

func init() {
rootCmd.AddCommand(syncCmd)
syncCmd.Flags().BoolVar(&dryRun, "dry-run", false, "show what would be done without making changes")
syncCmd.Flags().BoolVar(&syncDryRun, "dry-run", false, "show what would be done without making changes")
syncCmd.Flags().BoolVar(&relativeLinks, "relative", false, "create relative symlinks instead of absolute")
}
7 changes: 5 additions & 2 deletions cmd/unsync.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import (
"github.com/spf13/cobra"
)

// unsyncDryRun is the local flag for the unsync command
var unsyncDryRun bool

// unsyncCmd represents the unsync command
var unsyncCmd = &cobra.Command{
Use: "unsync",
Expand All @@ -29,12 +32,12 @@ to the source before deleting. If changed, it skips deletion to prevent data los
}

return gv.Unsync(gitvolume.UnsyncOptions{
DryRun: dryRun,
DryRun: unsyncDryRun,
})
},
}

func init() {
rootCmd.AddCommand(unsyncCmd)
unsyncCmd.Flags().BoolVar(&dryRun, "dry-run", false, "show what would be done without making changes")
unsyncCmd.Flags().BoolVar(&unsyncDryRun, "dry-run", false, "show what would be done without making changes")
}
105 changes: 77 additions & 28 deletions docs/translations/README_de.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
> 🌐 [English](../../README.md) | [한국어](README_ko.md) | [日本語](README_ja.md) | [中文](README_zh.md) | [Español](README_es.md) | [Português](README_pt.md) | [Français](README_fr.md) | [Deutsch](README_de.md) | [Italiano](README_it.md)
> 🌐 [English](../../README.md) | [한국어](README_ko.md) | [日本語](README_ja.md) | [中文](README_zh.md) | [Español](README_es.md) | [Português](README_pt.md) | [Français](README_fr.md) | [Italiano](README_it.md)

# git-volume

> **"Behalte den Code in Git, mounte deine Umgebung als Volumes."**
> **Code in Git, Umgebung als Volumes."**

`git-volume` ist ein CLI-Tool zur zentralen Verwaltung von Umgebungsdateien (`.env`, Secrets usw.) über Git-Worktrees hinweg und deren dynamischem Mounten.
`git-volume` ist ein CLI-Tool, das Umgebungsdateien (`.env`, Secrets usw.) zentral über Git-Worktrees hinweg verwaltet und dynamisch einbindet.

## ✨ Hauptmerkmale
## ✨ Hauptfunktionen

- **Volume-Mounting**: Unterstützt symbolische Links oder Dateikopiermodi
- **Konfigurationsvererbung**: Untergeordnete Worktrees erben automatisch die Einstellungen der Eltern
- **Sicheres Aufräumen**: Geänderte Dateien bleiben beim Unsync erhalten
- **Optimiert für KI-Agenten**: Worktree erstellen + Umgebung konfigurieren mit einem einzigen Befehl
- **Volume-Mounting**: Unterstützung für symbolische Links oder Dateikopien
- **Konfigurationsvererbung**: Kind-Worktrees erben automatisch die Eltern-Konfiguration
- **Sichere Bereinigung**: Vom Benutzer geänderte Dateien werden nicht gelöscht
- **KI-Agenten-optimiert**: Worktree erstellen + Umgebung konfigurieren mit einem einzigen Befehl

## 📦 Installation

Expand All @@ -33,7 +33,7 @@ go install github.com/laggu/git-volume@latest

## 🚀 Schnellstart

**1. Initialisieren**
**1. Initialisierung**
```bash
git volume init
```
Expand All @@ -46,7 +46,7 @@ volumes:
mode: "copy"
```

**3. Volumes mounten**
**3. Volumes einbinden**
```bash
git volume sync
```
Expand All @@ -58,12 +58,17 @@ git volume status

## 📖 Befehle

| Befehl | Beschreibung |
| ------------------- | --------------------------------------------------------------------- |
| `git volume init` | Erstellt das globale Verzeichnis und eine Beispielkonfigurationsdatei |
| `git volume sync` | Mountet Volumes im aktuellen Worktree basierend auf der Konfiguration |
| `git volume unsync` | Entfernt gemountete Volumes (geänderte Dateien bleiben erhalten) |
| `git volume status` | Zeigt den aktuellen Volume-Status an |
| Befehl | Beschreibung |
| -------------------------- | ------------------------------------------------------------------- |
| `git volume init` | Globales Verzeichnis und Beispielkonfiguration erstellen |
| `git volume sync` | Volumes basierend auf Konfiguration im aktuellen Worktree einbinden |
| `git volume unsync` | Eingebundene Volumes entfernen (geänderte Dateien bleiben erhalten) |
| `git volume status` | Aktuellen Volume-Status anzeigen |
| `git volume global add` | Dateien in den globalen Speicher kopieren (`~/.git-volume`) |
| `git volume global list` | Dateien im globalen Speicher auflisten (Baumansicht) |
| `git volume global edit` | Eine Datei im globalen Speicher mit `$EDITOR` bearbeiten |
| `git volume global remove` | Dateien aus dem globalen Speicher entfernen (alias: `rm`) |
| `git volume version` | Versionsinformationen anzeigen |

## ⚙️ Konfigurationsdatei (`git-volume.yaml`)

Expand All @@ -76,36 +81,80 @@ volumes:
- mount: "secrets/prod.key:config/prod.key"
mode: "copy" # link (Standard) oder copy

# Aus globalem Speicher einbinden (~/.git-volume)
- "@global/secrets/prod.key:config/key"

# Verzeichnis-Mounting (kopiert gesamtes Verzeichnis)
- mount: "configs:app/configs"
mode: "copy"
```

### Modus-Vergleich
### Modusvergleich

| Modus | Beschreibung | Anwendungsfall |
| ------ | -------------------------- | ----------------------------------------------------- |
| `link` | Erstellt symbolischen Link | Lokale Entwicklung (Änderungen werden sofort wirksam) |
| `copy` | Kopiert Datei | Docker-Builds (Umgebungen ohne Symlink-Unterstützung) |
| Modus | Beschreibung | Anwendungsfall |
| ------ | --------------------------- | ----------------------------------------------- |
| `link` | Symbolischen Link erstellen | Lokale Entwicklung (Änderungen sofort wirksam) |
| `copy` | Datei kopieren | Docker-Builds (Umgebungen ohne Symlink-Support) |

## 🔄 Worktree-Vererbung

Wenn ein untergeordneter Worktree keine `git-volume.yaml` hat, verwendet er automatisch die Konfiguration des übergeordneten (Haupt-)Worktrees.
Wenn ein Kind-Worktree keine `git-volume.yaml` hat, wird automatisch die Konfiguration des Eltern-Worktrees (Haupt-Worktree) verwendet.

```bash
# Konfiguration existiert nur im Haupt-Worktree
main-repo/
├── .git/ # gemeinsames Git-Verzeichnis
├── .git/ # git common dir
├── git-volume.yaml # Konfigurationsdatei
├── .env.shared # Quelldatei
└── ...

# Das Ausführen von sync in einem untergeordneten Worktree verwendet die Eltern-Konfig
# Sync im Kind-Worktree verwendet die Eltern-Konfiguration
cd ../feature-branch
git volume sync # verwendet die git-volume.yaml des Eltern-Worktrees
git volume sync # verwendet git-volume.yaml des Eltern-Worktrees
```

## 🌐 Globaler Speicher

Der globale Speicher (`~/.git-volume`) ermöglicht das Teilen von Dateien über mehrere Projekte hinweg mit dem `@global/`-Präfix.

```bash
# Dateien zum globalen Speicher hinzufügen
git volume global add .env
git volume global add .env.local --as .env
git volume global add .env config.json --path myproject

# Auflisten, bearbeiten und entfernen
git volume global list
git volume global edit config.json
git volume global remove old-secret.key
```

## 🛡️ Sicherheitsmerkmale
Verwenden Sie `@global/` in Ihrer Konfiguration, um auf diese Dateien zu verweisen:

```yaml
volumes:
- "@global/.env:.env"
- mount: "@global/secrets/prod.key:config/key"
mode: "copy"
```

## 🔧 CLI-Optionen

| Flag | Befehle | Beschreibung |
| ----------------- | ---------------- | --------------------------------------------------- |
| `--dry-run` | `sync`, `unsync` | Zeigen was getan würde, ohne Änderungen vorzunehmen |
| `--relative` | `sync` | Relative statt absolute symbolische Links erstellen |
| `--verbose`, `-v` | Alle | Ausführliche Ausgabe |
| `--quiet`, `-q` | Alle | Nicht-Fehler-Ausgaben unterdrücken |
| `--config`, `-c` | Alle | Benutzerdefinierter Konfigurationsdateipfad |

## 🛡️ Sicherheitsfunktionen

- **Änderungserkennung beim Unsync**: Im Copy-Modus kopierte Dateien bleiben erhalten, wenn sie geändert wurden
- **Idempotent**: Das mehrmalige Ausführen von `sync` ist sicher
- **Ablehnung symbolischer Quellen**: `sync` und `global add` lehnen Quellen ab, die symbolische Links sind
- **Pfad-Traversal-Schutz**: Alle Pfade werden validiert, um Verzeichnis-Escape-Angriffe zu verhindern
- **Änderungserkennung bei Unsync**: Kopierte Dateien und Verzeichnisse werden beibehalten, wenn sie geändert wurden
- **Änderungserkennung bei Status**: Kopierte Dateien, die vom Original abweichen, werden als `MODIFIED` angezeigt
- **Idempotentes Sync**: Mehrfaches Ausführen von `sync` erzeugt immer das gleiche Ergebnis

## 📄 Lizenz

Expand Down
Loading