{"id":50477187,"url":"https://github.com/marc2332/git","last_synced_at":"2026-06-01T14:02:34.019Z","repository":{"id":350744692,"uuid":"1208097718","full_name":"marc2332/git","owner":"marc2332","description":"marcgit 🚧, a git worktree manager that I like","archived":false,"fork":false,"pushed_at":"2026-04-20T07:07:13.000Z","size":33,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-23T05:42:44.555Z","etag":null,"topics":["git","rust","worktree"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marc2332.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-11T20:16:45.000Z","updated_at":"2026-04-20T07:07:16.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/marc2332/git","commit_stats":null,"previous_names":["marc2332/git"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/marc2332/git","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marc2332%2Fgit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marc2332%2Fgit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marc2332%2Fgit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marc2332%2Fgit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marc2332","download_url":"https://codeload.github.com/marc2332/git/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marc2332%2Fgit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33777971,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-01T02:00:06.963Z","response_time":115,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["git","rust","worktree"],"created_at":"2026-06-01T14:02:32.913Z","updated_at":"2026-06-01T14:02:34.008Z","avatar_url":"https://github.com/marc2332.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE.md)\n\n# 🚧 marcgit\n\nA fancy git worktree manager. You call it as `mg` through a shell wrapper.\n\nProjects live at `\u003cproject\u003e/trunk`, and every other worktree (PRs, feature branches) lives as a sibling folder next to `trunk`:\n\n```\nmyproject/\n├── trunk/             # main worktree\n├── feat-login/        # mg work feat/login\n└── fix-typo/          # mg pr 42 (branch: fix/typo)\n```\n\n## Install\n\n```sh\ncargo install --git https://github.com/marc2332/git\n```\n\nThen wire the `mg` shell function into your rc:\n\n```sh\n# bash\neval \"$(marcgit init bash)\"\n\n# zsh\neval \"$(marcgit init zsh)\"\n\n# fish\nmarcgit init fish | source\n\n# nushell — add to config.nu\nmarcgit init nushell | save -f ~/.config/nushell/marcgit.nu\n# then: source ~/.config/nushell/marcgit.nu\n```\n\nThe binary prints paths; the wrapper `cd`s to them. Same trick `zoxide` and `direnv` use.\n\n**`mg pr` requires `gh`** (GitHub CLI) to look up the PR's branch name.\n\n## Commands\n\n| Command                          | What it does                                                                   |\n| -------------------------------- | ------------------------------------------------------------------------------ |\n| `mg new \u003cname\u003e` / `mg n`         | Create `./\u003cname\u003e/trunk` and `git init` it. Jump in.                            |\n| `mg clone \u003curl\u003e \u003cname\u003e` / `mg c` | Clone a repo into `./\u003cname\u003e/trunk`. Jump in.                                   |\n| `mg work \u003cbranch\u003e` / `mg w`      | Create (or jump to) a sibling worktree for `\u003cbranch\u003e`. Creates branch if new.  |\n| `mg pr \u003cnumber\u003e` / `mg p`        | Fetch the PR via `gh`, create a worktree named after its head branch, jump in. |\n| `mg trunk` / `mg t`              | Jump to the project's `trunk` from any sibling worktree.                       |\n| `mg list` / `mg l`               | Print `git worktree list` for the current project.                             |\n| `mg remove \u003cbranch\u003e` / `mg r`    | Remove the worktree and delete its branch. Jump back to `trunk`.               |\n| `mg prune \u003cdays\u003e`                | Remove sibling worktrees whose last commit is older than `\u003cdays\u003e` days. Asks for confirmation; skips worktrees with modified or stashed files. `-n` / `--dry-run` to preview. |\n| `mg init \u003cshell\u003e`                | Print the shell wrapper for `bash` / `zsh` / `fish` / `nushell`.               |\n| `mg config init`                 | Write a default `marcgit.toml` at the project root. Print its path.            |\n| `mg config path`                 | Print the path of the `marcgit.toml` reachable from the current directory.    |\n\n### Examples\n\n```sh\nmg new myproject                              # → ./myproject/trunk\nmg clone https://github.com/user/repo.git foo # → ./foo/trunk\nmg work feat/login                            # → ./myproject/feat-login (branch feat/login)\nmg pr 42                                      # → ./myproject/fix-typo (PR #42's head branch)\nmg trunk                                      # → ./myproject/trunk\nmg remove feat/login                          # removes worktree + branch\nmg prune 30                                   # prune worktrees idle ≥ 30 days (asks first)\nmg prune 30 -n                                # dry-run: just list what would be pruned\n```\n\n### Notes\n\n- Slashes in a branch name become dashes in the folder — `feat/login` → `feat-login`. No nested subfolders.\n- `mg work` and `mg pr` are idempotent: if the worktree already exists, they just jump.\n- `mg pr` requires `gh` (GitHub CLI) to look up the PR's head branch name.\n- `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.\n\n## Config\n\nOptional `marcgit.toml` at the project root (next to `trunk/`). `mg config init` writes the default:\n\n```toml\ninit-submodules = true   # pull submodules on `mg work` (default: true)\n```\n\n## How it finds the project\n\nEvery 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.\n\n## License\n\n[MIT](./LICENSE.md) © Marc Espín Sanz\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarc2332%2Fgit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarc2332%2Fgit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarc2332%2Fgit/lists"}