Skip to content

marc2332/git

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

9 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

License: MIT

🚧 marcgit

A fancy git worktree manager. You call it as mg through a shell wrapper.

Projects live at <project>/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

cargo install --git https://github.com/marc2332/git

Then wire the mg shell function into your rc:

# 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 cds 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 <name> / mg n Create ./<name>/trunk and git init it. Jump in.
mg clone <url> <name> / mg c Clone a repo into ./<name>/trunk. Jump in.
mg work <branch> / mg w Create (or jump to) a sibling worktree for <branch>. Creates branch if new.
mg pr <number> / 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 <branch> / mg r Remove the worktree and delete its branch. Jump back to trunk.
mg prune <days> Remove sibling worktrees whose last commit is older than <days> days. Asks for confirmation; skips worktrees with modified or stashed files. -n / --dry-run to preview.
mg init <shell> 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

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:

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 Β© Marc EspΓ­n Sanz

About

marcgit 🚧, a git worktree manager that I like

Topics

Resources

License

Stars

Watchers

Forks

Contributors