Skip to content

Type-Delta/gdx

Repository files navigation

gdx (Git Developer Experience)

The git CLI wrapper that treats you like a human, not a compiler.

License Status

Warning

⚠️ ALPHA WARNING: This project is currently in a "trial phase" (i.e., I'm dogfooding it daily). Expect breaking changes, missing features, and the occasional hiccup.


What is gdx?

gdx is a drop-in wrapper for the Git CLI. It doesn't replace Git; it just makes it less... unpleasant.

It wraps standard git commands with intelligent shorthands and adds powerful new capabilities that Git is missing like safety rails for destructive actions (undoable reset --hard), new workflows for parallel editing and local analytics, git output enhancements, and AI-powered commit message generation.

Why gdx?

  • 👍 Convenience: Type less, do more. git status? how about gdx s, git reset HEAD~3? why not gdx res ~3
  • 🛡️ Safety: gdx clear backs up before it wipes, and gdx history undo is Ctrl+Z for your repo. No more "oops" moments.
  • ✨ Enhanced Output: Git's output is... functional. gdx makes it beautiful and easier for humans to digest.
  • 🧠 Logic: Handles the things Git makes hard, like dropping a range of stashes, working with worktrees, or submodules.
  • 📊 Local-First Stats: Beautiful TrueColor graphs and stats generated from your local history.
  • 🤖 AI Integration: Generate commit messages and roast your history with local or cloud LLMs.

Installation

With NPM

Default (Recommended)

Uses the bundled JS version. Works everywhere Node.js 18+ is installed. This is the easiest way to get started and ensures maximum compatibility.

npm i -g gdx

Prebuilt Binary

Downloads a precompiled native binary. No runtime dependency on Node/Bun for execution.

GDX_USE_PREBUILT=1 npm i -g gdx # bash / zsh
# or
$env:GDX_USE_PREBUILT='1'; npm i -g gdx # powershell / fish

Build Locally

Compiles a native binary on your machine during install. Requires Bun to be installed.

GDX_BUILD_NATIVE=1 npm i -g gdx # bash / zsh
# or
$env:GDX_BUILD_NATIVE='1'; npm i -g gdx # powershell / fish

[!NOTE] If your environment sets ignore-scripts=true, the installation will succeed but default to the Node.js fallback. Run gdx doctor to verify your installation status.

Download Manually

Prebuilt stand-alone binaries are available on the Releases page.

Build it yourself

Requires Bun to be installed.

git clone https://github.com/Type-Delta/gdx.git --depth 1
cd gdx
bun install
bun run build

Your compiled binary will be in ./dist/ folder.

Optional: Shell Integration

To enable features like gdx parallel switch (auto-cd into worktrees) and tab completion, you need to add shell integration.

Shell integration provides:

  • Auto-cd support: Allows switching between parallel worktrees and submodules without needing to cd into them manually.
  • Tab completion: Intelligent completion for gdx commands, shorthands, and git subcommands
  • Completion fallback: Falls back to native git completion when gdx has no suggestions (git fallback requires you to install git's completion scripts separately)

To add shell integration, add the following line to the End of your shell profile (~/.bashrc, ~/.zshrc, etc.):

For bash and zsh:

eval "$(gdx --init bash)"  # for bash
eval "$(gdx --init zsh)"   # for zsh

For fish:

gdx --init fish | source

For PowerShell:

To find your profile path, run $PROFILE in PowerShell.

Invoke-Expression (& { (gdx --init pwsh | Out-String) })

Tip

You can add --cmd to the gdx --init command to create custom aliases. For example, gdx --init zsh --cmd g will create g as an alias for gdx.

Core Features

1. Intelligent Shorthands

gdx isn't just a list of static aliases. It understands partial commands and expands them smartly.

gdx s                 # -> git status
gdx sta               # -> git stash
gdx statu             # -> git status
gdx lg                # -> git log --oneline --graph --all --decorate
gdx pu -au            # -> git pull --allow-unrelated-histories
gdx ps -fl            # -> git push --force-with-lease
gdx cmi -m "Fix bug"  # -> git commit -m "Fix bug"
gdx reset ~2          # -> git reset HEAD~2

Note

This wrapper forwards unrecognized commands directly to git, so you can use it as a full git replacement.

If GDX still gets in your way, just run gdx --bypass <git-commands> to skip gdx intervention altogether.

2. Smart Linting

Catch issues before they reach the remote. gdx lint checks for:

  • Spelling errors in commit messages
  • Conflict markers left in code
  • Sensitive content (keys, tokens)
  • Large files

You can configure gdx to run this automatically before every push.

3. The Safety Net

We've all accidentally nuked changes we meant to keep. gdx gives you ways back:

  • gdx clear: Creates a timestamped patch backup, then effectively runs reset --hard & clean -fd.

  • gdx clear pardon: "Wait, I didn't mean to do that." Applies the backup patch and restores your changes.

  • gdx snap: Creates a repository/worktree+index backup you can switch back to later.

  • gdx history (Experimental): Ctrl+Z for Git. gdx keeps a repository-local journal of the commands it runs (and picks up direct git ref changes from reflogs, or live via gdx history hook) so you can step through them:

    gdx history           # List recorded transactions (newest first)
    gdx history undo      # Undo the most recent transaction
    gdx history redo      # ...changed your mind? bring it back
    gdx history show 0    # Inspect a transaction in detail

    Undo and redo refuse to touch anything that has diverged since the recording — no silent overwrites. Entries respect a retention limit (history.maxEntries), and recording can be turned off with history.enabled.

4. Parallel Worktrees (Experimental)

A wrapper for git worktree that reduces the friction of managing multiple worktrees, it handles the setup, switching, syncing changes, and cleanup of parallel worktrees so you can focus on coding instead of git logistics.

It also works great with detached worktrees, allowing you to quickly spin up a fork without worrying about getting a branch locked to it.

# Manage forked worktrees for the current branch
gdx parallel fork    # Create a new temp-backed fork
gdx parallel list    # See where your forks are
gdx parallel switch  # Switch between forks (requires shell integration)
gdx parallel open    # Open any fork in your default editor
gdx parallel join    # Merge changes from a fork back to main
gdx parallel sync    # Sync forks with the main (origin worktree)
gdx parallel pick    # Cherry-pick a commit from between forks
gdx parallel remove  # Remove a fork when you're done

Additionally, gdx parallel fork can auto-initialize submodules, install dependencies using detected package managers (see parallel.init config for options), and copy ignored env files if configured (see parallel.envPaths config for options), getting the fork ready for work in no time.

5. Git Output for Humans

Admit it, Git's default output isn't exactly designed for readability. gdx enhances the output of some commands with better formatting to make it less "git" to read.

Currently, we only support enhanced formatting for gdx diff and gdx show, but more commands will be added in the future. (feel free to request what commands you'd like to see enhanced!)

Example: gdx diff

diff example

Note

The enhanced output is only enabled when the output is TTY (i.e., in the terminal) plus other conditions based on the command (e.g., diff must be run without --name-only). If you pipe the output to a file or another command, it will fall back to the standard Git output.

If you want to disable the enhanced output altogether, you can set enhancedOutput to false in the config.

Tip

Enhanced gdx show allows you to navigate between commits in the pager with ←→ keys. This is especially useful when viewing a file's history.

6. Advanced Stash Management

Git stash is great until you need to clean it up.

gdx sta l           # git stash list
gdx sta drop 2..6   # Drops stashes 2 through 6.
                    # (Drops high->low to prevent index shifting)
gdx stash d pardon  # Restores the last dropped stash.

7. GitHub CLI Wrapper (Experimental)

Similar to how gdx wraps git, gdx gh wraps the GitHub CLI (gh) to provides better UX and some QoL features like:

Example: gdx gh repo create

Instead of asking you millions of obvious questions, gdx looks around to figure out what you want and only asks what matter.

See how it works
flowchart TD
   classDef ask fill:#f59e0b,stroke:#b45309,color:#1f2937,font-weight:bold
   classDef auto fill:#34d399,stroke:#059669,color:#064e3b,font-weight:bold
   classDef skip fill:#94a3b8,stroke:#475569,color:#1e293b
   classDef decision fill:#e0e7ff,stroke:#6366f1,color:#312e81
   classDef mode fill:#6366f1,stroke:#4338ca,color:#ffffff,font-weight:bold
   classDef final fill:#0ea5e9,stroke:#0369a1,color:#ffffff,font-weight:bold

   START(["gdx gh repo create"]) --> MODE{"Which mode?"}
   class MODE decision

   MODE -- "--template / -p given" --> T["🧩 From template"]:::mode
   MODE -- "--source given,<br/>or inside a git repo" --> P["📤 Push local"]:::mode
   MODE -- "otherwise" --> S["✨ From scratch"]:::mode

   %% ───────────── From scratch ─────────────
   subgraph SG_S [" From scratch "]
      S --> S_NAME{"Name in args?"}:::decision
      S_NAME -- yes --> S_NAME_A["Skip — use positional arg"]:::skip
      S_NAME -- no --> S_NAME_Q["Ask: repository name"]:::ask

      S_NAME_A & S_NAME_Q --> S_DESC{"--description given?"}:::decision
      S_DESC -- yes --> S_DESC_A["Skip"]:::skip
      S_DESC -- no --> S_DESC_Q["Ask: description<br/><i>(optional)</i>"]:::ask

      S_DESC_A & S_DESC_Q --> S_LIC{"--license given?"}:::decision
      S_LIC -- yes --> S_LIC_A["Skip"]:::skip
      S_LIC -- no --> S_LIC_Q["Ask: license<br/><i>(optional dropdown)</i>"]:::ask

      S_LIC_A & S_LIC_Q --> S_VIS{"--public/--private/<br/>--internal given?"}:::decision
      S_VIS -- yes --> S_VIS_A["Skip"]:::skip
      S_VIS -- no --> S_VIS_Q["Ask: visibility<br/><i>(default: private)</i>"]:::ask

      S_VIS_A & S_VIS_Q --> S_CLONE["Auto: --clone<br/><i>(unless --clone/--no-clone given)</i>"]:::auto
   end

   %% ───────────── From template ─────────────
   subgraph SG_T [" From template "]
      T --> T_NAME{"Name in args?"}:::decision
      T_NAME -- yes --> T_NAME_A["Skip — use positional arg"]:::skip
      T_NAME -- no --> T_NAME_Q["Ask: repository name"]:::ask

      T_NAME_A & T_NAME_Q --> T_DESC{"--description given?"}:::decision
      T_DESC -- yes --> T_DESC_A["Skip"]:::skip
      T_DESC -- no --> T_DESC_Q["Ask: description<br/><i>(optional)</i>"]:::ask

      T_DESC_A & T_DESC_Q --> T_LIC["License question skipped<br/><i>(template provides files)</i>"]:::skip

      T_LIC --> T_VIS{"--public/--private/<br/>--internal given?"}:::decision
      T_VIS -- yes --> T_VIS_A["Skip"]:::skip
      T_VIS -- no --> T_VIS_Q["Ask: visibility<br/><i>(default: private)</i>"]:::ask

      T_VIS_A & T_VIS_Q --> T_CLONE["Auto: --clone if outside a repo<br/><i>(unless --clone/--no-clone given)</i>"]:::auto
   end

   %% ───────────── Push local ─────────────
   subgraph SG_P [" Push local "]
      P --> P_META["Read package.json /<br/>pyproject.toml metadata"]:::auto

      P_META --> P_NAME{"Name in args<br/>or in metadata?"}:::decision
      P_NAME -- "in args" --> P_NAME_A["Skip"]:::skip
      P_NAME -- "in metadata" --> P_NAME_M["Auto-fill from manifest"]:::auto
      P_NAME -- neither --> P_NAME_Q["Ask: repository name"]:::ask

      P_NAME_A & P_NAME_M & P_NAME_Q --> P_DESC{"--description given<br/>or in metadata?"}:::decision
      P_DESC -- "in args" --> P_DESC_A["Skip"]:::skip
      P_DESC -- "in metadata" --> P_DESC_M["Auto-fill from manifest"]:::auto
      P_DESC -- neither --> P_DESC_Q["Ask: description<br/><i>(optional)</i>"]:::ask

      P_DESC_A & P_DESC_M & P_DESC_Q --> P_VIS{"--public/--private/<br/>--internal given?"}:::decision
      P_VIS -- yes --> P_VIS_A["Skip"]:::skip
      P_VIS -- no --> P_VIS_Q["Ask: visibility<br/><i>(default: private)</i>"]:::ask

      P_VIS_A & P_VIS_Q --> P_FILL["Auto: --source ‹repo root›<br/>--remote origin · --push"]:::auto
   end

   S_CLONE & T_CLONE & P_FILL --> CONFIRM["📋 Show summary &<br/>confirm"]:::final
   CONFIRM --> RUN(["▶ gh repo create ‹args›"]):::final

   %% Legend
   subgraph LEGEND ["Legend"]
      L1["Asked interactively"]:::ask
      L2["Auto-filled"]:::auto
      L3["Skipped — already provided"]:::skip
   end
Loading

With this you will only be asked a maximum of 4 questions, only the ones you care about.

Oh! did I mention that the "Form" now looks like this?

gh repo create tui

8. Commits Message Generation

Struggling to come up with a commit message? Let gdx do it for you.

gdx commit auto   # Generates a commit message based on staged changes, then commits them.
# or
# Generates a commit message based on staged changes, but does not commit them.
# `--copy` also copies the message to clipboard.
gdx cmi auto --no-commit --copy
# You can also configure which LLM to use with `gdx-config`

Unlike most AI commit message generators, by default gdx creates messages generation guidelines based on your repo's history and conventions. This ensures the generated messages fit your project's style and tone. Said guidelines are updated every month to reflect your evolving commit style.

9. Fun & Analytics

Tools to help you feel productive without leaving the terminal.

  • gdx stats: Shows fun contribution statistics and metrics for your current repo.
  • gdx graph: Renders a GitHub-style contribution heatmap in your terminal using TrueColor.
  • gdx nocap: Uses AI to roast your latest commit message.

Example: gdx stats

stats example

Command Reference

Expansions & Custom Commands

Command Expansion / Function
s, stat git status (use -r recursively run "status" on all submodules)
lg git log --oneline --graph --all --decorate
sw, swit git switch
br, bra git branch
ps git push with option expansion -fl=--force-with-lease
pu, pl git pull
sub git submodule
sta git stash
cmi, com git commit (Try gdx cmi auto for AI messages!)
res git reset with option expansion -h=--hard, -s=--soft (supports res ~3 expansion)
dif git diff (supports dif ~3, dif origin ~2 expansion)
sho git show (supports sho ~3, sho origin ~2 expansion)
sta, st git stash
rst git restore
lint Run pre-push checks (spelling, secrets, etc.)
gdx-config Manage gdx configuration
reword, rew Rewrite commit messages
parallel, par Manage parallel worktrees for the current branch
stats Show contribution statistics and metrics for the current repo
snap Create a local snapshot of current worktree/repository
graph Render a GitHub-style contribution heatmap in the terminal
nocap Roast your latest commit message with AI
clear Wipe changes in the working directory with a backup patch
history, his Inspect, undo, and redo recorded repository transactions
cache Manage gdx cache
macro Create custom gdx command macros to run multiple commands with a single macro
gh GitHub CLI wrapper, provides better UX and QoL features

Run gdx ghelp to see the full list of expansions/commands.

Command Extensions

Command Expansion / Function
tag mv, tag move Move a tag to a new commit (supports ref expansion)
log export Export git log to a markdown file with enhanced formatting
commit auto Generate commit messages with AI based on staged changes (supports --no-commit and --copy flags)
stash drop Drop stashes with advanced options (e.g., drop 2..6)
stash drop pardon Restore the last dropped stash
submodule switch Jump into a submodule's directory from the parent repo (requires shell integration)
status --recursive, status -r Show status for the main repo and all submodules recursively

Development

This project uses Bun for development because it's fast and the developer experience is great.

  1. Clone the repo

  2. Prepare the development environment:

    bun run prepare-dev
  3. Run in dev mode:

    bun start -- # your gdx commands here
    
    # for example:
    bun start -- s # runs `gdx s` (git status)

Roadmap

Since this is currently a solo "scratch your own itch" project, the roadmap is fluid, but here is what is on the horizon:

  • Configurability: Allow users to define their own shorthands in a .gdxrc.toml file (default: ~/.gdx/.gdxrc.toml).
  • Shell Integration: Auto-completion scripts for Zsh/Bash/Fish/Powershell with git fallback.
  • Quick linting before push: gdx lint to run following checks before pushing:
    • commit message spelling
    • env or sensitive content scanning
    • conflict markers
    • abnormal file sizes with an option to automatically run lint before every push (bypass with gdx push --no-lint)
  • Undoable stash drop
  • Parallel worktree switching gdx parallel switch Jump between forks (auto-cd) (requires shell integration with gdx --init)
  • Seamless Integration with fzf and cloc automatically detect and use fzf and/or cloc if installed for:
    • Interactive fuzzy search for branches, commits, stash, log and files instead of less
    • Code line statistics in gdx stats using cloc
  • gdx clear Untracked files support: gdx clear now automatically backs up untracked files in the patch.
  • Recursive status for submodules with gdx status --recursive or gdx s -r
  • Submodule dir switching: extension of git submodule, gdx submodule switch to jump into a submodule's directory from the parent repo (requires shell integration)
  • Snapshot: gdx snap to create snapshot of current state of your working directory (including uncommitted changes, untracked files) that can be easily switched back to later (similar to a lightweight, temporary branch that doesn't clutter your branch list)
  • Enhanced output for more commands: Extend the "Git Output for Humans"
  • Undo and Redo: gdx history undo and gdx history redo to step backward and forward through git actions (commit, add, branch, switch, etc.) with safety nets.
  • Edit commit messages: gdx reword to quickly reword the last commit message or a specific commit without needing to do an interactive rebase.

License

MIT © Type-Delta

About

Git, but with better DX. The raw power of Git, aligned with human workflows.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors