https://github.com/marc2332/git
marcgit π§, a git worktree manager that I like
https://github.com/marc2332/git
git rust worktree
Last synced: 23 days ago
JSON representation
marcgit π§, a git worktree manager that I like
- Host: GitHub
- URL: https://github.com/marc2332/git
- Owner: marc2332
- License: mit
- Created: 2026-04-11T20:16:45.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-04-20T07:07:13.000Z (2 months ago)
- Last Synced: 2026-05-23T05:42:44.555Z (about 1 month ago)
- Topics: git, rust, worktree
- Language: Rust
- Homepage:
- Size: 32.2 KB
- Stars: 4
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
[](./LICENSE.md)
# π§ marcgit
A fancy git worktree manager. You call it as `mg` through a shell wrapper.
Projects live at `/trunk`, and every other worktree (PRs, feature branches) lives as a sibling folder next to `trunk`:
```
myproject/
βββ trunk/ # main worktree
βββ feat-login/ # mg work feat/login
βββ fix-typo/ # mg pr 42 (branch: fix/typo)
```
## Install
```sh
cargo install --git https://github.com/marc2332/git
```
Then wire the `mg` shell function into your rc:
```sh
# bash
eval "$(marcgit init bash)"
# zsh
eval "$(marcgit init zsh)"
# fish
marcgit init fish | source
# nushell β add to config.nu
marcgit init nushell | save -f ~/.config/nushell/marcgit.nu
# then: source ~/.config/nushell/marcgit.nu
```
The binary prints paths; the wrapper `cd`s to them. Same trick `zoxide` and `direnv` use.
**`mg pr` requires `gh`** (GitHub CLI) to look up the PR's branch name.
## Commands
| Command | What it does |
| -------------------------------- | ------------------------------------------------------------------------------ |
| `mg new ` / `mg n` | Create `.//trunk` and `git init` it. Jump in. |
| `mg clone ` / `mg c` | Clone a repo into `.//trunk`. Jump in. |
| `mg work ` / `mg w` | Create (or jump to) a sibling worktree for ``. Creates branch if new. |
| `mg pr ` / `mg p` | Fetch the PR via `gh`, create a worktree named after its head branch, jump in. |
| `mg trunk` / `mg t` | Jump to the project's `trunk` from any sibling worktree. |
| `mg list` / `mg l` | Print `git worktree list` for the current project. |
| `mg remove ` / `mg r` | Remove the worktree and delete its branch. Jump back to `trunk`. |
| `mg prune ` | Remove sibling worktrees whose last commit is older than `` days. Asks for confirmation; skips worktrees with modified or stashed files. `-n` / `--dry-run` to preview. |
| `mg init ` | Print the shell wrapper for `bash` / `zsh` / `fish` / `nushell`. |
| `mg config init` | Write a default `marcgit.toml` at the project root. Print its path. |
| `mg config path` | Print the path of the `marcgit.toml` reachable from the current directory. |
### Examples
```sh
mg new myproject # β ./myproject/trunk
mg clone https://github.com/user/repo.git foo # β ./foo/trunk
mg work feat/login # β ./myproject/feat-login (branch feat/login)
mg pr 42 # β ./myproject/fix-typo (PR #42's head branch)
mg trunk # β ./myproject/trunk
mg remove feat/login # removes worktree + branch
mg prune 30 # prune worktrees idle β₯ 30 days (asks first)
mg prune 30 -n # dry-run: just list what would be pruned
```
### Notes
- Slashes in a branch name become dashes in the folder β `feat/login` β `feat-login`. No nested subfolders.
- `mg work` and `mg pr` are idempotent: if the worktree already exists, they just jump.
- `mg pr` requires `gh` (GitHub CLI) to look up the PR's head branch name.
- `mg prune` measures age by each worktree's last commit date (`git log -1`). It refuses to remove worktrees with uncommitted changes, untracked files, or stashes recorded against their branch.
## Config
Optional `marcgit.toml` at the project root (next to `trunk/`). `mg config init` writes the default:
```toml
init-submodules = true # pull submodules on `mg work` (default: true)
```
## How it finds the project
Every command other than `new`, `clone`, and `init` needs to know which project you're in. It runs `git worktree list --porcelain` and picks the worktree whose folder is literally named `trunk`. That's the anchor β so don't rename it.
## License
[MIT](./LICENSE.md) Β© Marc EspΓn Sanz