Skip to content

Releases: gfazioli/findergit-website

FinderGit 0.30.0

Choose a tag to compare

@gfazioli gfazioli released this 07 Sep 15:25

GitLab and Bitbucket, with nothing to set up

FinderGit already read GitHub with your own credentials and Codeberg with none at all. It now reads GitLab and Bitbucket the same way Codeberg is read — anonymously — so a folder of clones from any of the four fills in its columns on its own.

Open a folder with a GitLab project in it and the Issues, Pull Requests and Stars columns populate. No account to connect, no token to paste. The Issues and Pull Requests tabs work there too, with labels, authors, drafts and state — merge requests included, since that is what GitLab calls them. The Overview tab fills in description, stars, forks, topics and the latest release, and the fork badge names the repository a fork came from.

GitLab projects nested in subgroupsgroup/team/project — are recognised as the one repository they are, rather than being skipped.

Bitbucket works the same way for pull requests, with the full comment thread in the preview, inline review notes included.

What each forge can honestly answer

The interesting part of adding two forges is what they refuse, and this release is careful about it in a way that is visible on screen:

  • Bitbucket has no issue tracker any more. Its API was retired in August 2026, so the Issues tab says so and the Issues column stays empty on Bitbucket repositories — not zero. An empty cell is the truth; a zero would be a claim about a tracker that no longer exists.
  • Bitbucket has no stars. The closest number it keeps is watchers, which appear on the Overview under their own name rather than borrowed into a column headed Stars.
  • A fork is never called up to date unless somebody measured it. Only GitHub reports how far a fork trails its upstream. On the other three the banner now says the drift is not available there, instead of showing a green check nobody earned — which is what it used to do.
  • GitLab shows comments only to a signed-in user, even on public projects, so the preview says so rather than failing.

The same rule now runs through the columns generally: a count that could not be obtained shows nothing rather than zero, whatever the reason — a forge that has no such concept, a header the API omits past ten thousand results, or a request refused by a rate limit.

Also in this release

  • Comment threads show the right faces. An author's picture comes from the forge the repository actually lives on, so the same username on two different forges is no longer drawn as the same person.
  • The sidebar filters gain GitLab and Bitbucket beside GitHub and Codeberg, each with its count.

Known limits

  • Only the hosted services are recognised. A self-hosted GitLab or Bitbucket Server remote is treated as a repository with no forge, and its columns stay empty.
  • Bitbucket allows an anonymous caller 60 requests an hour, and a repository row costs three of them. Roughly twenty Bitbucket clones exhaust the hour on a single paint; the cells then wait and fill in later. GitLab is generous by comparison and Codeberg has never been a problem.
  • Private repositories on GitLab and Bitbucket are invisible without an account — both answer "not found" to an anonymous caller, exactly as they do for a repository that does not exist.

Signing in per forge would lift most of these; it is the next thing in this area.

Under the hood

Every capability above was measured against the live APIs rather than read off documentation, and the numbers are in the pull request. The release also carries a fix to the branch-pruning script the release pipeline runs, which could delete a local branch whose only copy of some work was local.

Verify this download

Compare the checksum of the file you downloaded:

shasum -a 256 FinderGit-0.30.0.dmg

It must print exactly:

7ad3fa9769086afc379dabc13a49b62f45f4a062a184d71aaf80c54d70248961

The DMG is also signed with an Apple Developer ID and notarized by Apple, which you can confirm without installing it:

spctl -a -vv -t open --context context:primary-signature FinderGit-0.30.0.dmg

That reports source=Notarized Developer ID for a genuine build.

FinderGit 0.29.0

Choose a tag to compare

@gfazioli gfazioli released this 04 Sep 12:02

New

If a row does something, it now says so.

Lists you can click light up under the pointer, everywhere: the branch list, the changed files, the stash entries, the clone picker, the settings, the breadcrumb. It sounds small and it is the difference between a list you read and a list you use — before this, several of those rows responded to a click with nothing on screen suggesting they would, and nothing telling you which one you were on.

The same pass made whole rows clickable where only a word used to be. A file in the Unstage tab opens its diff from anywhere on the row, not just from the characters of its path.

Open a commit the way you open a folder.

Every commit in the Commits tab has a disclosure chevron. Open it and the files that commit touched unfold underneath, with a N files · +added −removed summary on top and, per file, git's own status letter, the path, the old name on a rename, and that file's own line counts. Binary files say binary rather than pretending to a count.

