GitDesktop
An AI-native, keyboard-first Git desktop client
GitDesktop is a free, open-source (Apache-2.0) Git client for Windows, macOS, and Linux, built with Tauri 2 and React 19. It keeps GitHub Desktop's approachable model and goes further: staging, diffs, branches, and history for any remote, plus the whole pull-request loop (code review and CI) on GitHub, GitLab, and Bitbucket, with issues in-app on GitHub and GitLab or via Jira on Bitbucket. That includes things GitHub Desktop doesn't do at all, like offline "local" pull requests and a GitHub Actions cockpit.
AI runs through commits, reviews, and CI debugging, with the provider you choose (local models included). It's also optional: one switch hides every AI surface, leaving a keyboard-first Git client.
All GitHub access goes through the GitHub CLI (gh): no OAuth app, and
the app never stores your tokens. Core git runs against any remote via system
git. Because gh detects each repo's host from its remote, **GitHub
Enterprise** servers work the same as github.com once you've run
gh auth login --hostname , and Settings → Accounts switches the
active account per host.
Install
Pick the installer for your OS under Assets. On macOS you can also install
with Homebrew: brew install --cask thebguy/tap/gitdesktop. Builds are signed
and keep themselves up to date (see Updates). To build from source
instead, see Development.
Highlights
- The whole PR lifecycle, in-app: review, comment, approve, and merge
- Three forges, first-class: GitHub, GitLab, and
- My work, one inbox across repos and forges: your open
- A GitHub Actions cockpit: runs, jobs, steps,
- Coding agents with guardrails: hand tasks to
- **AI review that doesn't quit or repeat
- MCP in both directions: bring your own servers to agent
- Deep git tooling: interactive rebase,
- Keyboard-first, privacy-first: rebindable shortcuts, a command palette,
Features
The full catalog, area by area. The deepest provider sections fold away; expand them when you want the detail.
Repositories
Clone, add local, create (with README / .gitignore / license scaffolding), publish to GitHub, GitLab, or Bitbucket, and fork.
- Pick the owner when you publish: publishing a local repo to GitHub
- Repo switcher: every repo grouped by owner, with a Recent section and a
- Locate a moved repository: when a repo's folder moves on disk, point
- macOS menu bar: File carries New / Open / Clone Repository… and
- Manage files git tracks or ignores (beyond pending changes): untrack a
GitHub repo settings (admin): rulesets, security toggles, secrets, webhooks, Pages, danger zone
Description and topics (with AI suggestions), merge options and default
commit messages, template and forking, collaborators and invitations,
branch rulesets (create/edit, reversible enable/disable), **code security
and analysis toggles, Actions/Dependabot/Codespaces secrets and
variables (repo and environment scope), the Sponsor button**
(.github/FUNDING.yml), webhooks with delivery history, GitHub Pages
config, a danger zone (rename, archive, change visibility, transfer,
delete), and deep links to the settings GitHub keeps browser-only.
Changes and commits
A unified or split diff with syntax highlighting, collapsible surrounding
context, and image diffing. Filter the changes list by path or category, and
read a file's +added -deleted line counts without opening it. Show that
list flat or as a compacted directory tree: collapsible folders, single-child
folder chains merged into one row, and arrow keys that walk and fold it. The
working-tree diff is one whole-file view with hunk- and line-level staging
and discarding (drag across the line numbers, spanning hunks freely — a drag
picks up added and removed lines together in either view, Shift keeps it to
one side, and Ctrl, or Cmd on macOS, adds to a selection), including
committing or discarding only part of a brand-new (untracked) file. Stage or
unstage a drag-made selection with Ctrl/⌘+Shift+Enter, without
reaching for the button. Stage, unstage, or discard single files or a
multi-selection from the context menu (staging and unstaging a selection sit
in the command palette too); discarding a whole untracked file goes to the
recycle bin. Commit with title + body, co-authors suggested from history,
amend, undo, reset, and revert.
Markdown and MDX files add a Raw / Preview toggle to the diff, so you can read a doc change as rendered prose (headings, tables, and code blocks) on the working tree, commit details, stashes, an agent session's worktree changes, a file's history, branch compare, and pull request files when the PR's commits are available locally.
Branches
Switch (with a bring-changes / stash prompt), create, rename, delete, and archive (hide from the switcher without deleting). Each switcher row shows the branch's push/pull state vs. its upstream (↑ to push, ↓ to pull, plus markers for never-published and upstream-deleted branches), its +/− divergence vs. the default branch (labeled with the default's name), and a PR badge.
- Clean up branches ⭐: one reviewed list that archives or deletes your
- Advanced merge tooling ⭐: predicts a merge's result in memory before
--no-ff and a clearly cautioned auto-resolve
strategy (-X ours/theirs); GitHub Desktop offers none of this. This is
the local prediction; a remote PR's conflict state comes from the forge
itself, and falls back to this prediction only where the forge publishes
none.
- Change base ⭐: rebase a branch onto a different base when it was
- No-checkout and remote-branch ops: update a branch without checking
- Push or publish without switching: from the switcher's context menu,
origin) or publish an unpushed one, choosing the remote when
there's more than one. Works even when the branch is checked out in
another worktree.
- Start a branch from any base: the new-branch dialog's Base it on
origin/epic/big-feature) starts from the remote tip
and leaves the new branch untracked, so its first push publishes it under
its own name.
- Worktree manager: create, switch between, rename, lock, promote a
- Compare: a tab with a three-dot diff, commits ahead/behind,
- Local branch-protection rules: naming, merge methods, require-PR, and
History
Paged, filterable history with rich commit detail, commit-author avatars, and an at-a-glance marker on every commit that hasn't been pushed yet. Per-file history and line blame are reachable from any file list (History, pull requests, Compare) or the command palette, pinned at that commit or branch where it applies; each blame line's commit gets a hover-card preview and a click to jump to it in History.
- Interactive rebase ⭐: an Edit history editor to reword, squash,
- Recover lost work ⭐: a stash browser whose scan (via
git fsck) finds
git stash saved but
that fell out of git stash list (dropped, or abandoned by an interrupted
operation), and restores any of them non-destructively to the working
tree.
- Operation journal ⭐: records the risky compound operations GitDesktop
Plus tag management and releases: publish, edit, and delete them with asset
uploads. When a GitHub release carries a latest.json updater manifest,
editing its notes can refresh the manifest in the same save, so apps updating
from that release show the notes you just wrote.
Submodules get a manager of their own: add and remove them, update to the commit your repo records or to the tip of the branch each one tracks (recursing into nested submodules either way), edit a submodule's URL or tracked branch, and open one as its own repository. Adding, removing, and editing stage the change for you to commit, and the clone dialog can bring every submodule down with the repo.
Syncing and conflicts
Fetch, pull, and push, with the ahead/behind counts shown right on the Push
and Pull buttons. The Pull button is --ff-only; the menu's rebase and
merge modes reconcile a diverged branch. Divergence routes to a guarded
force push with --force-with-lease --force-if-includes (lease-only on
Git releases older than 2.30, or when the branch has no reflog for the
check to read). When the remote itself was rewritten (a server-side
rebase) and every local commit already landed there under new ids, the
Pull menu offers a confirmed Reset to _origin/…_ that lines the two
up instead. Pulling with rebase pre-checks the upstream for a rewrite
that would take commits of yours off the branch, names them, and asks
whether to keep or drop them, recording a drop in Operation history.
When a repo has an upstream remote, the Pull menu adds
Update from upstream: one click fetches upstream and brings your
branch up to date (fast-forward when it can, a merge commit when cleanly
diverged, the conflict editor otherwise), for keeping a fork current.
Auto-fetch (on by default) quietly runs a background git fetch on an
interval while the window is focused, so the behind-count and incoming
commits stay current without pressing Fetch; it never pulls or merges, and
pushing and pulling stay manual.
- Conflict editor: an in-progress merge, rebase, cherry-pick, or revert
- AI conflict resolution: one more option there. Ask your model to merge
- Stash and reapply: when a pull, a merge into the branch you're on, a
Pull requests
The full pull-request loop on GitHub, GitLab & Bitbucket, plus **local PRs**: the same workflow against any two branches with no remote at all, promotable to a real GitHub, GitLab, or Bitbucket PR (comments and all) in one click.
- Open, edit, merge: review, comment, approve, edit, and merge (merge &
- Linked issues: link related issues when you open or edit a PR, as
fix/123-…
branch seeds #123) or picked by hand. Each chip toggles between
Closes (auto-closes the issue on merge) and Relates to (GitHub &
GitLab; also on local PRs, where the refs carry into the promoted PR).
On a Bitbucket repo with a linked Jira project, the same row
surfaces linked-Jira issues (KEY-123) as mention-only Relates to
chips (Jira tickets aren't closed from PR text). Editing a PR peels any
trailing Closes #N / Relates to #N lines back into chips, so the chips
stay the single editor for the ref block.
- Conflicts with the base: an in-flow strip under a PR's header when it
- Blocked by branch protection: a PR that merges cleanly but whose rules
- Local PR merges: a merge pre-shows conflicts and lets you resolve
- Activity feed: a PR's Conversation is a date-sorted timeline of
- CI rollup: checks collapse into a **✓ passed · ✕ failed · ● pending ·
- Line-anchored review comments, from Copilot, CodeRabbit, or humans:
- Compose your own review from the diff: click a line number, or drag a
- An unfinished GitHub review (one you started on github.com or with
- Commit-level comments: the Commits tab is arrow-navigable; open a
- Stacked PRs: stacked rows get a position badge (2/3) in the PR
- Scope the list to your work: a one-click All | Mine | Needs review
- Fork · Upstream lens: on a GitHub fork (a repo with an
upstream
- Maintaining a fork's PR (GitHub): a pull request that's fallen
origin, wherever the PR allows edits from maintainers.
- Record management: a local PR's context menu in the list (or the
AI review and security audits
Run an AI review or security audit on any PR, with an activity indicator, a cancel, and a concurrency-capped queue; while one mode streams you can queue the other to run next instead of waiting. Reviews keep running while you move between PRs, and finish in the tray even after you close the window.
- Iterative: re-runs remember the last round, fold in other reviewers'
" or refutation replies) as soft, re-verifiable context.
A finding it already refuted or marked fixed is treated as settled instead
of re-raised cold; the current diff is always the source of truth. Once
rounds accumulate well past the context budget, that history is distilled
into a compact ledger instead of being trimmed. Per PR, you can ignore the
prior review, trim a false finding, or opt out of external-bot folding.
- Your models, per job: pick a review model independent of the
- Sized to your model: a Review context setting scales the review's
- Dial the review effort: a Review effort setting picks how hard an
- Timeboxed on your terms: agent-CLI reviews are timeboxed. Agentic ones
- Agentic review, so there's no more "couldn't verify the truncated
- Notes for reviewers: hand the reviewer context up front. An agent
- Clearly machine-authored: a branded header/footer and a robot-avatar
- Drafts wait by default: a draft PR's first automated review waits
Issues and to-dos
A dedicated tab for GitHub & GitLab issues and private local to-dos (no remote needed; publishable to GitHub, GitLab, or linked Jira in one click). Browse, create, and edit (drafting with AI from your repo's issue templates), react with emoji, and manage the shared metadata: labels, assignees, and milestones. On GitHub, add projects (GitHub Projects, repo and owner level), issue type, sub-issues, dependencies (blocked-by / blocking), and development links (linked and closing PRs and branches, plus create-a-branch); on GitLab, related issues. Close or reopen with a comment you've drafted posted alongside; duplicate, transfer (called move on GitLab), pin/unpin (GitHub), lock/unlock, or delete. On a fork, the same Fork | Upstream lens as the PR tab browses the parent repository's issues (creating one under the Upstream lens opens it on the parent), and a fork with issues turned off offers a one-click switch to Upstream instead of a dead end. An All | Mine switch in the list toolbar scopes the list to the issues assigned to you, and the funnel beside it narrows the whole repository's issues by author or label (GitHub & GitLab).
Activity feed: an issue's timeline events interleave with its comments, date-sorted oldest-to-newest — labels, assignees, milestones, title renames, mentioned this in cross-references, linked pull requests, marked-as-duplicate, pin/lock/transfer, and close (with its reason) or reopen. Each event row carries the actor's avatar and a relative timestamp, and a cross-reference, link, or duplicate row pointing inside the repository jumps to the pull request or issue it names (under a fork's Upstream lens those rows stay plain text). GitLab issues report labels, state changes, milestones, assignment, locks, duplicates, and same-project mentions.
Code TODOs
A tab that scans your working tree for real TODO, FIXME, HACK, BUG,
and XXX comment markers (tracked and new-but-not-ignored files), groups
them by file, and lets you filter by text/path or marker. Select one for a
syntax-highlighted excerpt with blame attribution (who wrote the line, and
how long ago); then open it in your editor, copy its path:line, or
promote it to a local issue, pre-filled with the comment and a
path:line reference, from where it's publishable to GitHub, GitLab, or
Jira like any other local issue.
Discussions
Browse and read a repository's GitHub Discussions, create and edit them, and react or upvote, with Write/Preview markdown throughout. Close or reopen one with a comment you've drafted posted alongside.
GitHub Actions
A dedicated tab with live run status, run detail, re-run (all or failed), cancel, manual dispatch, and inline failed-step logs (none of which GitHub Desktop does), plus a current-branch CI badge in the header and run-completion notifications. Right-click any run in the list to re-run or cancel it, run its workflow again with the picker already on that workflow, open it on the forge, or copy its link; those actions are in the command palette too. The Run workflow picker marks the workflows that can't be started by hand on the chosen ref, so a dispatch that would be rejected is visible before you run it.
- Debug failed CI with AI: turn a failed job's logs into a streamed
Security findings
A Findings tab (More ▾) lists a GitHub repo's open **Dependabot alerts**, grouped by the vulnerable package, each row with its severity, affected version range, first patched version, and a CVSS score when GitHub has one; its code scanning alerts; its secret scanning alerts, with a validity chip for the leaked credential; and the **security advisories** published on the repository itself. Select a row for its detail, then open it on GitHub. A Dependabot alert's detail adds a base-metric table per CVSS version the advisory carries (3.x and 4.0), its CWEs, labeled reference links, and whether the package is a direct or transitive dependency. When a category isn't reporting (scanning switched off, a token that can't read it, or a check that didn't complete), the tab says which and why; for the three scanning categories, **Open security settings** (with repo-admin access) goes straight to Repository settings → Security to turn scanning on. Repository advisories have no such switch; they're only published on public repositories.
On a GitLab repo the same tab reads the newest completed pipeline
for your checked-out branch (falling back to the default branch, and
saying so) and lists its SAST, secret detection, and **code
quality** findings straight out of the pipeline's report artifacts,
including scans that run in triggered child pipelines. Those
analyzers run on every GitLab tier, Free included; it's GitLab's own
vulnerability report that's Ultimate-only, so this is often the only place
you'll see findings your pipelines already produce. A provenance strip
names the pipeline, branch, and commit the findings came from, with **View
pipeline**; a finding's detail adds its severity, file:line, the scanner
that raised it, its identifiers as links, the description, and **View file
on GitLab** — a permalink to that line at the scanned commit. Detected
secret values never leave the report: the raw extract is dropped before a
finding reaches the app. Rather than looking clean, each section explains
itself: scanning not set up (with Open scanning setup on GitLab), a
report GitLab won't serve (add the gl-*-report.json to artifacts:paths
in the job that produces it), expired artifacts, nothing finished yet, an
access problem, or a check that didn't complete. An empty section only
reads as clean once a parsed report proves it, and a partly unreadable
pipeline says how much was lost. When one cause covers all three (no
pipeline to read yet, or one problem across every category), a single card
stands in for them.
Insights
A repository-graphs tab (Ctrl/⌘+9): commit activity, code frequency
(additions vs. deletions), contributor churn, and a commit punch card, all
computed locally from your clone, so they work offline, on private
repos, with no token or rate limit, and without GitHub's 10k-commit chart
degradation. Plus the at-a-glance overview (languages, contributors, sizes,
branch-vs-default), a GitHub Actions success-rate / duration trend, a
community-health card, 14-day traffic (views/clones/referrers/paths,
with push access), a dependencies card, and quick links to the web-only
GitHub insights (Pulse, network, dependents, Actions metrics, stars over
time). A Fork activity card lists the repo's recently active direct
forks on GitHub, GitLab & Bitbucket (up to ten, most recent first,
each with its latest activity and stars where it has any), plus the total
fork count and a link to the full list; on GitHub, a per-fork Compare
fetches ahead/behind counts, so you can see which forks carry commits
yours doesn't. Charts ship one-line captions, data-table fallbacks, and
keyboard navigation.
Explore repositories
A full-page browser across GitHub, GitLab & Bitbucket. Before you type, it shows the repositories you have access to (your own, ones you collaborate on, and those in an organization, group, or Bitbucket workspace you belong to), grouped by owner, plus a Popular star-sorted feed (GitHub & GitLab); typing searches GitHub, all public GitLab projects, or your Bitbucket workspaces (Bitbucket retired global repo search). Sort by best match, most stars, or recently updated. Open a result for its README preview, then clone it, fork it (with an offer to clone the fork), or star it (GitHub & GitLab), without ever knowing the URL. Fork only shows on a repository that isn't already yours, so on Bitbucket (where Explore lists just workspaces you belong to) it doesn't normally appear. Fully keyboard-navigable.
My work
A cross-repo inbox of the open work that involves you, across all three
forges. On GitHub it collects every pull request and issue you
authored, were assigned, were mentioned in, or commented on, plus
anything awaiting your review; GitLab adds the merge requests and
issues from each host you're signed in to, and Bitbucket the pull
requests from your recent repositories. Newest first, so what's waiting
on you is one screen away instead of one repository at a time. Every row
carries the mark of the forge it came from, each forge loads on its own,
and a forge you haven't connected simply doesn't appear. Narrow it with
the All / Pull requests / Issues tabs and a filter box that takes
arrow keys and Enter, then press Enter on a row: an item from a
repository you've added to GitDesktop usually opens right in the app, and
the ↗ marks the rows GitDesktop already knows will open on their host in
your browser — a row without it can still land there when its checkout
can't be confirmed as you open it. A pull request usually lands in the
worktree its head branch is checked out in (when GitDesktop can
resolve that in time), so you arrive in the checkout the work lives in;
Shift+Enter (or Open in main workspace on the row's right-click
menu) takes you to the main workspace instead.
Read-only, with a Refresh in the header, plus *Open on GitHub / GitLab /
Bitbucket and Copy link* alongside. Reach it with Ctrl/⌘+Shift+M,
from the welcome screen, or from the command palette (My work).
GitLab
First-class, via the GitLab CLI (glab), on gitlab.com or
self-managed (any host glab auth login knows). Browse and clone
projects, then read and act on merge requests, issues, pipelines, and
releases in the same panels: MR comments, commits, and diff; an issue's
labels/assignees/milestone rail; pipeline jobs with logs and a branch CI
badge; release notes with asset links. Star a project ("View on GitLab" plus
a fork link), publish a local repo (or local issues and PRs) to GitLab,
and Insights charts GitLab pipelines and lists the project's recently
active forks. GitHub is unchanged.
The full GitLab surface: merge requests, issues, time tracking, pipelines and releases, project settings
- Merge requests: comment (edit/delete your own), close/reopen with a
- Issues: create, comment, close/reopen with a drafted comment posted
- Time tracking: estimate + spent, on an issue or an MR.
- Pipelines and releases: retry, cancel, or run pipelines with CI/CD
- Project settings: General (description, topics, default branch,
Bitbucket Cloud
Connect with an Atlassian API token (Settings → Accounts), then browse
and clone repositories and work pull requests and Pipelines (with step logs)
in the same panels. Publish a local repo to Bitbucket (creates the repo,
adds origin, pushes). Reopening a declined PR isn't available (a platform
limit), and issues live in Jira; link a project (below).
The full Bitbucket surface: pull requests, tasks, Pipelines, repo settings
- Pull requests: comment (edit/delete your own), decline, merge (merge /
- Tasks checklist: add, edit, resolve/unresolve, and delete, with a
- Pipelines: rerun, trigger, and stop; on a repo with custom
pipelines.custom. in bitbucket-pipelines.yml, *pick which pipeline
to run** (Default or a named custom one, with variables). Insights charts
Pipeline durations and lists the repo's recently active forks, with a
link-out to Bitbucket's Commits/Branches/Pipelines/Deployments.
- Repo settings (admin): General (description, website, language,
origin; no archive).
Jira Cloud issues
Link a Jira Cloud site and project to any repo (the repo ⋯ menu's **Link
Jira project…, or the palette), and its Issues tab gains a Jira**
section. Connect with an Atlassian API token (validated, kept in your OS
keychain) or reuse a Bitbucket credential. Especially handy for
Bitbucket, whose tracker Atlassian retires 2026-08-20. Agents reach
the linked project through GitDesktop's MCP server: jira_* tools to
list and read, and (behind --allow-remote-write) comment, close/reopen,
create, assign, log work (jira_log_work), and update an issue's due date,
priority, labels, and original/remaining estimates.
The full Jira surface: browse, agile fields, actions, linked keys
- Browse and read: filter issues (open / closed / all, mapped to Jira's
- Agile fields (when the project uses them): story points (also on
- Act: create (summary, description, type), comment in Markdown,
2d 4h 30m duration grammar, with an
optional note), set the original/remaining estimates, and edit/delete
your own comments and worklog entries. Actions your permissions don't
allow simply don't appear.
- Linked in: issue keys (e.g.
PROJ-123) spotted in your branch name,
Accounts and sign-in
Reconnect GitHub (gh's device-code flow) and GitLab
(glab --web) right from the not-signed-in panels, Settings → Accounts, or
the palette; no dropping to a terminal for github.com and gitlab.com (a
self-managed GitLab host needs glab auth login --hostname … once, in a
terminal).
GitDesktop tells an expired-or-revoked session apart from
never-signed-in and network blips, badges the affected account with
one-click Reconnect, and warns before a token lapses: GitLab and
GitHub PAT expiry, plus an optional Bitbucket expiry date you supply.
For GitLab it nudges the browser (OAuth) option, whose sessions renew
themselves instead of expiring.
Coding agent sessions
Hand a coding task to a Claude Code, Codex, GitHub Copilot, or opencode agent (the CLI you already have; opencode's hosted models are free, no extra subscription). It works in an isolated worktree that never touches your checkout.
- Watch it work: follow every file it reads and edits and command it
- Several at once: sessions organize into Active and Kept tabs,
- Sandbox: confine writes to a Docker/Podman container (or rely on
... (README truncated for length)