Drydock treats release state as a separate axis from dirty state
What's uncommitted, unpushed, and unreleased across every repo you own. A live TUI dashboard for a fleet of git repos.
At a glance
- What is it?
- Drydock is a terminal dashboard, written in Rust for macOS and Linux, that puts every git checkout you own on one screen and colour-codes what is outstanding in each. The design decision that makes it more than a git status loop is separating two questions that most tools conflate: is this repository dirty, and is it released. Four release states get their own column, and an explicit hold lets you say a commit is not worth shipping.
- Who is it for?
- Drydock fits someone with dozens of checkouts on disk who has lost track of which ones have work sitting in them, especially side branches, and who wants one screen rather than a loop of status commands. It does not fit a Windows user, and it does not fit someone who wants the tool to act on what it finds, because the history view is explicitly read-only and the actions are limited to fetching and opening things elsewhere.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 10 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 3, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Four release states get their own column
The distinctive part of this tool is that being clean and being released are different questions. Every repository sits in one of four release states, shown in a column of their own. A repository with no tags at all is marked unreleased and has simply never been released. One that is tagged with nothing since is marked released. One that is tagged but has commits or uncommitted changes past the tag is marked as needing release. And one that is past its tag where you have declared the commit not worth releasing is marked held. Alongside that column you get the commits since the last tag with their real subject lines, and a flag for whether the changelog file has run ahead of the newest tag. The consequence is stated plainly: a repository can be dirty and released, or spotless and still needing a release. Two filter keys cover the three actionable states, and one key toggles a repository in and out of the held state, which is how a personal judgement becomes durable instead of something you re-derive every morning.
Unpushed is measured across every branch, not the checked-out one
Most status tooling answers the question you asked about the branch you happened to be on. This one answers the question you actually have, which is whether work is stranded anywhere in the checkout. The unpushed check spans every local branch, and the README is blunt about why: side branches are exactly where work goes missing. The detail pane agrees, listing branches alongside the commits since the last tag and the files that changed. Colour does the rest of the work, and the scheme is deliberately loud only where it should be. Yellow marks uncommitted changes, cyan marks commits you have not pushed, a bold light red marks commits waiting on the remote, magenta marks commits past the last tag, and red is reserved for conflicts and half-finished merges. Everything clean is dimmed out of the way, so a screen of a hundred repositories is readable at a glance and the rows worth acting on are the ones that survive a squint.
Recent means something different for a clean repo
There is a subtlety in the activity filter that is easy to miss and changes how you read the column. When you filter to the last hour, day, week or month, the tool does not simply look at commit dates. For a clean repository, activity is its newest commit. For a dirty one, activity is when you last saved a changed file, which the README notes is usually much more recent. So a repository where you have been editing for three days without committing shows up as touched today, while a repository you committed to yesterday and have not touched since shows up under yesterday. That is the correct behaviour for the question being asked, which is what did I work on, and it is different from what a log-based filter would report. Alongside the recency filters there is a key for repositories with nothing outstanding at all, a fuzzy search over name, group and branch, keys to step through groups, and a key that switches between matching any active filter and all of them.
--root replaces the configured roots rather than adding to them
The root flag has one behaviour that will surprise you if you assume otherwise: given even once, it replaces the configured roots instead of adding to them, so a single flag is enough to inspect a tree the tool has never seen. It can be passed more than once to build a different set, and it can go before or after a subcommand, so the same flag works for the dashboard and for the list output. Each distinct set of roots maintains its own cache file, which means a one-off run against a client directory does not cost your main fleet its warm start, and repeating the same set is still instant. Roots expand a home directory marker and environment variables, in the configuration file as well as on the command line, and that single feature is what makes a popular checkout manager work. Point it at the root of the manager's tree and every repository lands in a group named after the host; point it one level deeper and the groups become the owner names, which is usually what you want.
It scans your configured roots, not your current directory
This is a deliberate choice and the README explains the reasoning: the tool scans the directories in your configuration rather than the current directory, so it behaves the same wherever you invoke it. A dashboard that only ever showed the repo you happened to be standing in would not answer the question it exists to answer. The default root is a projects directory under your home. There are three install routes. A Homebrew tap, a plain cargo install, or a source build whose make target installs into a local bin directory under your home with the force flag.
brew install yetidevworks/drydock/drydockgit clone https://github.com/yetidevworks/drydock
cd drydock
make install # into ~/.local/binPlatform support is macOS and Linux, and it is written in Rust with a single crate in a one-member workspace. The release profile is tuned for size and speed with thin link-time optimisation, a single codegen unit and symbol stripping, which is the profile you want for a binary people install globally.
The contextual footer needs a terminal that reports modifiers
One feature is explicitly conditional on your terminal, and the project says so rather than letting you discover it. Hold shift or ctrl and the hints along the bottom of the screen change to describe what those keys would do instead: the hint for opening in the file manager becomes the hint for opening in the editor, ctrl shows a terminal hint and the rest of its row. For that to work the terminal has to report a modifier being held on its own, which means a terminal implementing a specific keyboard protocol. The named list is kitty, Ghostty, WezTerm, iTerm2 from 3.5, and foot. Anywhere else the footer stays as the static list it always was, and the help key still lists everything. That is the right way to ship a progressive enhancement: the feature works where the terminal supports it, degrades to something still useful everywhere else, and never silently does nothing. It also means the keyboard map you read in the README is a superset of what a given terminal will show you.
The history view writes nothing, and merges diff against the first parent
The detail view is the most surprising part of the tool because it is a git client, and it is explicitly read-only. Pressing the history key on a row opens that repository's recent history full screen, with commits down the left beside a graph and the selected commit's contents on the right: author and date, the full message, the files with their line counts, and then the diff itself with line numbers. Its stated purpose is checking what has been going on in a repository without opening a separate git client window, and nothing in that view writes anything. Two details make it behave the way a reader would want. The list is the checked-out branch plus its upstream, so commits you have not pulled yet appear too, marked with their own colour and counted in the title. And a merge is diffed against its first parent, so it reads as what the merge brought in rather than as the combined state. A dirty repository gets an uncommitted entry at the top, and the view opens there, since that is usually what you wanted.
Editorial conclusion
Drydock fits someone with dozens of checkouts on disk who has lost track of which ones have work sitting in them, especially side branches, and who wants one screen rather than a loop of status commands. It does not fit a Windows user, and it does not fit someone who wants the tool to act on what it finds, because the history view is explicitly read-only and the actions are limited to fetching and opening things elsewhere. Before you rely on it, decide which root layout you are pointing it at, since the root flag replaces rather than extends the configured list, and set up the roots once in the config rather than passing the flag every time, because each distinct set of roots maintains its own cache.
Frequently asked questions
What does the drydock tool show me?
It is a terminal dashboard that lists every git checkout you own and flags what is outstanding in each: uncommitted changes, unpushed commits across every local branch, conflicts and half-finished merges, and commits sitting past the last tag. Repositories with nothing outstanding are dimmed so the actionable rows stand out.
Which platforms does drydock support?
macOS and Linux. It is written in Rust and can be installed with Homebrew, with cargo install, or by building from source, in which case the make target installs the binary into a bin directory under your home.
How does drydock decide a repository needs a release?
It compares the repository against its last tag. A repo with no tags is marked unreleased, one with a tag and nothing after it is released, one with commits or uncommitted changes past the tag needs release, and one you have explicitly held is marked as such with a keyboard shortcut.
Does the drydock root flag add to my configured folders?
No. Given even once it replaces the configured roots rather than adding to them, which is enough to inspect a tree the tool has never seen. You can pass the flag several times, and each distinct set of roots keeps its own cache so a one-off run does not cost your main fleet its warm start.
Can drydock show commits I have not pushed?
Yes, and it checks every local branch rather than only the one checked out, because side branches are where work goes missing. The unpushed commits get their own colour, and the detail view lists branches alongside the commits since the last tag and the files that changed.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/yetidevworks-drydock)