Files
GitDesk/README.md
T
2026-11-06 21:01:01 +00:00

185 lines
10 KiB
Markdown

# gitdesk
A GitHub Desktop-style git client that runs in your terminal. Use the mouse or the keyboard.
## Setup
1. Install Python 3.9+. That's not needed if you use the built exe.
2. Install the one dependency: `python -m pip install -r requirements.txt`
(or just run gitdesk once and say yes when it offers to install it).
3. **git:** if it isn't installed, gitdesk offers to install it for you when it starts.
It does the same if your git is older than 2.25.
- **Windows:** installs Git for Windows (which includes Git LFS) with `winget`, after
the usual permission prompt. gitdesk picks it up straight away. Without winget, it opens
the download page.
- **Linux:** installs `git` and `git-lfs` with apt, dnf, yum, pacman, zypper or apk, using sudo.
- **macOS:** uses Homebrew, or Apple's command line tools.
4. **Your name and email:** the first time you commit or create a repository, gitdesk asks
for them if git doesn't know them yet. They're saved for all your repositories.
## Build a standalone executable (optional)
This makes a single file that runs without Python or Textual installed.
- **Windows:** double-click `build.bat`. In PowerShell type `.\build.bat`; PowerShell won't
run it without the `.\`. You get `dist\gitdesk.exe`.
- **Linux / macOS:** run `./build.sh`. You get `dist/gitdesk`.
`build.py` does the work, and the .bat/.sh just start it. It:
- sets up its own environment in `.build`;
- installs PyInstaller and Textual;
- builds the exe;
- test-starts the new exe to make sure it works;
- logs everything to `build.log`.
If something goes wrong it says why in plain English (old exe still open, antivirus,
OneDrive, no internet...). Send `build.log` over if the reason isn't clear.
Build on the system you want to run it on: a Windows exe has to be built on Windows.
The exe takes a second or two to start because it unpacks itself first.
## Run
| | |
|---|---|
| **Windows** | `gitdesk.bat` inside a repo folder, or `gitdesk.bat C:\path\to\repo`. Windows Terminal gives the best mouse support and symbols. |
| **Linux / macOS** | `python3 gitdesk.py` inside a repo, or `python3 gitdesk.py ~/path/to/repo` |
Tip: put this folder on your PATH (Windows), or symlink it on Linux/macOS
(`ln -s "$PWD/gitdesk.py" ~/.local/bin/gitdesk`). Then you can type `gitdesk` in any repo.
## What's on screen
- **Top bar:**
- **Current repository:** click it to open the picker. It lists your recent repos
and has **Add local repository…**, **New repository…** and **Clone repository…**.
- **Current branch:** click to switch branches or create one.
- **Fetch / Pull / Push / Publish:** one button that changes with the state of your
branch, like GitHub Desktop's. If the repo has no remote yet, it shows **No remote**:
click it to add the URL of an empty repo you created on GitHub or Gitea, then publish.
- **More:** lists every action.
- **Startup:** gitdesk reopens the repository you had open last. If you start it inside
a repo folder, or pass a path (`gitdesk C:\path\to\repo`), it opens that one instead.
- **Add local repository** (`o`): type a path, or click **Choose…** to pick the folder.
If the folder isn't a git repository yet, it offers **Create a repository here**:
the files already in it go into the first commit (pick the Unity .gitignore for a Unity
project so Library/ and Temp/ stay out).
- **Choose… buttons** (Add local, New repository, Clone) open the normal folder picker:
the Explorer "Select Folder" window on Windows, Finder on macOS, and zenity/kdialog on
Linux desktops. With no desktop (e.g. over SSH) you get a folder browser inside the terminal.
On Windows the Explorer picker needs Python's tkinter, which the python.org installer
includes by default. Without it you get the older Windows folder dialog instead.
The same goes for the exe: build it with a Python that has tkinter.
- **New repository:** choose a name, description and folder, a README, a .gitignore
template (Unity, Python, Node, Visual Studio), an MIT license, and an optional remote URL.
It makes the first commit for you.
- **Clone repository:** paste an HTTPS or SSH URL. The folder name fills in automatically
and progress shows in the top bar. If the server needs a password, use **Retry in terminal**.
- **Changes tab:** changed files with checkboxes. Ticked files go into the commit.
Click a file to see its diff, then **Discard** it if you don't want those changes.
Discard keeps a backup in Stashed changes, so it can be undone. More → Discard
ticked changes does several files at once. Below the list are Stash all / Stashed, and
the commit summary + description.
- **Right-click a changed file** (or press `m` / Shift+F10) for the same menu as GitHub Desktop:
- **Discard changes…**
- **Ignore file**, **Ignore folder ▸** (pick which parent folder), or **Ignore all .ext files**.
Each one adds a line to the repo's `.gitignore`.
- **Copy file path / relative path**
- **Show in Explorer**, **Open in VS Code**, **Open with default program**
Ignoring a file git already tracks doesn't hide its changes, so if the new rule covers tracked
files, gitdesk offers **Stop tracking**. The files stay on your disk and leave the repository
in your next commit.
- **History tab:** recent commits (↑ = not pushed yet). Click one to see what changed,
or **View on GitHub** to open that commit's page.
- **View on GitHub** (`g`, More menu, or the card on the "No local changes" screen) opens
the repo's web page, worked out from the remote URL. It works for GitHub, Gitea,
GitLab and Bitbucket, over SSH or HTTPS, and any token in the URL is left out.
If the address can't be worked out (e.g. SSH goes through a separate hostname), set it once:
`git config gitdesk.webUrl https://git.example.com/owner/repo`
- **Log** (`l`): shows every git command gitdesk ran and what git printed.
## Behaviour
- It refreshes every 3 seconds and fetches in the background every 5 minutes.
- **Pull blocked by your local changes:** it offers *Stash, pull & re-apply*.
- If re-applying clashes, the file shows the `<<<<<<< ======= >>>>>>>` markers.
- Fix the file, then click **Mark as resolved**. The stash is kept until you drop it.
- **Pull hits a merge conflict:** choose *Resolve conflicts* (fix files, Mark as resolved,
Commit merge) or *Abort merge*.
- **Push when the remote has newer commits:** it offers *Pull, then push*.
- **Switching branch blocked by your changes:** it offers *Stash & switch*.
- **A network command needs a password, token, SSH passphrase or host-key confirmation:**
click **Retry in terminal**. gitdesk steps aside so git can ask you, then comes back.
- **Push refused as too big over HTTPS (HTTP 413)**, e.g. by Cloudflare's 100 MB upload limit:
gitdesk offers **Push over SSH** with the SSH address filled in. You can change the address,
and it's remembered per repo.
- Tick *Always push this repository over SSH* to set git's push URL, so pushes go over SSH
while fetches stay on HTTPS.
- If the site is behind Cloudflare, SSH needs an address that reaches the server directly:
a DNS-only hostname or the server's IP.
- **Another program has the repository busy** (GitHub Desktop, VS Code, Unity, OneDrive,
antivirus): gitdesk waits and retries for a few seconds. If a `.git/index.lock` is left
behind by a crashed git, it offers **Remove lock file & retry**.
Keys: `f` fetch · `p` pull · `u` push · `b` branch · `s` stash · `t` stashes · `d` discard ·
`o` add local repo · `n` new repo · `c` clone · `g` view on web · `l` log · `r` refresh · `space` tick/untick file · `m` file menu · `q` quit
## Set up SSH for git (Windows, optional)
`git-ssh-setup.ps1` sets up SSH, so pushes and Git LFS don't ask for your passphrase
every time. It's handy when HTTPS pushes are refused as too big (see **Push over SSH** below).
**Run it:** double-click `git-ssh-setup.cmd`. Run it as your normal user, not
"Run as administrator". From PowerShell, use:
```
powershell -NoProfile -ExecutionPolicy Bypass -File .\git-ssh-setup.ps1
```
The bypass applies to that one run only. Your system's execution policy isn't changed.
It asks for the SSH host. You can type `git.example.com`, `git.example.com:2222`, or paste an
SSH clone URL. Next time it offers the host you used last: press Enter to keep it, or type
another one to set up a second server. Then it:
1. turns on Windows' `ssh-agent` service. This step shows a UAC prompt, and only when the
service needs turning on. If the OpenSSH client is missing, it installs that too.
2. creates an ed25519 key `~/.ssh/id_ed25519_gitea` (it asks for a passphrase), or reuses the
one that's already there.
3. loads the key into ssh-agent. Windows keeps it loaded across reboots.
4. adds a `Host` entry for the server to `~/.ssh/config`. If one already exists, it leaves it
alone and shows what it would have written.
5. points git at Windows' OpenSSH (`core.sshCommand`), so git uses the agent. It also sets
`lfs.ssh.automultiplex false`, which stops Git LFS transfers over SSH from hanging.
6. shows your public key and copies it to the clipboard. Add it in Gitea: your avatar >
Settings > SSH / GPG Keys > Add Key.
7. verifies the key in Gitea (optional). Click **Verify** next to the key, paste the token
into the script, then paste the signature it copies back into Gitea.
8. tests the connection with `ssh -T`.
You can run it again safely. It reuses the key, doesn't add it to the agent twice, and never
changes an existing `~/.ssh/config` entry.
| Option | What it does |
|---|---|
| `-HostName git.example.com` | Skips the host prompt. `-HostName ""` skips the config entry and the test. |
| `-Port 2222` | SSH port (default 22). |
| `-User git` | SSH user (default `git`, which is right for Gitea, GitHub and GitLab). |
| `-KeyName id_ed25519_github` | Key file name in `~/.ssh` (default `id_ed25519_gitea`). |
| `-Comment "label"` | Label shown in Gitea's key list (default `user@computer`). |
| `-Force` | Replaces the existing key instead of reusing it. |
| `-NoVerify` | Skips the Gitea verify step (e.g. for GitHub). |
| `-Token <hex>` | Signs this Gitea verify token without asking for it. |
| `-NoTest` | Skips the connection test. |
Gitea's verify token expires quickly. If Gitea rejects the signature, click **Verify** again
and run it again with only the new token:
```
powershell -NoProfile -ExecutionPolicy Bypass -File .\git-ssh-setup.ps1 -NoTest -Token <new token>
```
If the site is behind Cloudflare's proxy, use a hostname or IP that reaches the server
directly. SSH doesn't go through the proxy.