|
1 | 1 | # git-stack |
2 | 2 |
|
3 | | -A Rust CLI tool to manage, update, and rollback a stack of Git branches. |
| 3 | +`git-stack` is a command-line tool for managing stacked git branches — a workflow where you develop |
| 4 | +features atop one another, keeping their history clean and rebasing as needed. It tracks |
| 5 | +relationships between branches, helps you re-stack and synchronize them, and visualizes your stack |
| 6 | +tree. |
4 | 7 |
|
5 | | -## Overview |
| 8 | +## Key Features |
6 | 9 |
|
7 | | -This tool manages a "stack" of related branches. It automates stacking, updating, and restoring |
8 | | -them. |
| 10 | +- Stacked Workflow: Track parent-child branch relationships ("stacks") in your repo. |
| 11 | +- Restack: Automatically rebase your branch stack on top of trunk or another branch. |
| 12 | +- Status Tree: Visualize your current stacked branches, their hierarchy, and sync status. |
| 13 | +- Branch Mounting: Change the parent branch of an existing branch in your stack. |
| 14 | +- Diffs: Show changes between a branch and its parent. |
| 15 | +- Safe Operations: Prevent accidental data loss by checking upstream sync status. |
9 | 16 |
|
10 | | -Main capabilities: |
| 17 | +## Installation |
11 | 18 |
|
12 | | -- Update (rebase and force-push) all branches in the defined stack atop `origin/main`, creating |
13 | | - backups before rebasing. |
14 | | -- Display summary info about the latest commit on each stack branch (`--verbose`). |
15 | | -- Roll back both stack branches to a backup version (`rollback` subcommand). |
| 19 | +Build from source (Rust required): |
16 | 20 |
|
17 | | -## Usage |
| 21 | +```bash |
| 22 | +cargo install --path . |
| 23 | +``` |
| 24 | + |
| 25 | +This will install a CLI you can use as follows: |
| 26 | + |
| 27 | +```bash |
| 28 | +git stack <command> [options] |
| 29 | +``` |
18 | 30 |
|
19 | | -```sh |
20 | | -# Stack/rebase and update all branches |
21 | | -cargo run --release |
| 31 | +## Usage |
22 | 32 |
|
23 | | -# Simply show the commit message for each stack branch |
24 | | -cargo run --release -- --verbose |
| 33 | +You can invoke `git-stack` directly or as a git subcommand: |
25 | 34 |
|
26 | | -# Roll back the stack to a previous backup (by backup version or 'origin') |
27 | | -cargo run --release -- rollback --version <backup-id> |
| 35 | +```bash |
| 36 | +git stack <subcommand> [options] |
28 | 37 | ``` |
29 | 38 |
|
30 | | -Typical Workflow: |
31 | | -1. All local changes must be committed or stashed. |
32 | | -2. When running, each stack branch is rebased on the previous one (starting from `main`). Backups |
33 | | - are made before rebasing. |
34 | | -3. If a conflict occurs during rebase, resolve conflicts and rerun. |
| 39 | +### Common Subcommands |
| 40 | + |
| 41 | +- `status`: Show the current stack tree in the repo. |
| 42 | + - _Default_, so `git stack` is equivalent to `git stack status`. |
| 43 | + |
| 44 | +- `checkout <branch>`: Create a new branch stacked on the current branch, or checkout an existing |
| 45 | + one in the stack. |
35 | 46 |
|
36 | | -## Arguments |
| 47 | +- `restack [--branch <branch>]`: Rebase the named (or current) branch and its descendents onto their |
| 48 | + updated stack base (like trunk or a parent feature branch). This command recursively applies to |
| 49 | + all ancestors of the given branch. |
37 | 50 |
|
38 | | -- `--verbose, -v` |
39 | | - Print current stack info and exit. |
| 51 | +- `mount [<parent-branch>]`: Mounts (attaches) the current branch on a different parent branch. |
40 | 52 |
|
41 | | -- `rollback --version <backup-id>` |
42 | | - Restore both branches in the stack to a prior state, using the given backup id (a timestamp or |
43 | | - `origin` for remote state). |
| 53 | +- `diff [<branch>]`: Show diff between a branch and its stack parent. |
44 | 54 |
|
45 | | -## Notes |
| 55 | +- `delete <branch>`: Remove a branch from the stack tree. |
46 | 56 |
|
47 | | -- Requires [Git](https://git-scm.com/) installed and accessible in `PATH`. |
| 57 | +### Examples |
| 58 | + |
| 59 | +#### See your stack status |
| 60 | + |
| 61 | +``` |
| 62 | +git stack status |
| 63 | +``` |
| 64 | + |
| 65 | +#### Create and stack a new branch |
| 66 | + |
| 67 | +``` |
| 68 | +git stack checkout my-feature |
| 69 | +``` |
48 | 70 |
|
49 | | -## Error Handling |
| 71 | +#### Restack your current branch |
50 | 72 |
|
51 | | -- Exits with an error if the git status is not clean. |
52 | | -- Exits if the stack branches do not exist or have no commits. |
53 | | -- On rebase failure, suggests manually resolving conflicts and rerunning. |
| 73 | +``` |
| 74 | +git stack restack |
| 75 | +``` |
54 | 76 |
|
55 | | -## Customization |
| 77 | +#### Change the parent stack of a feature branch |
56 | 78 |
|
57 | | -- To use with your repo/branches, change `GIT_ROOT` & `STACK` constants at the top of `main.rs`. |
| 79 | +``` |
| 80 | +git stack mount new-parent-branch |
| 81 | +``` |
58 | 82 |
|
59 | | ---- |
| 83 | +#### Show diff with parent |
60 | 84 |
|
61 | | -Example: |
62 | | -```sh |
63 | | -cargo run -- --verbose |
64 | | -# branch-01: ... |
65 | | -# branch-02: ... |
| 85 | +``` |
| 86 | +git stack diff my-feature |
| 87 | +``` |
66 | 88 |
|
67 | | -cargo run |
68 | | -# Rebases branch-01 & branch-02 in order, force-pushes both to origin. |
| 89 | +#### Remove a branch from stack management |
69 | 90 |
|
70 | | -cargo run -- rollback --version 1717682735 |
71 | | -# Restores both to the backup made at that timestamp. |
72 | 91 | ``` |
| 92 | +git stack delete my-feature |
| 93 | +``` |
| 94 | + |
| 95 | +## Stack Storage |
| 96 | + |
| 97 | +- Stack state is stored per-repo in a YAML file at: |
| 98 | + `~/.local/state/git-stack/state.yaml` (using XDG state dir conventions). |
| 99 | + |
| 100 | +## Requirements |
| 101 | + |
| 102 | +- A POSIX shell |
| 103 | +- git (on your `$PATH`) |
| 104 | +- Rust (to install/build) |
| 105 | + |
| 106 | +## Troubleshooting |
| 107 | + |
| 108 | +If `git stack` reports missing branches or refuses to restack: |
| 109 | + |
| 110 | +- Ensure your working tree is clean (`git status`). |
| 111 | +- Use standard git commands to resolve any rebase conflicts (`git mergetool` is your friend, |
| 112 | + followed by `git rebase --continue`), then rerun `git stack restack`. |
| 113 | + |
| 114 | +## License |
| 115 | + |
| 116 | +[GPL2](LICENSE) |
0 commit comments