Git Extensions runs on Linux now. It’s the Windows build, under Wine, with about fifty patches and one script.
curl -fsSL https://raw.githubusercontent.com/craig-b/gitextensions/wine-support/eng/wine/install.sh | sh
That’s the whole install. Type gitext-wine in a repository, or find Git Extensions in your
application menu, and the browse window opens on it.
Why a fork
The stock build almost works. It gets as far as the main window, and then every time that window
gains focus you get the bug-report dialog, because Wine’s taskbar doesn’t implement jump lists and
the app asks for one on every activation. That fix is one of about fifty patches on the
wine-support branch of my fork.
Some are Wine gaps worked around in code: the dashboard’s recent-repository tiles don’t respond to
clicks because Wine’s list view has no tile mode and never sends the click notification; the Console
tab shows a stale copy of the previous tab after you switch windows, because a child window from
another process gets no back buffer; “Open with” and “Copy path” hand out Windows paths to a desktop
that wants Linux ones. Some are quality of life that Windows users wouldn’t notice: process output
that was unreadable in dark mode, a diff margin sized from the wrong font, a Linux terminal on the
Tools menu instead of PuTTY. And some are about speed, which is a longer story and
its own post. The short version: under Wine, starting git.exe
costs about a third of a second, and Git Extensions starts git once or more per click. So the fork
doesn’t start git.exe. It runs your Linux git through a small daemon instead, and everything
downstream of that decision turns out to be an improvement.
What you need
Wine 10 or later. curl or wget, unzip or bsdtar, tar, sha256sum, and fontconfig, all of
which you almost certainly have. Nothing needs root. If you want the Git GUI and GitK entries on the
Tools menu to work, install Tk (git lists it as an optional dependency). A monospace font called
Hack is nice to have, for reasons the next section gets to, but DejaVu Sans Mono will do.
You don’t need a Windows git or a .NET SDK. Everything comes from the release: a portable app archive built on Linux, and a tarball of everything that runs on the Linux side.
What the script does
It finds the latest release, downloads the two archives, checks them against the published
checksums, and unpacks them under ~/.local/opt. Your settings and window positions live in that
directory too and survive a re-run.
Then it builds a Wine prefix, and this is where it earns its keep, because Wine’s default font setup is wrong for this app in three separate ways. Every Windows process enumerates every font on your system at startup, so the script gives Wine a short list. The app’s UI font is Wine’s Tahoma, which lacks the arrow glyphs branch labels use, so the script tells Wine where to borrow them from. And the app’s default console and diff font is Consolas, which Wine substitutes with something proportional, and a terminal drawn in a proportional font looks like it’s been through a mangle. The script substitutes Hack when you have it, because Hack has the glyphs shell prompts draw their branch symbol with, and DejaVu Sans Mono otherwise.
The .NET desktop runtime is unpacked from Microsoft’s zip straight into the prefix’s
Program Files\dotnet. No installer runs under Wine, and no Mono or Gecko prompt appears.
Last, a symlink in ~/.local/bin, a menu entry, and the icons in the hicolor sizes.
What it’s like to use
Git is your git. Every git call the app makes goes over a socket to a daemon on the Linux side, which runs your Linux git in your environment. So your global config applies, your identity, your credential helpers, your SSH keys and known hosts, your hooks, your LFS. Fetch and push work on the first try because nothing about credentials changed.
If your Linux git config already names a merge and diff tool, that’s what you get. Check
merge.guitool and diff.guitool are set too, because the app reads those. Native git launches the
native tool, and the conflicts dialog hands the file to git mergetool so git stages the result
itself.
The Console tab is your login shell, in the repository, with your prompt and dotfiles and SSH agent. Progress dialogs (rebase, merge, pull, cherry-pick) run their command on a real pseudo-terminal, so an interactive rebase with a terminal editor works and the output is coloured. Stage-by-patch asks its questions in the process dialog and you answer in its input line. User scripts and external tools are Linux programs unless they’re obviously Windows ones; write them as you would on Linux. “Tools > Linux terminal” opens your terminal emulator in the repository.
What doesn’t work is short. PowerShell user scripts silently do nothing, because Wine’s
powershell.exe is a stub that exits 0. The Gource and AutoCompileSubmodules plugins want programs
the prefix hasn’t got. And don’t run without the bridge unless you’ve read
docs/running-under-wine.md: GITEXT_GIT_BRIDGE=0 in the environment turns it off, and then the
prefix needs a Windows git of its own.
Updating and removing
“Help > Check for updates” asks the fork for its latest release, and if there’s a newer one it offers to install it. The app closes, the update runs once every window has gone, and the app comes back. It won’t kill a window to get on with the job; if something stays open it gives up, having changed nothing.
Re-running the curl command does the same from outside the app. Pipe it to sh -s -- --help instead
of sh for the options; sh -s -- uninstall removes everything but the prefix, and
uninstall --purge removes that too.
Versions read 7.3.0.6-dev-wine: upstream’s version, then a build number, and -dev while upstream
hasn’t released that base yet.
When it breaks
GITEXT_GIT_BRIDGE_LOG=<file> in the environment before gitext-wine lists every command the
bridge ran. After a Wine upgrade, run through this:
- open the Console tab and switch windows away and back
- “Edit commit” on a throwaway branch
- “Open with…” on a file
- resolve a conflict with the merge tool
- fetch from a remote
- click a tile on the dashboard’s recent repositories
docs/running-under-wine.md in the branch, and in the Linux tarball, has everything else, including
what turned up in every place the app shells out and the Wine bugs that were worked around in code.
It also covers running with a Windows git in the prefix, if you must.
Everything above was worked out on Arch, against Wine 11 and .NET 10 in a KDE Wayland session.