|
1 | 1 | <div align="center"> |
2 | 2 |
|
3 | | -<img src="assets/logo.svg" alt="Git Switch" width="128" height="128" /> |
| 3 | +<img src="assets/logo.svg" alt="Git Switch" width="96" height="96" /> |
4 | 4 |
|
5 | 5 | # Git Switch |
6 | 6 |
|
7 | | -**A fast, native macOS Git client that runs your dev servers, too.** |
| 7 | +A fast, native Git client that runs your dev servers too. |
8 | 8 |
|
9 | | -[](https://tauri.app) |
| 9 | +[](https://tauri.app) |
10 | 10 | [](https://react.dev) |
11 | | -[](https://www.typescriptlang.org) |
12 | | -[](https://tailwindcss.com) |
13 | | -[](https://www.rust-lang.org) |
14 | | -[](#install) |
15 | | -[](LICENSE) |
| 11 | +[](https://www.rust-lang.org) |
| 12 | +[](#install) |
| 13 | +[](#install) |
| 14 | +[](LICENSE) |
16 | 15 |
|
17 | 16 | </div> |
18 | 17 |
|
19 | 18 | --- |
20 | 19 |
|
21 | | -## Features |
22 | | - |
23 | | -**Git** |
24 | | -- Multi-repo sidebar — folder picker (multi-select) or drag-and-drop, persists across launches |
25 | | -- Per-repo status tints in the sidebar — behind = rose · uncommitted = amber · ahead = emerald |
26 | | -- Searchable branch picker · create branch from scratch (`git switch -c`) or check out remote as local |
27 | | -- Dirty-tree guard before switching, with confirmation dialog |
28 | | -- Adaptive primary action button — switches between **Pull / Push / Publish / Fetch** based on ahead / behind / upstream state |
29 | | -- `⋯` overflow menu consolidates every git action: refresh, fetch, pull, push, create branch, publish branch, show history |
30 | | -- Publish branch with one click (`git push -u origin <branch>`) when upstream is missing |
31 | | -- Stage / unstage selected · stage all · commit · optimistic UI (file list flips instantly) |
32 | | -- **Undo last commit** — safe `git reset --soft HEAD~1`, only shown when the commit hasn't been pushed |
33 | | -- **Inline diff viewer** for any changed file (eye icon on the row) — syntax-light unified diff with sticky line-number gutter |
34 | | -- **Commit history popup** — last 50 commits with author, short hash, relative time |
35 | | -- Sensitive files (`.env`, `*.pem`, SSH keys, …) surface at the top of the changes list in red — one click adds them to `.gitignore` and untracks |
36 | | -- Ahead / behind indicators in the dashboard header |
37 | | -- Native FS watcher (`notify` / FSEvents) auto-refreshes the GUI when the terminal touches the repo |
38 | | -- Shift-click range select · `⌘↵` commit · `⌘R` refresh · `⌘P` pull · `⌘⇧P` push |
39 | | - |
40 | | -**AI commits** |
41 | | -- ✨ Generate Conventional-Commits messages from the staged diff via Gemini |
42 | | -- Live model picker — only shows models your API key can actually invoke, auto-falls back when quota's hit |
43 | | - |
44 | | -**Run / dev environments** |
45 | | -- Multiple run targets per repo — `yarn dev`, `yarn dev:worker`, `cargo run`, each with its own terminal tab, port, and restart command |
46 | | -- Real PTY (xterm.js + `portable-pty`) → ANSI colors, progress bars, `⌃C`, login-shell PATH all work |
47 | | -- Smart port management — read from `.env` or set per-target; conflicts prompt before killing the holder |
48 | | -- Process-group kills (`setsid` + `killpg`) — `nodemon` orphans and detached `node` children die with the parent, no zombie servers |
49 | | -- Branch-aware auto-restart — switch branch, every running target relaunches |
50 | | -- Sleep-safe; clean shutdown on app close |
51 | | - |
52 | | -**Groups** |
53 | | -- Bundle multiple repos as a group, fire them all in parallel with one click |
54 | | -- Filterable picker with sticky select-all row (handy when you've added 20+ repos) |
55 | | -- Color-coded bulk actions (Run / Stop / Restart) react to live aggregate status |
56 | | -- Each member runs with **its own** saved config — the group is just a launcher |
57 | | - |
58 | | -**UX & performance** |
59 | | -- Light + dark themes that propagate instantly across every panel (including xterm.js) |
60 | | -- macOS-style frosted-glass toasts (Sonner) with severity-encoded icons |
61 | | -- Tooltips on every icon and the adaptive sync button (shows the underlying git command) |
62 | | -- Rolling command-output log with per-row status |
63 | | -- Async backend — `git fetch` / `pull` / `push` never freeze the UI |
64 | | -- Batched sidebar refresh — one IPC fetches quick-status for every repo in parallel |
65 | | -- Lazy-loaded heavy panels (xterm.js, every dialog) — small initial JS payload |
| 20 | +## What it does |
66 | 21 |
|
67 | | ---- |
| 22 | +Multi-repo Git GUI with a built-in PTY-backed dev-server launcher. Switch |
| 23 | +branches, commit, push, and start every project's dev server from one |
| 24 | +window. |
| 25 | + |
| 26 | +## Highlights |
| 27 | + |
| 28 | +- **Multi-repo sidebar** with live status tints and an FS watcher. |
| 29 | +- **Adaptive sync button** that switches between Pull / Push / Publish / Fetch based on branch state. |
| 30 | +- **Inline diff viewer** and **commit history popup**. |
| 31 | +- **Undo last commit** (safe `git reset --soft`, never on pushed history). |
| 32 | +- **AI commit messages** via Gemini, with auto-fallback when a model is rate-limited. |
| 33 | +- **Run targets** like `yarn dev`, `cargo run`, each with its own xterm tab and port management. |
| 34 | +- **Groups** to bundle repos and run them in parallel. |
| 35 | +- **Menu-bar tray** showing the active repo's branch and ahead/behind status. |
| 36 | +- **Desktop notifications** when teammates push new commits to your branch. |
| 37 | +- **Six accent themes** (Neutral, Orange, Blue, Green, Rose, Violet) plus light/dark mode. |
| 38 | +- **Async backend**, so `git fetch` / `pull` / `push` never freeze the UI. |
68 | 39 |
|
69 | 40 | ## Install |
70 | 41 |
|
| 42 | +One command. Detects your OS, fetches the latest release, drops it in |
| 43 | +the right place. Re-run to update. |
| 44 | + |
71 | 45 | ```bash |
72 | | -# Prerequisites (one-time) |
73 | | -xcode-select --install # git |
74 | | -brew install node # Node 20+ |
75 | | -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh && source "$HOME/.cargo/env" |
76 | | -brew install librsvg # for icon generation |
| 46 | +curl -fsSL https://raw.githubusercontent.com/Avijit07x/git-switch/main/install.sh | bash |
| 47 | +``` |
| 48 | + |
| 49 | +### Build from source |
77 | 50 |
|
78 | | -# Clone + run |
| 51 | +```bash |
79 | 52 | git clone git@github.com:Avijit07x/git-switch.git |
80 | 53 | cd git-switch |
81 | 54 | yarn install |
82 | 55 | yarn tauri:dev |
83 | 56 | ``` |
84 | 57 |
|
85 | | -First launch compiles ~400 Rust crates — expect 2–5 min cold, seconds thereafter. |
86 | | - |
87 | | -### Build a `.app` / `.dmg` |
| 58 | +Prerequisites: Git, Node 20+, Rust stable. On Debian / Ubuntu also install |
| 59 | +`libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev patchelf`. |
88 | 60 |
|
89 | | -```bash |
90 | | -yarn tauri icon assets/logo.svg # first time only |
91 | | -yarn tauri:build |
92 | | -``` |
| 61 | +First launch compiles roughly 400 Rust crates. Expect 2 to 5 minutes |
| 62 | +cold, seconds thereafter. |
93 | 63 |
|
94 | | -Output: `src-tauri/target/release/bundle/macos/Git Switch.app` and the matching `.dmg`. For a Universal binary: |
| 64 | +### Build a release bundle |
95 | 65 |
|
96 | 66 | ```bash |
97 | | -rustup target add x86_64-apple-darwin aarch64-apple-darwin |
98 | | -yarn tauri build --target universal-apple-darwin |
| 67 | +yarn tauri:build |
99 | 68 | ``` |
100 | 69 |
|
101 | | -### First launch on macOS |
102 | | - |
103 | | -Git Switch ships with **ad-hoc signing** (free, no Apple Developer account). macOS Gatekeeper will warn you the very first time: |
104 | | - |
105 | | -1. Right-click **Git Switch.app** in Finder → **Open** |
106 | | -2. Confirm in the dialog that appears |
107 | | -3. macOS remembers your choice — every launch after that is normal |
108 | | - |
109 | | -If you'd rather skip the prompt entirely, you can strip the quarantine flag once: |
| 70 | +Output lands in `src-tauri/target/release/bundle/`. The installer script |
| 71 | +handles signing quirks automatically; if you're distributing a manual |
| 72 | +build on macOS, strip the quarantine flag once: |
110 | 73 |
|
111 | 74 | ```bash |
112 | 75 | xattr -dr com.apple.quarantine "/Applications/Git Switch.app" |
113 | 76 | ``` |
114 | 77 |
|
115 | | ---- |
116 | | - |
117 | 78 | ## Safety |
118 | 79 |
|
119 | | -Out of scope by design: force push, rebase, hard reset, discard, stash, merge-conflict resolution, raw command input. The one carve-out is `git reset --soft HEAD~1` (the **Undo last commit** button), which never touches your working tree and only appears when the commit hasn't been pushed. |
120 | | - |
121 | | -Auth relies on your existing Git setup (SSH keys, Keychain, `gh`, credential helper) — Git Switch stores nothing related to remotes. |
122 | | - |
123 | | -The Gemini API key (if set) lives in `localStorage` and is only ever sent to `generativelanguage.googleapis.com` when you click ✨ Generate. |
| 80 | +Out of scope: force push, rebase, hard reset, discard, stash, and |
| 81 | +merge-conflict resolution. The one carve-out is `git reset --soft HEAD~1` |
| 82 | +behind the **Undo** button, which only appears for local-only commits |
| 83 | +that haven't been pushed. |
124 | 84 |
|
125 | | - |
126 | | ---- |
| 85 | +Auth uses your existing Git setup (SSH keys, Keychain, `gh`, credential |
| 86 | +helper). The Gemini API key, if set, lives in `localStorage` and is only |
| 87 | +sent to `generativelanguage.googleapis.com` when you click ✨ Generate. |
127 | 88 |
|
128 | 89 | ## License |
129 | 90 |
|
|
0 commit comments