Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

stray

Find the git repositories on a machine that exist nowhere else.

A laptop accumulates repositories. Some are yours, most are not — vendored dependencies, clones you made to read someone else's code, checkouts of things you had forgotten. Of the ones that are yours, some are safely on a forge and some only look that way. stray sorts that out and tells you what you would lose if the disk died tonight.

The part people get wrong

A repository with a remote configured is not necessarily backed up.

$ git push
Everything up-to-date

That message is about your local branches. It says nothing about refs/remotes/* entries that have no local counterpart — branches you once fetched, or that a git clone --mirror brought along, which now live only in this copy. A plain git push never sends them. Neither does git push --all.

stray counts those separately, and treats a repository that has them as at risk even when every branch you can see is pushed:

$ stray risk inventory.json
/Users/you/src/parser        3 orphan refs
/Users/you/work/scheduler    remote gone, 2 unpushed
/Users/you/tmp/spike         no remote

It also checks whether the remote is still there at all — through the GitHub and GitLab APIs, not git ls-remote. Over SSH an auth failure and a deleted repository produce the same error, so ls-remote will report a perfectly healthy repository as gone the moment your credentials expire. The APIs distinguish 404 from 403.

Install

$ go install github.com/robintemme/stray/cmd/stray@latest

stray check shells out to gh and glab and uses whatever credentials they already hold. Everything else runs offline.

Use

$ stray scan ~/ -o inventory.json
$ stray check inventory.json -o inventory.json
$ stray report inventory.json -o report.html

Example summary (numbers are illustrative):

412 repositories under /Users/you
    31 yours
     9 at risk (gone remote, unpushed commits, or orphaned refs)
   347 vendored dependencies
    28 foreign clones
     7 directories with code but no repository

report writes a single self-contained HTML page: what is at risk and why, last commit per year, language mix.

What counts as yours

Whatever matches -me, checked against remote URLs and commit author lines:

$ stray scan ~/ -me yourhandle -me yourcompany.example

With no -me, stray derives it from git config user.email. Everything else is either vendored — it sits inside a dependency tree such as go/src, node_modules or vendor — or foreign, someone else's repository you cloned. Neither is your problem to back up.

Staying out of places

$ stray scan ~/ -exclude /Volumes/timemachine -exclude .sparsebundle

Anything matching an -exclude substring, by path or by remote URL, is recorded as a name and a byte count and nothing more. Nothing below it is opened. Useful for mounted backups, disk images, and network shares you would rather not have a tool walk through.

-skip adds directory basenames to the built-in list of caches and build output that is never descended into.

What it reads

Sizes and modification times come from stat. The only file stray ever opens inside a repository is .git/config, to learn the remote URLs; history comes from git itself. It never reads your source, and it sends nothing anywhere — check talks to the forges about repository names only.

License

MIT

About

Find the git repositories on a machine that exist nowhere else — including the branches git push silently leaves behind

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages