# Stash User Guide - Enhanced GNU Stow Replacement ## Table of Contents 1. [Introduction](#introduction) 2. [Installation](#installation) - [Using Guix](#using-guix) - [Manual Installation](#manual-installation) 3. [Shell Configuration](#shell-configuration) 4. [GNU Stow-like Features](#gnu-stow-like-features) - [Deploy Mode](#deploy-mode) - [Dot Syntax](#dot-syntax) - [Package Management](#package-management) 5. [Traditional Stashing](#traditional-stashing) 6. [Restoration](#restoration) 7. [Intelligent Stashing](#intelligent-stashing) 8. [Common Use Cases](#common-use-cases) 9. [Advanced Features](#advanced-features) 10. [Configuration](#configuration) 11. [Troubleshooting](#troubleshooting) 12. [Tips and Best Practices](#tips-and-best-practices) ## Introduction Stash is a powerful symlink management utility written in Guile Scheme that serves as an enhanced replacement for GNU Stow. It helps you organize your files by moving them to a target location while maintaining easy access through symbolic links. With intelligent stashing, restoration capabilities, and GNU Stow-like deployment features, it's perfect for managing dotfiles and any other directory organization needs. ### Why Use Stash? - **Keep Your Files Organized**: Move files to logical storage locations while maintaining easy access - **Backup with Access**: Store files in backup locations without changing your workflow - **Dotfile Management**: Perfect for managing configuration files across different machines - **Project Organization**: Archive old projects while keeping them accessible - **Cross-device File Management**: Safely manage files across different storage devices ## Installation ### Prerequisites - Guile Scheme 3.0.9 or later - Unix-like environment (Linux/macOS) ### Using Guix The recommended way to install Stash is using the Guix package manager: ```sh # Install from local package definition guix package --install-from-file=minimal-package.scm ``` After installation, the `stash` executable will be available in your Guix profile at `~/.guix-profile/bin/stash`. ### Manual Installation If you're not using Guix, you can install Stash manually: 1. Install prerequisites: ```sh # Debian/Ubuntu sudo apt-get install guile-3.0 # Fedora sudo dnf install guile30 # Arch Linux sudo pacman -S guile ``` 2. Clone and set up the repository: ```sh git clone https://codeberg.org/glenneth/stash.git cd stash mkdir -p ~/.guile.d/site/3.0 ln -s $(pwd)/modules/stash ~/.guile.d/site/3.0/ ``` ## Shell Configuration ### Fish Shell 1. Add to `~/.config/fish/config.fish`: ```fish # Guix environment setup set -gx GUIX_PROFILE $HOME/.guix-profile set -gx PATH $GUIX_PROFILE/bin $PATH # Load Guix environment variables if test -f $GUIX_PROFILE/etc/profile for line in (cat $GUIX_PROFILE/etc/profile | grep '^export' | string replace 'export ' '') set var (string split '=' $line) set -gx $var[1] (eval echo $var[2]) end end ``` 2. Alternative method using symlink: ```fish ln -sf ~/.guix-profile/bin/stash ~/.local/bin/stash ``` ### Bash Shell Add to `~/.bashrc`: ```bash # Guix environment setup export GUIX_PROFILE="$HOME/.guix-profile" if [ -f "$GUIX_PROFILE/etc/profile" ]; then . "$GUIX_PROFILE/etc/profile" fi ``` ### Zsh Shell Add to `~/.zshrc`: ```zsh # Guix environment setup export GUIX_PROFILE="$HOME/.guix-profile" if [ -f "$GUIX_PROFILE/etc/profile" ]; then . "$GUIX_PROFILE/etc/profile" fi ``` ## GNU Stow-like Features Stash provides enhanced GNU Stow replacement functionality with intelligent behavior and additional features. ### Deploy Mode Deploy mode (`-d`) allows you to batch deploy all packages from a dotfiles repository, similar to GNU Stow: ```sh # Deploy all packages from current directory cd ~/.dotfiles && stash -d # Deploy all packages with explicit path stash -d /path/to/dotfiles ``` **How it works:** - Scans the current directory for subdirectories (packages) - Creates symlinks from each package's contents to the home directory - Automatically handles directory structure creation - Skips system files like `.git`, `README.md`, etc. ### Dot Syntax The dot syntax (`.`) provides reverse symlinking - creating a symlink from the current directory back to its corresponding location in the home directory: ```sh # From within a dotfiles package directory cd ~/.dotfiles/shell stash . # Creates: ~/.shell -> ~/.dotfiles/shell ``` **Use cases:** - Quick reverse linking from dotfiles repo - Testing configurations before full deployment - Selective package activation ### Package Management Deploy specific packages by name: ```sh # Deploy only the shell package cd ~/.dotfiles && stash shell # Deploy only the emacs package cd ~/.dotfiles && stash emacs ``` **Package structure example:** ``` ~/.dotfiles/ ├── shell/ │ ├── zshrc │ └── bashrc ├── emacs/ │ ├── config.org │ └── init.el └── git/ └── gitconfig ``` ## Restoration Stash includes complete restoration capabilities with metadata tracking: ```sh # Restore a specific file stash -R -s ~/.files/config/app/config.yml # Restore using metadata stash -R -s /path/to/stashed/file ``` **Features:** - Each stashed file includes `.stash-meta` metadata - Metadata contains original path information - Automatic directory structure recreation - Safe restoration with conflict detection ## Intelligent Stashing Stash automatically detects existing symlinks and adapts its behavior: **File-level stashing:** When a directory already contains symlinks, stash operates at the file level to avoid "symlink to symlink" issues. **Directory-level stashing:** When no symlinks exist, stash can move entire directories. ```sh # First file - directory level stashing stash -s ~/.config/app/config.yml -t ~/.files # Second file - detects existing symlink, uses file-level stashing stash -s ~/.config/app/theme.json -t ~/.files ``` ## Traditional Stashing ### How Stash Works 1. **Source Directory**: The original location of your files 2. **Target Directory**: Where you want to store the files 3. **Symbolic Links**: Created in the source location, pointing to the target ### Key Terms - **Stashing**: The process of moving files to a target location and creating symlinks - **Dot Syntax**: A shorthand way to create symlinks for previously stashed files - **Recursive Mode**: Processing entire directory trees ## Usage Patterns ### 1. Interactive Mode Best for beginners or when you want to choose the target location interactively. ```sh stash --source ~/Pictures --interactive ``` ### 2. Explicit Paths When you know exactly where you want to store files. ```sh stash --source ~/Documents/notes --target ~/backup/notes ``` ### 3. Dot Syntax Quick way to create symlinks for previously stashed files. ```sh cd ~/.dotfiles/config/nvim stash . # Creates symlink in ~/.config/nvim ``` ### 4. Recursive Mode For processing entire directory trees. ```sh stash --source ~/.config --target ~/.dotfiles/config --recursive ``` ## Common Use Cases ### 1. Managing Dotfiles Keep configuration files in a git repository: ```sh # Initial stash stash --source ~/.config/nvim --target ~/.dotfiles/config/nvim # Later, on another machine cd ~/.dotfiles/config/nvim stash . ``` ### 2. Project Organization Archive old projects while keeping them accessible: ```sh stash --source ~/projects/old-webapp --target ~/archive/projects/webapp ``` ### 3. Cross-device File Management Store large files on external drives: ```sh stash --source ~/Videos --target /media/external/videos --recursive ``` ## Advanced Features ### 1. Path Handling - Supports home directory expansion (~) - Handles both absolute and relative paths - Maintains directory structure in target location ### 2. Symlink Management - Creates intermediate directories as needed - Handles existing symlinks gracefully - Preserves original file permissions ### 3. Ignore Patterns - Create `.stashignore` in source directory - Add patterns similar to `.gitignore` ```sh *.tmp .DS_Store node_modules/ ``` ### 4. Conflict Resolution - Automatically detects existing files/symlinks - Interactive prompts for resolution - Options to skip, replace, or backup ## Configuration ### Environment Variables - `GUILE_AUTO_COMPILE=0`: Disable auto-compilation - `GUILE_LOAD_PATH`: Add custom module paths - `GUIX_PROFILE`: Set Guix profile location ### Global Configuration - System-wide ignore patterns in `/etc/stash/ignore` - User-specific patterns in `~/.config/stash/ignore` ## Troubleshooting ### Common Issues and Solutions 1. **Command Not Found** - Verify Guix profile is sourced correctly - Check PATH includes `~/.guix-profile/bin` - Try creating symlink in `~/.local/bin` 2. **Module Loading Issues** - Ensure GUILE_LOAD_PATH includes module directory - Check module permissions and ownership - Verify Guile version compatibility 3. **Permission Errors** - Check file/directory permissions - Ensure write access to target location - Verify symlink creation permissions 4. **Common Warnings** - "canonicalize-path override": Normal, can be ignored - "auto-compilation enabled": Set GUILE_AUTO_COMPILE=0 ### Cross-device Issues - Use the recursive flag for cross-device operations - Ensure target location has sufficient space ## Tips and Best Practices 1. **Organization** - Keep related files together in the target location - Use meaningful directory names - Document your stash organization 2. **Backup** - Always back up important files before stashing - Test symlinks after creation - Use version control for dotfiles 3. **Maintenance** - Regularly check for broken symlinks - Keep your stash locations organized - Document your stash structure ## Command Reference ### Basic Commands ```sh stash --help # Display help stash --version # Show version stash --source DIR # Specify source directory stash --target DIR # Specify target directory stash --recursive # Process directories recursively stash --interactive # Interactive target selection ``` For more information or to report issues, visit: