# Gitte

A GTK4/libadwaita Git client for the GNOME desktop, written in Rust. It is heavily inspired by [Git Tower](https://www.git-tower.com/) and [Magit](https://magit.vc/). The name Gitte is a play on words. It is the diminutive form of the German female first name Brigitte and is pronounced "Git-ty" in English (with a hard G like in GIF).

![Git GUI showing staged and unstaged changes with a diff view of a Rust file, highlighting modified lines and chunk actions](https://wwwtech.de/pictures/419.png)

See [SCREENSHOTS.md](SCREENSHOTS.md) for more screenshots.

[![Get it on Flathub](https://flathub.org/api/badge?locale=en)](https://flathub.org/apps/de.wwwtech.gitte)

[![Get it for macOS](https://gitlab.com/dehesselle/gitte_macos/-/badges/release.svg?value_width=94&key_text=Get%20it%20for%20macOS&key_width=110)](https://gitlab.com/dehesselle/gitte_macos/-/releases/permalink/latest)

## Features

### Repositories

- Add, rename, and remove repositories; initialize new Git repos
- Clone repositories with a live progress dialog
- Search and configurable sort order (manual, by name, by last opened) on the start screen
- Copy paths or open them in the file manager
- Multi-window support with per-window state
- Open a repository from the command line: `gitte <path>` focuses an existing window for that repo, or opens a new one

### Changes & Diffs

- Working copy view with file status (modified, added, deleted, renamed) and split or unified layout
- Stage, unstage, and discard at file, hunk, or individual line level
- Color-coded diff viewer (additions/deletions) with sticky hunk headers
- Binary-file detection
- Inspect diffs for commits and stashes alongside the working copy
- Add files to `.gitignore` directly from the changes list

### Commits & History

- Write commit messages with subject and body; configurable maximum line length (global or per repo)
- Amend the last commit
- Paginated history with tag and upstream markers
- Search commits by message, author, or date
- Interactive rebase: squash/fixup, reorder via drag & drop, reword, and drop commits

### Branches & Tags

- Branches: create (including "create from here" on any commit), rename, delete, checkout local and remote
- Upstream tracking with ahead/behind counts and stash-before-switch for dirty working trees
- Merge another branch into the current one with strategy selection (fast-forward, merge commit, rebase, or squash)
- Collapsible branch groups in the sidebar
- Tags: lightweight and annotated, delete, push (with force option)
- Tag sorting by semver, alphabetical, or date — ascending or descending

### Syncing

- Pull with branch selection, fast-forward / merge / rebase strategies, auto-stash, prune, fetch tags, and conflict detection
- Push with branch selection, automatic upstream setup, force push (with visual warning), tag push, and no-op detection
- Remote list with per-remote tracking branches; fetch from a single remote or all at once
- Configurable auto-fetch interval (global or per repo)
- Export archives from any ref as `tar.gz`, `tar.xz`, or `zip`

### Stashes

- Create stashes with or without untracked files
- Apply, pop, and drop stashes
- Inspect stash diffs

### Authentication

- SSH key agent support with optional per-remote SSH key
- HTTP basic auth with secure keychain storage via Secret Service (D-Bus)
- Built-in askpass helper for password and SSH-passphrase prompts

### Customization

Available in *Preferences* (most settings have a per-repository override):

- Auto-fetch interval
- Diff font and compact-mode spacing
- Working-copy layout (split or unified)
- Per-repository Git identity (`user.name` / `user.email`)
- Tag sort method and direction
- Bypass local Git config (relevant for Flatpak — see below)

### Updates

- In-app notification banner when a new release is available, with per-version dismiss
- "What's new" release-notes dialog shown after upgrades

### Localization

Built with gettext. Available languages: English (source), German, Ukrainian. Contributions for other locales are welcome.

### UI

- Built on libadwaita for a native GNOME look and feel
- Resizable split panes with persistent positions and window-size persistence

### Keyboard Shortcuts

| Action                    | Shortcut       |
| ------------------------- | -------------- |
| New Window                | Ctrl+N         |
| Close Window              | Ctrl+W         |
| Search                    | Ctrl+F         |
| Add Repository            | Ctrl+Shift+A   |
| Preferences               | Ctrl+,         |
| Keyboard Shortcuts        | Ctrl+?         |
| Quit                      | Ctrl+Q         |
| Toggle Sidebar            | F9             |
| Fetch                     | Ctrl+Shift+F   |
| Pull                      | Ctrl+P         |
| Push                      | Ctrl+Shift+P   |
| Stash                     | Ctrl+Shift+S   |
| Stash Including Untracked | Ctrl+Shift+U   |
| Pop Latest Stash          | Ctrl+Shift+O   |
| Create Branch             | Ctrl+Shift+B   |
| Create Tag                | Ctrl+Shift+T   |
| Focus Commit Message      | Ctrl+Shift+C   |
| Commit                    | Ctrl+Return    |
| Stage/Unstage             | Space / Return |
| Discard Changes           | Delete         |

## Building

### Dependencies

- Rust toolchain (stable)
- GTK 4 (>= 4.20)
- libadwaita (>= 1.8)
- libgit2
- Meson
- Ninja

On Fedora:

```bash
sudo dnf install gtk4-devel libadwaita-devel libgit2-devel meson ninja-build
```

On Arch Linux:

```bash
sudo pacman -S gtk4 libadwaita libgit2 meson ninja
```

or use the community maintained [AUR package](https://aur.archlinux.org/packages/gitte-git)

```bash
yay -S gitte-git
```

On NixOS (or with Nix):

```bash
nix develop
```

This enters a dev shell with all dependencies provided via `flake.nix`.

### Build & Install

```bash
meson setup builddir
meson compile -C builddir
meson install -C builddir
```

> **Note:** `src/config.rs` is generated by Meson from `src/config.rs.in`. You need to run `meson compile` at least once before `cargo check` or `cargo build` will work.

## Flatpak

The Flatpak version of Gitte uses the `--filesystem=home` permission to access Git repositories in your home directory. This means that system-wide configuration files like `/etc/gitconfig` **cannot** be read from within the sandbox.

If you need settings from `/etc/gitconfig`, you can override the Flatpak permissions:

```bash
flatpak override --user --filesystem=/etc/gitconfig:ro de.wwwtech.gitte
```

Alternatively, you can copy the relevant settings into your user-specific `~/.gitconfig`.

### Sandbox limitations

When Gitte shells out to `git` from inside the Flatpak sandbox, a few features are disabled by default. Not as a policy decision, but because the helpers they rely on simply aren't reachable from inside the sandbox:

- **Git hooks** are bypassed (`core.hooksPath` is pointed at `/dev/null`). Hook scripts typically need interpreters (`bash`, `python`, `node`, project-specific tooling) and tools from your `$PATH` that don't exist inside the sandbox, so running them would mostly produce confusing failures rather than the behavior you configured on the host.
- **Credential helpers** (`credential.helper`, including any `credential.<url>.helper` overrides) are neutralized. Helpers like `libsecret`, `manager`, or custom scripts live on the host and can't be invoked from inside the sandbox. Gitte ships its own askpass helper so password and SSH-passphrase prompts still work; only the cached-credential helpers are unavailable.

These bypasses can be toggled in *Preferences → Bypass local Git config*, but flipping that switch alone does **not** make hooks or credential helpers start working. It only stops Gitte from suppressing them. To actually get hooks and host credential helpers to run, you need to invoke the host's `git` instead of the sandboxed one (see below).

### Using the host's `git` binary

History-rewriting operations shell out to `git`. By default Gitte invokes the bundled `git` inside the sandbox; user and system Git config files are bridged in via env vars so this normally Just Works.

If you want hooks, host credential helpers, a custom git build, or any other host-side tooling to participate, you can have Gitte run the `git` installed on the host. This requires two steps:

1. **Grant the Flatpak permission to spawn host commands:**

   ```bash
   flatpak override --user --talk-name=org.freedesktop.Flatpak de.wwwtech.gitte
   ```

   ⚠️ This permission effectively allows the app to escape the sandbox by spawning arbitrary host processes. Only enable it if you trust the application and understand the implication.

2. **Point Gitte at `flatpak-spawn` via dconf** (there is no UI for this on purpose):

   ```bash
   dconf write /de/wwwtech/gitte/git-command "'flatpak-spawn --host git'"
   ```

   The setting takes a single shell-style command line, it's split by `shell-words` rules. Common values:

   - `'git'`: default, sandbox-internal git
   - `'flatpak-spawn --host git'`: host's git via the Flatpak portal
   - `'/path/to/some/custom/git'`: absolute path to a specific binary

   To revert to the default:

   ```bash
   dconf reset /de/wwwtech/gitte/git-command
   ```

With `flatpak-spawn --host git` in effect, you'll typically also want to turn *Bypass local Git config* **off** in the preferences — otherwise Gitte will still pass `core.hooksPath=/dev/null` and `credential.helper=` to the host git, defeating the point of routing through the host.

## macOS app

The macOS version of Gitte comes packaged as native application bundles for both Apple Silicon and Intel architectures. They are built by and hosted at [a separate project on GitLab](https://gitlab.com/dehesselle/gitte_macos) due to the macOS infrastructure that is kindly being provided there.

## Contributing

Contributions are welcome! Please make sure your code passes `cargo clippy` without warnings before submitting a pull request. However, code generated fully or partially by Large Language Models (LLMs) such as ChatGPT, Copilot, or similar tools is not accepted. Please ensure that all submitted code is written and understood by you, so it can be properly reviewed and maintained.

## Code of Conduct

This project follows the [GNOME Code of Conduct](https://wiki.gnome.org/Foundation/CodeOfConduct).

## License

Gitte is licensed under the [AGPL-3.0-or-later](COPYING).