Click a file and its diff for that commit opens in a sheet — the same viewer the working-tree diff uses, scoped to what this one commit did to this one file. It is read-only: nothing here stages, discards or reverts. What a commit removed is often the part worth reading, so deleted files open too.

The list is fetched only when you open a row, so the tab costs the same however far you scroll. Merge commits list what they brought in rather than the nothing they used to.

The Branches tab was rebuilt.

The branch you are on is pinned at the top in its own card, with its upstream and how far ahead or behind it is, so it never scrolls away. Local and Remote are separate groups, each with a count and separated rows, instead of two captions over undifferentiated text. Checking a branch out is a click anywhere on its row.

Read an issue or a pull request without leaving FinderGit.

A row opens in place onto the full description, rendered as Markdown — headings, lists, links, code — under the author and when they filed it, followed by the discussion. A long description folds behind Show more so one verbose issue cannot push the rest of the list off screen.

On a pull request that means the whole conversation: the body a reviewer submitted with their verdict and the notes pinned to lines of a file, each labelled for what it is, not just the comments tab. A pull request reviewed entirely inline — which is how most of them are — used to look as though nobody had said a word.

Open in browser and Copy link sit underneath for the parts FinderGit does not render. Images in a description are deliberately not downloaded: an issue body is written by anyone who can open an issue, and fetching an image it names would tell that person your IP address and when you read it.

Everything above is translated into Italian, French, German and Spanish.

Fixed

A way to lose work. Discarding a file whose name contains *, ? or [...] could revert an unrelated file that happened to match — and Discard has no undo. The same slip made Stage act on more files than you picked, and made a single file's diff show its neighbours' changes under the wrong name. Every path FinderGit hands back to git is now taken literally. If you have never named a file that way this never touched you; if you have, it did so silently.

A branch that was not a branch. The Branches tab listed origin among the remote branches, with a Checkout button git would have refused. It was the remote's own name leaking through a filter that could never match.

Wrong grammar in four languages. The file-status badge in a commit shared a translation with the panel that counts how many repositories are dirty, so a tooltip about one file read as a plural in Italian, French and Spanish. English showed nothing wrong, which is why it survived until now.

A commit whose file list could not be trusted is now refused rather than shown. If a path in it cannot be decoded, clicking it would have opened another file's diff or none at all.

Under the hood

  • Comments merged from three sources keep distinct identities, so none is silently dropped from a discussion.
  • Refresh on the Issues and Pull Requests tabs now reaches a thread you already have open, instead of only the list behind it.
  • Expanding a commit cancels its file load when you collapse it, so walking a long history no longer leaves a screenful of git processes racing each other.
  • Empty and space-only strings no longer enter the translation catalogue as keys nothing can translate. All three catalogues now read 100% in every supported language.
  • 453 tests.

Verify this download

Compare the checksum of the file you downloaded:

shasum -a 256 FinderGit-0.29.0.dmg

It must print exactly:

fa71e59120a489cd66be82cf442c1a4776192fdacebae7e26013904068b43921

The DMG is also signed with an Apple Developer ID and notarized by Apple, which you can confirm without installing it:

spctl -a -vv -t open --context context:primary-signature FinderGit-0.29.0.dmg

That reports source=Notarized Developer ID for a genuine build.

FinderGit 0.28.0

Choose a tag to compare

@gfazioli gfazioli released this 31 Aug 12:21

New

Stash — set the working tree aside without committing it.

The Unstage tab now carries a Stash… button beside Stage All and Discard All, because it is the third answer to the same question — what do I do with these changes right now — and the only one that is neither destructive nor a commitment. Give the stash a message, or leave it blank and let git name it after your last commit. Untracked files go along, so the tree is genuinely clean afterwards rather than half-stashed.

Everything you have set aside is listed under the commit box as Stashed changes (N), collapsed until you want it. Each entry shows the branch it came from, how long it has been waiting, and a quiet Automatic badge when the text is git's rather than yours — so a subject you never typed doesn't read as a description you chose. Three actions per row:

  • Pop — bring the work back and remove the stash
  • Apply — bring it back and keep the stash
  • Drop — delete it without applying, behind a confirmation that says plainly the changes are not applied first

If a pop hits a conflict, the conflict lands in your files and the stash stays put. Nothing is lost, the entry is still on the list, and you can try again once you have resolved it. On a clean tree, stashing tells you "Nothing to stash" rather than claiming it saved something you would later go looking for.

