You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A reading density, compact or comfortable. Body text was 12–13px and metadata went down to 9 and 10px, and the only answer was the zoom — which scales every pane together and makes a short window cramped sooner rather than later; the audit measured 900 × 600 as unusable before any zoom was applied. Settings › Appearance › Density now offers two, each previewing itself. Comfortable is what the app has always drawn, so nothing moves unless you ask it to. Compact takes away air, not letters: row heights come down (the graph from 28 to 24px, the whole left column from 26 to 22), the padding steps tighten, and the two body text sizes drop one step — while the smallest text does not move at all, because it was the thing that was too small in the first place. That one is fixed for everyone, at both densities: metadata that was 9 and 10px is 10 and 11px now. The graph follows properly rather than approximately — it reads the row heights back out of the stylesheet and re-lays its nodes and edges, so the commits stay aligned with the text they describe. (#195)
A journal of what happened to each repository, behind the bell. A toast was the only record of an operation: four fit on screen, the fifth pushed the first off for good, and a failed push read past four fetches later was simply gone. Every operation the app reports on — push, pull, fetch, merge, rebase, stash, commit, and everything else that raises a chip — is now also written down under the repository it ran on, and the bell is where you go back to it. Errors first, each line naming its repository and how long ago it was, the same words the chip used. An error chip carries a quiet Journal link to its own entry, so the chip is no longer the only copy; the bell's badge counts the failures of the repository on screen that have not been read, and opening it is reading them. With sessions, an operation that started on one repository and reports after you have switched away goes to its journal, not to whichever tab is in front — so it is waiting there when that tab comes back. Kept in memory for the session and bounded per repository: an error text is about a working tree as it was, and it can carry a path or a remote URL. (#193)
Changed
Opening a repository got faster, and opening one you have opened before is instant. A refresh was fourteen git processes in six waves, each waiting on the last — which on Windows, where starting git.exe costs an order of magnitude more than running it, is where the time went. It is five processes in two waves for a clean working tree, seven for a dirty one, and a test holds those numbers down. What went: the signature verification — %G? is not a field but a verification, one gpg process per signed commit, and nothing has drawn the result since the badge was removed on 28/08/2026; on this repository's own history a 200-commit page was 580 ms with it and 150 ms without, and a repository whose merges all come from the GitHub button is signed on every row. The second git status — the conflict list and the working changes each asked for their own, and on NTFS behind a virus scanner that is the slowest read the app makes, done twice. Two diffs of nothing — the staged and unstaged line counts were read beside the status rather than after it, so a clean tree paid for both. Three processes recomputing ahead/behind that the branch list already had. Two questions that cannot change while a repository is open — where its .git is, and whether it has a HEAD — now asked once instead of on every refresh. And the branch list is one for-each-ref instead of git branch -a --verbose plus a second call: out of plumbing rather than out of a sentence written for humans, which also retires the repair that turned * (HEAD detached at 1a2b3c4) into a branch called (HEAD. The six waves are two, with the graph alone in the first — firing all six together was tried and measured and cost 85 ms, because five more git processes take CPU and disk from the one query you are waiting for. Measured end to end on a 20,000-commit repository: 178 ms to 168 ms here, where none of the commits are signed and the working tree is one file — the changes that do the most are the ones this machine cannot show.
The graph a repository had last time is on screen before git says a word. The same 20,000 commits open in 42 ms on a later visit instead of 168, because the previous graph is drawn in the first frame while the real one is being read. Nothing is skipped and no answer is taken from the cache: the refresh runs exactly as it would have, silently, and replaces what is drawn when it lands. What is not kept is the working tree — conflicts, the conflict mode, the count of uncommitted files — because those change while the app is closed, and a stale conflict banner is a wrong statement rather than a slightly old graph. Six repositories, a page of commits each, thirty days; closing a repository forgets it.
Git's own caches, for repositories that need them — Settings › Behaviour › Speed up large repositories. Past a certain size the app's own cost stops being the story: git status walks the working tree, and on NTFS behind a virus scanner walking a large one is seconds however few times it is asked. Git has an answer, core.fsmonitor — a daemon that watches the tree so status stops walking it — and it is off by default in every repository. Switching this on writes it, plus fetch.writeCommitGraph, into each repository the first time it is opened, and writes that repository a commit-graph so history can be walked by generation number instead of by opening every commit object. Off unless asked for, because this goes into the repository's own config and every git client on the machine reads it afterwards; the row names the keys, the way the identity fields do, and git config --unset undoes it. A value you set yourself is never replaced — it is very possibly a path to your own hook. Nothing is written where git cannot support it: the daemon is git 2.37 and later, on Windows and macOS. core.untrackedCache is deliberately not in the list, although it belongs there on merit: git's own test for whether a filesystem can carry it writes a file into the working tree and sleeps on it for six seconds, and a feature meant to be invisible does not do that behind your back. And beside it, on Windows only, the thing this application cannot fix. Defender's real-time protection inspects every file as it is opened, and git status on a large repository opens all of them — which is why the same repository with the same git is quick on one machine and slow on another. Excluding the folder your repositories live in routinely beats everything above put together. The note says so, gives the one-line PowerShell for it, says what it does and does not cover and how to undo it — and copies rather than runs it: it changes the machine's security settings, which belongs to whoever owns the machine.
A build running in an open window no longer buys a refresh every 1.5 seconds. The working-tree watcher is recursive, so it saw node_modules, dist, coverage output and every other thing the repository ignores — and each of those was answered with a full refresh. What the watcher collects is now put to git check-ignore first, one process for the whole batch, with the answer per path remembered so an ordinary edit pays once and a build pays once for its files. The authority is git rather than a list of directory names, because dist is ignored in one repository and committed in the next. Everything uncertain still refreshes: git failing to answer, a batch too large to be an edit, or a .gitignore in it. The watcher inside .git got the same treatment for what cannot be news on its own: object writes and lock files. A fetch writes thousands of loose objects, and because the debounce is trailing they did not merely cost events — they held the refresh back until the fetch finished. That last one is also a fix — the watcher's test for the .git directory matched by prefix, so an edit to .gitignore or .gitattributes never refreshed anything, and those are the two files in the tree that change what the staging area shows.
The two products now run one implementation of a diff. Reading a commit, comparing two refs, listing what a comparison touched, a working-tree diff, a stash's patch, a blame, a search through diffs: the desktop app and the VS Code panel each had their own copy of all of it, and the copies drifted — the blame dates above are what that looks like from the outside. There is one now, shared, with each product keeping only its own way of reaching git. Nothing about what these produce was meant to change beyond the fix above. (#191)
Fixed
Blame dates are written in English again.Blame in the commit panel dated every line with the French calendar — 11/09/2026, read as the 11th of September by a UI that is English-only everywhere else, and as the 9th of November by anyone who took it at face value. The VS Code panel, running the same view, had always written 9/11/2026. The date is no longer taken from the machine the app happens to run on. (#191)