Shell History Per Project
Code name:
shell-history-per-project
This DevContainer feature provides shell history persistence per project by mounting a shell directory and creating symbolic links internally. This ensures that your shell history is preserved across container rebuilds and is isolated per project.
Also included automatically: repairs broken host paths in your git config and restores your SSH commit-signing key on every attach, on both local and cloud containers, with nothing to set up on your end — see
helpers4-commonfor how it works.
When to use this
Section titled “When to use this”Use this when you work on several devcontainer projects on the same machine and don’t want one project’s shell history mixed in with another’s — each project gets its own history file, isolated and persisted independently.
Alternatives:
- Mounting your host’s real history file (
~/.zsh_history) directly is simpler, but every project ends up sharing the exact same history — commands from one project show up while you’re working in another. - stuartleeks/dev-container-features’
shell-historyfeature does something similar but globally, not per project — see Comparison below.
Features
Section titled “Features”- Per-project history isolation: Each project maintains its own shell history
- Multiple shell support: Supports zsh, bash, and fish shells
- Persistent across rebuilds: History is preserved when containers are rebuilt
- Configurable: Customizable history directory and size limits
- Symbolic link approach: Uses internal symbolic links for seamless integration
Add this feature to your devcontainer.json:
Options
Section titled “Options”| Option | Type | Default | Description |
|---|---|---|---|
shell | string | zsh | Shell type to configure (zsh, bash, or fish) |
historyDirectory | string | /workspaces/.shell-history | Directory where shell history will be persisted |
maxHistorySize | string | 10000 | Maximum number of history entries to keep |
Examples
Section titled “Examples”Basic usage with default zsh
Section titled “Basic usage with default zsh”Custom configuration
Section titled “Custom configuration”With volume mount
Section titled “With volume mount”For persistent history across different development sessions, you might want to add a volume mount:
How it works
Section titled “How it works”- Creates a persistent history directory: The feature creates a dedicated directory for storing shell history files
- Configures shell settings: Updates the shell configuration files to use the persistent history location
- Creates symbolic links: Links the default history file location to the persistent location
- Sets appropriate permissions: Ensures proper file permissions for the remote user
Supported shells
Section titled “Supported shells”- Zsh: Configures
.zsh_historywith optimal history settings includingSHARE_HISTORY,HIST_IGNORE_DUPS, etc. - Bash: Configures
.bash_historywithhistappendand duplicate handling - Fish: Configures
fish_historywith appropriate Fish shell settings
Directory structure
Section titled “Directory structure”After installation, you’ll have:
With symbolic links from the standard locations:
~/.zsh_history→/workspaces/.shell-history/.zsh_history~/.bash_history→/workspaces/.shell-history/.bash_history~/.local/share/fish/fish_history→/workspaces/.shell-history/fish_history
Benefits over global history mounting
Section titled “Benefits over global history mounting”Unlike mounting the user’s global shell history, this approach provides:
- Project isolation: Each project maintains its own command history
- Team collaboration: History can be shared among team members if desired
- Context relevance: Commands are relevant to the specific project
- Clean development: No mixing of personal and project commands
- Flexibility: Easy to configure different settings per project
Comparison with stuartleeks/dev-container-features shell-history
Section titled “Comparison with stuartleeks/dev-container-features shell-history”This feature differs from the existing shell-history feature by:
- Project-scoped: History is isolated per project instead of global user history
- Internal symbolic links: Uses symbolic links internally rather than mounting user’s home directory
- Collaborative: Can be shared with team members through project setup
- Configurable location: Allows customization of where history is stored within the project
Contributing
Section titled “Contributing”This feature is part of the helpers4/devcontainer-features repository. Contributions and issues are welcome!
Version History
Section titled “Version History”- v1.2.3: Documentation only, no functional change — added a “When to use this” section with alternatives, matching the equivalent sections other features in this catalog already had.
- v1.2.2: Documentation only, no functional change — the previous wording sweep made the
JSON
descriptionfield far too long, shifting focus away from the feature itself onto the self-heal side benefit. Shortened to 5 words and kept generic (no implementation detail like “git config”), matching the original’s brevity and level of detail. - v1.2.1: Documentation only, no functional change — the self-heal callout above (and the
JSON
descriptionfield) led with internal jargon (“helpers4’s self-heal”) instead of the actual benefit; reworded to lead with what it does, with the full mechanism staying inhelpers4-common’s own README. - v1.2.0: Documentation only, no functional change — mentions that
helpers4-common’s automatic git-config self-heal (see above) now comes along with this feature. - v1.1.0: Switched from an inline copy of
helpers4-common’s bootstrap (user detection, apt helpers) to a directdependsOnon thehelpers4-commonfeature — no behavior change, just a single source of truth for that logic instead of a copy every feature had to keep in sync.