Dates and ages are shown in your language, and the whole feature is translated into Italian, French, German and Spanish along with the rest of the app.

File → Remove Root Folder. Removing a root folder used to be something only the pointer could do, through the ⊖ button in the sidebar. It now has a menu item, acting on the folder selected in the window you are actually using — so it does the right thing with more than one window open.

Fixed

A failed action no longer goes quiet. When a git action failed, the red warning in the action bar could vanish a second or two later — on exactly the actions that had changed something on disk, because re-reading the repository overwrote the message with "nothing wrong here". The failure now outlives every refresh, which is what "Last action failed" always claimed to mean. Most visible with a stash that pops into a conflict, but it applies to pull and to updating a fork as well.

Under the hood

  • Update signatures are produced with the same auto-update toolchain the app ships, rather than whichever copy happened to be on the release machine (#161). No effect on installed copies; it removes a way for a release to be signed with a key the app would not accept.
  • An action's failure and a status read's failure are now separate pieces of state. They shared one field, so any background refresh could clear the wrong one.
  • A stash is identified by its own commit hash rather than its position in the list. Positions renumber the moment anything is removed, so a confirmation left open could have acted on a different stash than the one on screen.
  • 407 tests.

Verify this download

Compare the checksum of the file you downloaded:

shasum -a 256 FinderGit-0.28.0.dmg

It must print exactly:

451167246c0b0e1c319f0508f619bd7c9e291dfeecc3bcfbe91f785868fea7e4

The DMG is also signed with an Apple Developer ID and notarized by Apple, which you can confirm without installing it:

spctl -a -vv -t open --context context:primary-signature FinderGit-0.28.0.dmg

That reports source=Notarized Developer ID for a genuine build.

FinderGit 0.27.1

Choose a tag to compare

@gfazioli gfazioli released this 26 Aug 06:21

Bug fixes

Codeberg columns and the fork badge now actually work. 0.27.0 introduced Codeberg support and got the headline wrong: in the file browser, a Codeberg repository's Issues, Pull Requests and Stars columns stayed empty, and its fork badge never appeared. The sidebar filter, "Open on Codeberg" and the Issues / Pull Requests tabs did work — which is what made it easy to miss.

The cause was two checks that asked "is this GitHub?" before anything else, written when GitHub was the only host FinderGit could read. Codeberg got a provider in 0.27.0; these two decided ahead of it, so the one host that needs no credentials was the one being turned away.

If you installed 0.27.0 and wondered why the columns were blank on Codeberg repositories: that was this, not your setup.

Under the hood

  • RemoteCountsStore and RepoForkStore now ask ProviderRouting.backend(for:) rather than comparing against .github. The routing was already per-host as of 0.27.0; these two sat upstream of it and never consulted it.
  • Sync-fork keeps its GitHub-only check on purpose, with the reason recorded in the code: Forgejo does expose a sync endpoint, but it needs write access and there is nowhere in FinderGit to sign in to a Forgejo instance yet.
  • Verified in the running app this time, not only under test: two public Codeberg repositories report 3 issues / 2 PRs / 52 stars and 3 / 2 / 116, matching what the API returns for them.
  • 393 tests.

Install

Download the DMG below, drag FinderGit to Applications, and open it. Existing installs update themselves.

Requirements

macOS 15 or later. Universal binary (Apple Silicon + Intel), signed and notarized.

Verify this download

Compare the checksum of the file you downloaded:

shasum -a 256 FinderGit-0.27.1.dmg

It must print exactly:

cb45eaf48e2e6589c651067dbbb25bf394a9acc2c93f734addae8b74d16286d3

The DMG is also signed with an Apple Developer ID and notarized by Apple, which you can confirm without installing it:

spctl -a -vv -t open --context context:primary-signature FinderGit-0.27.1.dmg

That reports source=Notarized Developer ID for a genuine build.

FinderGit 0.27.0

Choose a tag to compare

@gfazioli gfazioli released this 25 Aug 17:50

Highlights

Codeberg repositories are now first-class. They get their own filter in the sidebar, "Open on Codeberg" in the context menu, and — the part that matters — their Issues, Pull Requests and Stars columns fill in with nothing for you to set up. No account to connect, no token to paste. The Issues and Pull Requests tabs work the same way, as does the Overview panel with description, stars, forks, topics and latest release.

That is not how GitHub works in FinderGit, and the difference is not an oversight: Codeberg answers questions about public repositories without asking who is asking, so FinderGit can simply ask.

A fork on Codeberg shows its parent, and the "Forked from" link opens on the right host.

Bug fixes

  • Repositories on GitLab and Bitbucket no longer borrow another repository's numbers. A project mirrored under the same owner and name on two hosts could show counts, issues and pull requests belonging to the other one. Those columns now stay empty rather than confidently wrong, and the tabs say the data is not available for that host instead of asking you to connect an account that would not help.
  • The "Forked from" link went to GitHub whatever the host — correct while GitHub was the only host FinderGit could read, wrong the moment a second one arrived.
  • AI commit messages now distinguish "wait" from "this needs fixing". A temporary hiccup and a service that genuinely needs attention used to produce the same "try again in a moment", which is the wrong advice for one of them.
  • A refused anonymous request no longer counts against a host's health numbers in the connection panel.

Under the hood

  • New ForgejoAPIProvider speaking Forgejo/Gitea /api/v1, unauthenticated. repoCounts is a single GET — the same three numbers need a GraphQL query and a user token on GitHub. The instance URL is a parameter, so a self-hosted Forgejo needs a URL field rather than a new provider.
  • Provider resolution is now per host (ProviderRouting), with GitHub's CLI-then-token resolution, its cache and its single-flight untouched. GitLab and Bitbucket route to no backend at all.
  • New RemoteProviderError.unsupported, distinct from notConfigured, for operations no configuration can enable: fork sync, the account dashboard and repository listing on Codeberg. Forgejo has a sync-fork endpoint — it needs write access FinderGit cannot yet request.
  • Measured against codeberg.org rather than assumed: /contributors 404s, cross-repo /compare 500s, and GET /sync_fork reports commits_behind: 0, allowed: false to an anonymous caller — so fork drift shows nothing rather than a zero it cannot vouch for. New-PR links use /compare; /pulls/new is a 404.
  • 392 tests, 40 of them new.

Install

Download the DMG below, drag FinderGit to Applications, and open it. Existing installs update themselves.

Requirements

macOS 15 or later. Universal binary (Apple Silicon + Intel), signed and notarized.

Verify this download

Compare the checksum of the file you downloaded:

shasum -a 256 FinderGit-0.27.0.dmg

It must print exactly:

3cb0d6d68f35c8b832e55a4985b205ae0db930fcc5bb2f414bbe930ba1389c8a

The DMG is also signed with an Apple Developer ID and notarized by Apple, which you can confirm without installing it:

spctl -a -vv -t open --context context:primary-signature FinderGit-0.27.0.dmg

That reports source=Notarized Developer ID for a genuine build.

FinderGit 0.26.0

Choose a tag to compare

@gfazioli gfazioli released this 19 Aug 16:40

FinderGit 0.26.0 — a stop button, and what it leaves behind

Highlights

A git operation that's taking too long can now be stopped. Once Fetch, Pull or Push has been running for three seconds, its button becomes a stop control — click it and the operation ends. Until now a slow remote left the whole action bar disabled with nothing to do but wait it out, which is exactly how a slow forge came to read as a frozen app.

The three-second delay is deliberate: without it, a double-click on Fetch would cancel the fetch you just started.

Stopping is a real interruption, not the app looking away — the underlying Git process is ended. What that leaves behind depends on the action, so FinderGit tells you which:

  • A stopped Fetch is harmless. Nothing in your working tree changed, and you can simply run it again.
  • A stopped Push leaves the remote either updated or untouched, never half-way: Git updates each branch atomically.
  • A stopped Pull is the one to know about. If it was still downloading, nothing has changed. If it had started merging, you may be left mid-merge — and FinderGit notices that, offering Finish and Abort in the strip above the action bar, the same way it does for a merge that stopped on a conflict.

A stop is your decision, so it isn't reported as a fault. The button shows a neutral grey stop icon rather than a red ✗, and the repository is re-read immediately — the reconcile banner appears at once instead of waiting on a filesystem event that may never come.

Refresh has no stop control, because it's a local re-read that finishes before you could click it.

Every release page now publishes its checksum

If a virus scanner ever flags a FinderGit download, the first question is whether the file really is the one we published — and until now the answer lived nowhere you could reach. Every release page now states the SHA-256 of its DMG: this one and every earlier release. Verifying your download explains how to compare it, and what each check does and does not prove. Releases from 0.4.1 on can also be confirmed as notarized by Apple without installing anything.

Under the hood

  • Stopping and timing out are now distinguishable at the source. They had been collapsing into one: the timeout leg of the wait swallowed its own cancellation, so every stop was reported internally as "it ran too long" — harmless in itself, until a genuine timeout raced with a late stop and was misreported as something you had asked for.
  • The elapsed counter runs on one clock per control instead of one per thing that wants the time, and it stops when the action does. An animation with no end keeps the display pipeline committing frames for the rest of the session.
  • The cancellation tests no longer depend on the network to produce a stalled connection. They use a transport that hangs by construction, so a machine whose network answers an unreachable address can't quietly turn them green.

Install

Download the DMG below, drag FinderGit to Applications, and launch it. The app is signed with a Developer ID and notarized by Apple, so no Gatekeeper bypass is needed. Existing installations update themselves.

Requirements

macOS 15 or later. Universal binary (Apple Silicon and Intel).

Verify this download

Compare the checksum of the file you downloaded:

shasum -a 256 FinderGit-0.26.0.dmg

It must print exactly:

8aff7ffbce6b82335e90be6620d29173f89cdd9231a89e0be083eda81c4f01b6

The DMG is also signed with an Apple Developer ID and notarized by Apple, which you can confirm without installing it:

spctl -a -vv -t open --context context:primary-signature FinderGit-0.26.0.dmg

That reports source=Notarized Developer ID for a genuine build.

FinderGit 0.25.1

Choose a tag to compare

@gfazioli gfazioli released this 06 Aug 11:28

FinderGit 0.25.1 — a way out to the full picture

Highlights

The GitHub connection panel now links to GitHub's own status page. A Details link in the panel's footer opens it. The panel deliberately shows only the four services FinderGit depends on, and deliberately never renders a reassuring "all systems operational" banner — so when you want the rest (every service GitHub publishes, the 90-day uptime history, the full incident timeline), the honest answer is GitHub's page rather than a partial imitation of it.
The link is there whether or not the check succeeded. If anything, a status page FinderGit couldn't reach is exactly when you most want to open it yourself.

Under the hood

  • The human-facing status page URL is now the single source of truth: the API base is derived from it rather than maintained separately, so the page you open and the data the panel reads cannot drift onto different services.
  • GitLab and Bitbucket status pages are mapped too, ready for when those providers land. A host FinderGit can't identify — an enterprise install, a self-hosted forge — gets no link rather than a guessed one.
  • Why a link rather than a copy of that page: the uptime bars are not exposed by the status API at all (every plausible endpoint returns 404). They exist only inside the rendered page as ~990 markup elements, so reproducing them would mean parsing a third party's private HTML and breaking silently the next time they restyle it.

Install

Download the DMG below, drag FinderGit to Applications, and launch it. The app is signed with a Developer ID and notarized by Apple, so no Gatekeeper bypass is needed. Existing installations update themselves.

Requirements

macOS 15 or later. Universal binary (Apple Silicon and Intel).

Verify this download

Compare the checksum of the file you downloaded:

shasum -a 256 FinderGit-0.25.1.dmg

It must print exactly:

406e4ce5b251c4dd7ea58f94d507754e8dc51c0cfec7fff53cbe575e69ee0028

The DMG is also signed with an Apple Developer ID and notarized by Apple, which you can confirm without installing it:

spctl -a -vv -t open --context context:primary-signature FinderGit-0.25.1.dmg

That reports source=Notarized Developer ID for a genuine build.

FinderGit 0.25.0

Choose a tag to compare

@gfazioli gfazioli released this 06 Aug 09:08

FinderGit 0.25.0 — when GitHub is the problem, FinderGit says so

Highlights

Know whether it's you or GitHub. When GitHub is having a bad day, every symptom you see looks like FinderGit's fault: a fetch that crawls, a repository column that comes up empty, a dashboard that won't finish loading. The Overview now carries a GitHub connection panel that answers it — how quickly your own requests are actually coming back, and whether GitHub is reporting trouble with the four services FinderGit depends on: Git operations, API requests, Issues and Pull Requests. When there's an open incident, its name and the latest official update appear right there, with a link to the full story.
Only those four, deliberately. An outage of something FinderGit never touches isn't news, and a warning that fires on everything is one you learn to ignore.
It never tells you GitHub is fine when it can't check. If the status page can't be reached, or a service can't be read, that shows as Unknown rather than a reassuring green. And a slowdown nobody has announced yet still shows up, because your own requests are the first thing to know about it — the more useful half, since a status page can only report what somebody chose to declare.
See how long an action has been running. Past three seconds, a running Fetch, Pull or Push shows its elapsed time on the button. A spinner tells you something is happening; it doesn't tell you whether the thing is working or wedged, and only the second question matters when a remote is answering slowly.

Bug fixes

A slow remote could leave a repository's actions unusable for five minutes. Every action on a repository is disabled while one is running, and the time limit for a Fetch, Pull or Push was the one meant for a Git process wedged on your own machine. It's now far shorter for anything that talks to a server, while a first clone — which legitimately takes minutes on a large repository — keeps its own, longer allowance.
Opening the Overview with many repositories could bog the whole app down. Every repository asked "is GitHub reachable?" at the same moment, and none of them saw that the others were already asking, so the check ran once per repository instead of once. On a large workspace with a slow connection that was dozens of simultaneous checks. Now they share a single answer.
A rejected token would have read as GitHub being down. Caught before release: if your access token was revoked or lost its permissions, every request failed — and the new panel counted those as GitHub's failures, telling you "Your GitHub requests are failing" when the problem was your credential. A request that was refused is now kept separate from a request the server couldn't answer, so the dashboard points at the right place.
The Issues, PRs and Stars columns emptied silently when GitHub was unreachable — using the same blank cell that means "this repository isn't on GitHub". The columns still go quiet, but the Overview now says why.

Under the hood

  • The status source reads components.json and incidents/unresolved.json unconditionally and in parallel. The obvious design — check the top-level indicator first, fetch the incident only if it's non-none — silently drops live incidents: measured on 2026-08-05, status.json reported indicator: "none" while an unresolved incident was open and every component still read operational. The three endpoints are peers, not a hierarchy.
  • Components are matched on Statuspage's stable id with the display name as fallback, so a rename can't quietly drop one we depend on. An unrecognised status string, an unreachable page, or a component missing from the response all resolve to unknown — ordered below operational so it can never win a severity comparison, and tinted grey distinctly from green.
  • Incidents that carry no component attribution are diagnostic-only: they can explain a call that actually failed, but they never raise a banner. GitHub declares these regularly, and one measured example was "Incident With Blocked GitHub.com Traffic" — precisely the class that breaks a desktop client while the dashboard stays green.
  • The first-party signal leads because the published one has a hole: GitHub declared no incident at all on 2026-08-04, the day this was prompted by. The incident history spans 06-04 to 08-05 with entries either side and nothing in between.
  • Time limits are now split by what a command is waiting on: 120s for fetch/pull/push, 900s for a clone, 300s for local plumbing. The gh-backed clone path had been capped at the 120s meant for metadata queries, so a large repository could clone fine one way and fail the other.
  • The GitHub REST/GraphQL path gets a dedicated URLSession with a 10s inactivity limit and a 30s hard ceiling, replacing URLSession.shared's default — whose 60s is an inactivity timeout, not a wall-clock cap, so a response trickling bytes had no ceiling at all.
  • Provider resolution is collapsed through a single-flight actor. Swift actors are reentrant across await, so a TTL cache whose timestamp is written after the probe returns doesn't dedupe anything: every caller arriving during the probe reads the same empty cache and starts its own.
  • Request timings are recorded in the gateway rather than in each provider, so the CLI and token paths are measured identically and the dashboard can name which one produced the numbers. Git transfers are deliberately excluded — folding a multi-megabyte clone into the same median would blur "the API is slow" into "that pull was big".
  • Failures are classified by what they say about the forge rather than by whether they happened. A 4xx means the request was refused — no permission, not found, rate-limited — and says nothing about GitHub's health; a 5xx or a timeout does. Cancellations and decode errors are ours. Only the second group reaches the verdict.
  • The status response is streamed with a declared-size refusal before the first byte and an absolute ceiling for a chunked or mis-declared body. A time budget bounds how long a third party can hold you, not how much it can make you allocate.
  • The new panel and its four component descriptions are localized into Italian, French, German and Spanish, plural agreement included.

Install

Download the DMG below, drag FinderGit to Applications, and launch it. The app is signed with a Developer ID and notarized by Apple, so no Gatekeeper bypass is needed. Existing installations update themselves.

Requirements

macOS 15 or later. Universal binary (Apple Silicon and Intel).

Verify this download

Compare the checksum of the file you downloaded:

shasum -a 256 FinderGit-0.25.0.dmg

It must print exactly:

82262d97887201254f942db932caa2401fa04c1f16775d1b0ea6c1d528851717

The DMG is also signed with an Apple Developer ID and notarized by Apple, which you can confirm without installing it:

spctl -a -vv -t open --context context:primary-signature FinderGit-0.25.0.dmg

That reports source=Notarized Developer ID for a genuine build.

FinderGit 0.24.0

Choose a tag to compare

@gfazioli gfazioli released this 31 Jul 15:26

FinderGit 0.24.0 — forks that had drifted, and filenames that had been unreachable

Highlights

Update a fork from upstream — including one that has diverged. A fork that carries its own commits and is missing upstream commits can't be fast-forwarded, on GitHub or anywhere else. Until now FinderGit said so and stopped there, leaving you to finish the job in a terminal. It now offers an Update menu on the fork's Overview banner that does it: it sets up the connection to the original repository the first time, fetches it, and integrates the parent's default branch.
Merge or rebase, and you choose which. Merge keeps your commits where they are and records a merge commit; rebase replays them on top for a linear history. Both are offered every time rather than quietly following your Pull preference, so a one-off choice here doesn't change your default.
It stops before pushing, on purpose. After a rebase your history has been rewritten, so the next push needs a force — that's your call, not something to do on your behalf. FinderGit tells you which case you're in when it finishes.
It won't repoint a remote you configured. If your clone already has an upstream and it points somewhere other than the fork's parent, FinderGit stops and names both, rather than quietly pulling commits from a repository you didn't mean.
The one-click Sync is still there for a fork that's merely behind — it also updates the fork on GitHub itself — and now sits on a split button, so the local route is available even when you have no token, or one that can't push to the fork.

Bug fixes

Files with accents or non-Latin characters in their names could not be staged, unstaged or discarded. Any path containing a character outside plain ASCII — café.txt, Cyrillic, CJK, an emoji in a filename — came back from Git in an escaped form that FinderGit passed straight back without unescaping, so the action silently applied to a file that didn't exist. If you keep repositories with non-English filenames, those three actions now work.

Under the hood

  • Status is read with git status --porcelain=v2 -z, so paths arrive verbatim as NUL-terminated records instead of C-quoted strings. core.quotePath defaults to true, which is why every non-ASCII name was affected rather than an unlucky few.
  • Output that isn't valid UTF-8 is now refused rather than lossily decoded. The replacement character is neither reversible nor injective, so two different filenames can decode to the same string — acting on one could have staged or discarded the other.
  • The upstream URL is derived by substituting the owner/repo pair inside your existing origin URL rather than composing a fresh HTTPS one, which preserves the transport, host, port and path prefix you already use. An SSH clone stays SSH; a self-hosted forge keeps working.
  • The checked-out-branch check runs again immediately before the merge or rebase, not just before the network fetch that precedes it, narrowing the window in which a checkout elsewhere could land the integration on the wrong branch.
  • The test suite now runs green from a clean checkout. It had been failing on around 14 tests for a long time — a shared mock raced by parallel execution, plus assertions comparing against localized strings — which meant "did this change break anything" had no answer.

Install

Download the DMG below, drag FinderGit to Applications, and launch it. The app is signed with a Developer ID and notarized by Apple, so no Gatekeeper bypass is needed. Existing installations update themselves.

Requirements

macOS 15 or later. Universal binary (Apple Silicon and Intel).

Verify this download

Compare the checksum of the file you downloaded:

shasum -a 256 FinderGit-0.24.0.dmg

It must print exactly:

0011c6c955baf03124c30c10fea1cccf253bc7e2f027592625af7799817afadd

The DMG is also signed with an Apple Developer ID and notarized by Apple, which you can confirm without installing it:

spctl -a -vv -t open --context context:primary-signature FinderGit-0.24.0.dmg

That reports source=Notarized Developer ID for a genuine build.

FinderGit 0.23.0

Choose a tag to compare

@gfazioli gfazioli released this 28 Jul 09:59

FinderGit 0.23.0 — Pull that doesn't give up on a diverged branch

Highlights

  • Pull no longer stalls on a diverged branch. When your branch and the remote have both moved on, a plain pull simply refuses and changes nothing — which reads as a Pull button that does nothing at all. FinderGit now names the situation in a strip above the actions ("Diverged from origin/main ↑5 ↓8") and offers the two real ways out, Merge or Rebase, right there. The Pull button itself turns into a menu with the same choice, and if a Pull or Push already failed, the same two options appear inside the error popover — so the fix is one click from the message that explains it.
  • A Pull strategy setting. Settings → Git now decides how pulls reconcile: fast-forward only (the new default), merge, or rebase. FinderGit passes the choice explicitly every time, so pulling behaves identically on every machine regardless of what your git config happens to say — and nothing is ever merged or replayed behind your back.
  • A stopped merge or rebase is visible, and recoverable. Git integrates what it can and stops at the first real conflict, leaving the repository half-done. That state is now surfaced: the strip names what's open (merge, rebase, cherry-pick, revert, bisect), counts the files still in conflict, and offers Finish and Abort. Pull and Push are disabled while it's open, with a tooltip saying why instead of failing on click. It works even when you started the operation in a terminal.
  • It can tell a rewritten history from real work on both sides. Matching counts like ↑78 ↓78 look like two sets of commits, but they're just as often one history rewritten and force-pushed — the same commits wearing new identities. Merging that duplicates every one of them. FinderGit now compares the actual changes rather than the commit IDs and says which case you're in: when nothing local is genuinely new it says so and promotes the reset that fixes it; when the two histories share no ancestor at all it says that too and disables Merge, because git refuses it anyway.
  • Conflicts are called out where you work. Unmerged files are tagged CONFLICT in the changes list and stay in Unstaged until settled, with a Mark Resolved action — which is exactly what git wants next. Per-file Discard is deliberately hidden for them, and a bulk Discard leaves them alone.
  • Git failures explain themselves. A diverged branch, a rejected push, conflicts still open, local edits in the way, a missing upstream, credentials git couldn't get, an unreachable host: each now gets one line of plain language above git's own output, which stays visible underneath as the evidence.
  • Find them at a glance. A new Diverged smart view in the sidebar, plus a count in the status bar, so the repositories that need a decision are one click away.
    All of it is localized — Italian, French, German and Spanish, following your macOS language.
    Worth knowing: Pull now defaults to fast-forward only. If you had pull.rebase set in your git config, FinderGit no longer follows it silently — it stops and asks, with both options in front of you. Settings → Git changes the default.

Bug fixes

  • The ↑N ↓M tooltip advised "pull then push" — the one sequence that cannot work on a diverged branch. It now names the two options that can.
  • Discard All no longer sweeps up conflicted files. Reverting an unmerged file doesn't mean what that label promises, so those are left for you to resolve or abort.
  • Counts read correctly at one: "1 file still conflicting", not "1 conflicting files". Same fix in the reset confirmation and the diverged tooltip.
  • Three status tooltips (dirty, clean, and the diverged one) were never translated and always appeared in English. They follow your language now.
  • A hard reset can no longer land on the wrong branch: if you switch branch in a terminal while the confirmation is open, the reset refuses instead of resetting whatever is checked out at that moment.

Under the hood

  • Pull always passes its strategy on the command line (--ff-only, --no-rebase, or --rebase --autostash) instead of inheriting pull.rebase / pull.ff. With neither configured, git exits 128 on a diverged pull without touching the repository — that was the whole bug.
  • In-progress operations are detected from the git-dir markers (MERGE_HEAD, rebase-merge/, CHERRY_PICK_HEAD, …), following the gitdir: pointer so linked worktrees and submodules count too. It's a couple of stat calls, no subprocess.
  • Rewrite detection is git cherry (patch-id equivalence) plus a merge-base probe — two calls, run once per selection and only while diverged.
  • Conflicted files are identified by the porcelain v2 line kind (u), not by the XY letters, so DD and AA conflicts aren't missed.
  • merge --continue / rebase --continue run with the editor suppressed, so they can't hang waiting on one that can never appear.
  • 264 framework tests and 26 app tests cover the new surface, including operation detection against real repositories and a linked worktree.

Install

  1. Download FinderGit-0.23.0.dmg
  2. Open the DMG and drag FinderGit into Applications
  3. Launch normally — signed with Apple Developer ID and notarized by Apple

Requirements

macOS 15 Sequoia or later.

Verify this download

Compare the checksum of the file you downloaded:

shasum -a 256 FinderGit-0.23.0.dmg

It must print exactly:

7f2e150810ca390094693cef28b900152e03c6cdcd70de5e416aaa8a1ff627a1

The DMG is also signed with an Apple Developer ID and notarized by Apple, which you can confirm without installing it:

spctl -a -vv -t open --context context:primary-signature FinderGit-0.23.0.dmg

That reports source=Notarized Developer ID for a genuine build.