8Stash is a command-line tool designed to help you quickly save and share your work-in-progress with colleagues or friends. Throughout my career as a developer, especially during pair programming sessions, I often needed a fast way to hand over my current changes when switching drivers. I wanted to automate this process to avoid creating temporary commits or dealing with patch files, which led to the creation of 8Stash. This project was also a personal challenge to learn Go by building a practical tool. As the project evolves, contributions and suggestions to improve its architecture and align it further with Go best practices are highly encouraged.
The Idea and Goal of this Project is: having a simple command line tool that can quickly stash your current
work-in-progress changes, push them to a remote branch, and share them with others. The tool should be easy to use,
efficient, and integrate seamlessly into a developer's workflow.
Go was chosen as the language for 8Stash because its simplicity, speed, and portability align perfectly with the
project's goal of creating a reliable and efficient command-line tool for developers.
You can install the latest release of 8Stash with:
curl -sL https://raw.githubusercontent.com/TimothySpriegade/8stash/main/scripts/install_latest.sh | bash
Alternatively, build and install locally:
-
Clone the repository:
git clone git@github.com:TimothySpriegade/8stash.git
-
Install Go dependencies:
go mod tidy
-
Use the local install script
cd 8stash/scripts chmod +x scripts/build_install_locally.sh ./scripts/build_install_locally.sh
After installation, you can use 8Stash from the command line:
8stash [command] [options]
8Stash lets you quickly park your uncommitted work into a temporary remote branch, pick it up on another machine, and re‑apply it as local unstaged changes without polluting your main branch history.
Prerequisites:
- You are inside a Git repository with a clean syncable base (no unpushed divergent commits)
- You have uncommitted changes you want to share or move
- origin remote is available (SSH or HTTPS, preferably SSH)
Typical workflow:
- Save (push): Create a temporary branch from the current HEAD that contains exactly your current uncommitted changes; they are committed on that new branch, the branch is pushed to origin, and your original branch is restored to a clean state locally.
- Optionally add a descriptive message to your stash using the
-m
flag:8stash push -m "implementing login feature"
- The commit message will be displayed when listing stashes, making it easier to identify specific work-in-progress items
- Optionally add a descriptive message to your stash using the
- Share: Communicate the temporary branch number (e.g. 8stash/8374) to a teammate or switch machines and pull/fetch on the other clone.
- List (list): View available stash branches filtered by a naming convention (e.g. all starting with 8stash/) with human‑readable ages, author information, and commit messages to choose the right one.
- Apply (pop): Re‑apply a chosen stash branch onto your current branch so that its changes appear as unstaged modifications in your working directory; no merge commit and no history rewrite occur.
- Clean up: Applied stashes are removed localy and on remote to avoid messy repositories.
- Work: Inspect, edit further, stage, and create proper commits as desired.
- Repeat as needed for new slices of in‑progress work.
Behavior characteristics:
- Divergent histories are now supported: you can apply stashes even if your current branch has diverged from the stash base. The tool will attempt to merge changes, and you may need to resolve conflicts manually.
- Applying a stash does not advance or modify your current branch's commit history; it only repopulates the working tree.
- Relative age displays (e.g. minutes/hours/days ago) are based on the current system clock.
- Stash commit messages help you identify and organize your work-in-progress items across different contexts.
Ideal use cases:
- Pair programming driver handoff.
- Moving unfinished edits between desktop and laptop.
- Quick review handover without committing partial or experimental changes.
- Temporary parking of exploratory work prior to reshaping into clean commits.
- Annotating work-in-progress with descriptive messages for better organization.
Limitations to keep in mind:
- Not a replacement for long‑lived feature branches.
- Does not resolve underlying repository divergence; you must reconcile first.
- Large binary or generated assets will still be committed onto the temporary branch (consider .gitignore hygiene).
Use the 'help' command for further detailed usage instructions.
8stash help
Push with a descriptive message:
8stash push -m "WIP: refactoring user authentication"
Push without a message (uses default):
8stash push
# or simply
8stash
List all stashes (shows messages, authors, and timestamps):
8stash list
Pop a specific stash:
8stash pop 8374
Drop a stash you no longer need:
8stash drop 8374
Clean up old stashes:
8stash cleanup
# or skip confirmation prompt
8stash cleanup -y
# or override retention period
8stash cleanup -d 7
8Stash can be configured via a .8stash.yaml
file placed in your repository's root directory. This allows you to customize behavior like branch naming and cleanup policies on a per-project basis.
If no .8stash.yaml
is found, the application will use its default settings.
Example .8stash.yaml
:
branch_prefix: "project-wip/"
retention_days: 15
naming:
hash_type: "uuid" # "numeric" or "uuid"
hash_numeric_max_value: 99999
Key | Type | Description | Default |
---|---|---|---|
branch_prefix |
string | The prefix for all stash branches created by 8Stash. A trailing / is added automatically. |
8stash/ |
retention_days |
int | The number of days after which a stash is considered "old" and eligible for the cleanup command. |
30 |
naming.hash_type |
string | The format for generated stash IDs. Must be either "numeric" or "uuid" . |
"numeric" |
naming.hash_numeric_max_value |
int | The exclusive upper bound for randomly generated numeric stash IDs (e.g., a value of 10000 generates IDs from 0-9999). |
9999 |
Notes:
- The
retention_days
value can be temporarily overridden for a single run by using the-d
or--days
flag on thecleanup
command (e.g.,8stash cleanup -d 10
). - Confirmation prompts for the
cleanup
command can be skipped by using the-y
or--yes
flag (e.g.,8stash cleanup -y
). - If
naming.hash_type
is set to"uuid"
, thehash_numeric_max_value
is ignored. - The application will print a warning and clamp the value if
hash_numeric_max_value
is set above the maximum supported value (2,147,483,647
). - Invalid values in the config file will cause the application to fall back to the default settings for that specific key.
Contributions are welcome. 8Stash aims to be a simple and reliable CLI for sharing work in progress. Please open an issue to discuss larger changes, keep pull requests small and focused, add or update tests for new behavior, run go fmt and go test ./... before pushing, and update README.md when user facing changes are introduced. Check open issues and labels to find a good first task.
-
Clone the repository:
git clone git@github.com:TimothySpriegade/8stash.git
-
Install Go dependencies:
go mod tidy
-
Ensure that the project can be built
cd 8stash/cmd/8stash go build
or
cd 8stash/scripts chmod +x scripts/build_install_locally.sh ./scripts/build_install_locally.sh
This script can also be used during development to install the latest local version of 8Stash directly.
-
Ensure the install target (typically ~/bin or ~/.local/bin) is on your PATH:
export PATH="$HOME/bin:$HOME/.local/bin:$PATH"
-
Make sure the tests are working locally.
go test ./...
Thanks for contributing to 8Stash—every issue, discussion, and PR helps make it better. Happy hacking!
This project is my first experience with Go, so the code quality and structure may not be optimal. I am continuously learning and improving, and any feedback, suggestions, or contributions are always welcome and appreciated!