list
One line per clone: its name, its branch, how much is uncommitted, how much is unpushed, how long since anything happened in it, and what the copy cost when it was made. The first line is the canonical and says how far behind its upstream it is.
gitto list [--json] [--measure]One line per clone: its name, its branch, how much is uncommitted, how much is unpushed, how long since anything happened in it, and what the copy cost when it was made. The first line is the canonical and says how far behind its upstream it is.
$ gitto list
canonical storefront main 3 behind origin/main
auth-fix auth-fix dirty=0 unpushed=0 idle=12m new=60 MB
search-ranking feat/search dirty=3 unpushed=2 idle=6d new=210 MBdirty and unpushed count the submodules too, so a commit sitting in a
submodule that no remote has is in the number that decides whether the clone can
go.
What the disk figures mean
new= is what the copy consumed at the moment it was made, measured as the free
space the machine lost while it ran. It does not move afterwards. A clone that
has since installed and built has written over blocks it used to share, and the
figure has nothing to say about that.
--measure walks each clone with du and adds what it allocates now:
$ gitto list --measure
auth-fix auth-fix dirty=0 unpushed=0 idle=12m new=60 MB allocated=13 GBThat figure is an upper bound. du counts a shared block once for every file
that points at it, so two clones sharing a block are each charged for it, and
the walk costs a full directory traversal per clone.
Idleness
idle= is the time since the newest of three things: the last commit, the last
line written to the reflog, and the modification time of the clone's own
directory. It deliberately ignores .git/index, which git status rewrites,
because gitto list would then reset the number it was about to report.
Reading it as a machine
--json gives the same thing typed, with the name each command takes:
{
"canonical": { "path": "…", "branch": "main", "behind": 3 },
"clones": [
{ "name": "auth-fix", "branch": "auth-fix", "dirty": 0, "unpushed": 0,
"idleSeconds": 720, "diskKilobytesAtCreation": 61440, "path": "…" }
]
}new
Copies the canonical into `<canonical>-<name>` beside it, puts the copy on a new branch, and prints where it landed. The copy carries everything: history, submodules at every depth, dependencies, build output, and the files git was told to ignore.
sync
Fetches, moves the canonical forward when it can do so without a merge, and then runs whatever the project says brings it up to date. It holds the canonical alone while it runs, so no clone is copied out of a tree that is moving.