Skip to content

puria/gg

Repository files navigation

gg

gg is a small Go CLI that resolves a GitHub repository to a local checkout path, clones it if needed, and is designed to be wrapped by a shell function so gg f credim can still land you inside the repo.

Repos are stored as a container directory with a bare Git repo plus worktrees:

<root>/<host>/<owner>/<repo>/
  .bare/
  main/
  worktrees/<name>/
  PR/<number>/

Install

With mise

mise use -g github:puria/gg@latest

With Go

go install github.com/puria/gg@latest

Config

gg reads JSON config from:

$XDG_CONFIG_HOME/gg/config
~/.config/gg/config

You can print the active path with:

command gg config-path

You can persist an alias with:

command gg alias ForkbombEu/credimi credim

You can create a starter config with:

command gg init-config

Example config:

{
  "root": "/home/puria/src",
  "host": "github.com",
  "aliases": {
    "f": "ForkbombEu",
    "credim": "credimi",
    "fc": "ForkbombEu/credimi",
    "f/credimi": "ForkbombEu/credimi"
  }
}

Alias resolution works in this order:

  • exact alias first, so gg fc can map straight to ForkbombEu/credimi
  • per-segment alias expansion, so gg f credim becomes ForkbombEu/credimi
  • final exact alias pass on owner/repo, so f/credimi can also be overridden directly

After adding an alias like this:

command gg alias ForkbombEu/credimi credim

you can just run:

gg credim

If the repo is missing, gg creates the repo container and checks out the default branch into main/. If it already exists, the shell wrapper cds into <repo>/main.

If you pass just an owner like gg ForkbombEu or an owner alias like gg f, gg goes to <root>/<host>/<owner>.

Usage

gg ForkbombEu
gg ForkbombEu/credimi
gg ForkbombEu credimi
gg f/credim
gg f credim
gg credimi newworktree
gg credimi 99
gg md init puria/example
gg md up
gg new puria/example
gg list credimi
gg status credimi
gg prune credimi

The binary prints the local checkout path and clones the repo first if it does not exist yet.

md, new, list, status, and prune are reserved command names. If you ever need an owner or repo alias with one of those names, use gg path ... as the escape hatch.

Markdown Metadata

gg md init <owner/repo> creates a new local repository and seeds it with markdown metadata files from puria/md.

gg md up runs inside an existing Git repository and adds or updates those same metadata files in place.

Worktrees And PRs

If the first argument already resolves to a full repo by itself, the next argument is treated as a repo-local target:

gg credimi newworktree
gg credimi 99
gg credimi \#99
gg f credim feature-x
gg ForkbombEu credimi feature-x

Behavior:

  • gg credimi newworktree creates or reuses <repo>/worktrees/newworktree
  • it also creates a local branch named newworktree for that worktree
  • gg credimi 99 creates or reuses <repo>/PR/99
  • it checks out PR 99 there with gh pr checkout 99 --detach
  • plain gg credimi goes to <repo>/main
  • plain gg ForkbombEu goes to <root>/<host>/ForkbombEu

The shell wrapper then cds into the resulting path, so it feels like the old gg flow.

Management Commands

These commands do not cd; they print information or perform maintenance:

gg list credimi
gg status credimi
gg prune credimi
gg prune --dry-run
gg prune --yes

Behavior:

  • gg list credimi prints main, worktrees/*, and PR/* entries for the managed repo
  • gg status credimi runs git status --short --branch for each known worktree
  • gg prune credimi removes only green worktrees/* and PR/* checkouts, then cleans stale Git worktree metadata and leftover empty directories
  • green entries are clean, have no matching stash, and have no local-only commits
  • dirty files, stashes, and committed work that is not pushed or merged are kept
  • gg prune without a repo argument scans the current repo, owner directory, or host root such as ~/src/github.com
  • gg prune --dry-run only prints the green/yellow/red plan
  • gg prune --yes applies the no-argument scan without prompting

Shell Integration

A binary cannot cd the parent shell on its own, so the normal setup is a tiny wrapper function that delegates to the Go binary.

Fish

command gg shell-init fish > ~/.config/fish/functions/gg.fish

Or inline:

function gg --description 'manage git repos'
    switch "$argv[1]"
    case help -h --help version --version shell-init config-path init-config path alias list ls status prune rm
        command gg $argv
        return $status
    case new md
        set -l dir (command gg $argv)
        or return $status

        cd $dir
        return $status
    end

    set -l dir (command gg path $argv)
    or return $status

    cd $dir
end

Bash / Zsh

eval "$(command gg shell-init bash)"

About

`gg` is a small Go CLI that resolves a GitHub repository to a local checkout path, clones it if needed, and is designed to be wrapped by a shell function so `gg f credim` can still land you inside the repo.could not prompt

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages