gits is a Git repository group manager. It helps you efficiently clone, pull,
clean, convert, delete, and track the status of many repositories—organized by
group—using a single YAML configuration file.
- Define repositories in logical groups
- Use
alias,target_path, anddo_not_deletefor fine-grained control - CLI powered by Typer
- Fast installs and dependency management via
uv - Supports dry-run and verbose modes
- Works seamlessly on Arch Linux and Ubuntu
Installs
gitsto~/.gitsand links the CLI to~/.local/bin/gits.
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Traap/gits/master/install.sh)"This will:
Install uv if missing
Clone this repo into ~/.gits
Create a .venv and install dependencies
Symlink the CLI to ~/.local/bin/gits
Copy a default repository_locations.yml if one doesn't already exist
Ensure ~/.local/bin is in your PATH:``
To remove everything installed by gits:
Removes
gitsfrom~/.gitsand removes links the CLI to~/.local/bin/gits.
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Traap/gits/master/uninstall.sh)"This will:
Remove the ~/.gits directory
Remove the CLI symlink from ~/.local/bin/gits
editor:
- root_dir: ~/editor
- repositories:
- alias: LazyVimurl: https://github.com/LazyVim/starter
- alias: lazy.nvimurl: https://github.com/folke/lazy.nvim
- alias: neovimurl: https://github.com/neovim/neovimfzf:
- root_dir: ~/fzf
- repositories:
- alias: fzfurl: https://github.com/junegunn/fzf-git.sh
- alias: everythingurl: https://github.com/junegunn/everything.fzfhyprland:
- root_dir: ~/hyprland
- repositories:
- alias: Dotsurl: https://github.com/JaKooLit/Hyprland-Dots
- alias: Archurl: https://github.com/JaKooLit/Arch-Hyprlandplugins:
- root_dir: ~/plugins
- repositories:
- alias: neo-treeurl: https://github.com/nvim-neo-tree/neo-tree.nvim
- alias: telescopeurl: https://github.com/nvim-telescope/telescope.nvim
- alias: fugitiveurl: https://github.com/tpope/vim-fugitivetraap:
- root_dir: ~/traap
- repositories:
- alias: archlinuxurl: git@github.com:Traap/bootstrap-archlinux
- alias: gitsurl: git@github.com:Traap/gitsdo_not_delete: true
- alias: nvimsurl: git@github.com:Traap/nvimsdo_not_delete: true
- alias: vimtexurl: https://github.com/lervag/vimtexdo_not_delete: falsegits --help Usage: gits [OPTIONS] COMMAND [ARGS]... Manage git repositories defined in YAML configuration.╭─ Options ────────────────────────────────────────────────────────────────────╮│ --repo-group -r TEXT [default: None] ││ --verbose -v ││ --dry-run -n ││ --install-completion Install completion for the current ││ shell. ││ --show-completion Show completion for the current shell, ││ to copy it or customize the ││ installation. ││ --help Show this message and exit. │╰──────────────────────────────────────────────────────────────────────────────╯╭─ Commands ───────────────────────────────────────────────────────────────────╮│ clean Clean listed repositories by resetting and removing untracked ││ files, including subfolders. ││ clone Clone repositories listed in the YAML file. ││ convert Convert UTF-16 files to UTF-8 in all repositories. ││ doctor Run environment and configuration checks for gits. ││ delete Delete repositories listed in YAML that are not protected by ││ do_not_delete. ││ list List repository groups and optionally their repositories. ││ pull Pull changes for all repositories including unlisted ones. ││ status Print git status for all repositories. │╰──────────────────────────────────────────────────────────────────────────────╯gits List🗂️ editor🗂️ fzf🗂️ hyprland🗂️ plugins🗂️ traapgits list -v🗂️ editor 🗃️ LazyVim 🗃️ lazy.nvim 🗃️ neovim🗂️ fzf 🗃️ fzf 🗃️ everything🗂️ hyprland 🗃️ Dots 🗃️ Arch🗂️ plugins 🗃️ neo-tree 🗃️ telescope 🗃️ fugitive🗂️ traap 🗃️ archlinux 🗃️ gits 🗃️ nvims 🗃️ vimtexgits list -v -r traap🗂️ traap 🗃️ archlinux 🗃️ gits 🗃️ nvims 🗃️ vimtexClone runs 4 jobs concurrently so console output is interwoven.
gits clone🗂️ editor🗂️ fzf🗂️ hyprland🗂️ plugins🗂️ traap 📥 Cloned: fzf 📥 Cloned: LazyVim 📥 Cloned: lazy.nvim 📥 Cloned: everything 📥 Cloned: archlinux 📥 Cloned: gits 📥 Cloned: nvims 📥 Cloned: vimtex 📥 Cloned: Arch 📥 Cloned: neovim 📥 Cloned: Dotsgits clone -v -n🗂️ editor 📥 (dry-run) clone https://github.com/LazyVim/starter /home/traap/editor/LazyVim 📥 (dry-run) clone https://github.com/folke/lazy.nvim /home/traap/editor/lazy.nvim🗂️ fzf 📥 (dry-run) clone https://github.com/junegunn/everything.fzf /home/traap/fzf/everything 📥 (dry-run) clone https://github.com/junegunn/fzf-git.sh /home/traap/fzf/fzf🗂️ hyprland 📥 (dry-run) clone https://github.com/neovim/neovim /home/traap/editor/neovim 📥 (dry-run) clone https://github.com/JaKooLit/Arch-Hyprland /home/traap/hyprland/Arch 📥 (dry-run) clone https://github.com/JaKooLit/Hyprland-Dots /home/traap/hyprland/Dots🗂️ plugins 📥 (dry-run) clone https://github.com/nvim-telescope/telescope.nvim /home/traap/plugins/telescope 📥 (dry-run) clone https://github.com/nvim-neo-tree/neo-tree.nvim /home/traap/plugins/neo-tree 📥 (dry-run) clone https://github.com/tpope/vim-fugitive /home/traap/plugins/fugitive🗂️ traap ⚠️ Exists: archlinux ⚠️ Exists: gits ⚠️ Exists: nvims ⚠️ Exists: vimtexgits clone -v -r traap🗂️ traapCloning into '/home/traap/traap/archlinux'...Cloning into '/home/traap/traap/gits'...Cloning into '/home/traap/traap/nvims'...Cloning into '/home/traap/traap/vimtex'...POST git-upload-pack (181 bytes)POST git-upload-pack (gzip 1623 to 846 bytes) 📥 Cloned: archlinux 📥 Cloned: gits 📥 Cloned: vimtex 📥 Cloned: nvimsgits statusNo output when there are not any errors.
gits status -v🗂️ editor 🧹 Clean: LazyVim 🧹 Clean: lazy.nvim 🧹 Clean: neovim🗂️ fzf 🧹 Clean: fzf 🧹 Clean: everything🗂️ hyprland 🧹 Clean: Dots 🧹 Clean: Arch🗂️ plugins 🧹 Clean: neo-tree 🧹 Clean: telescope 🧹 Clean: fugitive🗂️ traap 🧹 Clean: archlinux 🧹 Clean: gits 🧹 Clean: nvims 🧹 Clean: vimtexgits status -v -r traap🗂️ traap 🧹 Clean: archlinux 🧹 Clean: gits 🧹 Clean: nvims 🧠 Modified: vimtex M README.md ?? new-file stash@{0}: On master: gits status demogits clean -n🧹 (dry-run) would clean LazyVim at /home/traap/editor/LazyVim🧹 (dry-run) would clean lazy.nvim at /home/traap/editor/lazy.nvim🧹 (dry-run) would clean neovim at /home/traap/editor/neovim🧹 (dry-run) would clean everything at /home/traap/fzf/everything🧹 (dry-run) would clean fzf at /home/traap/fzf/fzf🧹 (dry-run) would clean Dots at /home/traap/hyprland/Dots🧹 (dry-run) would clean Arch at /home/traap/hyprland/Arch🧹 (dry-run) would clean telescope at /home/traap/plugins/telescope🧹 (dry-run) would clean neo-tree at /home/traap/plugins/neo-tree🧹 (dry-run) would clean fugitive at /home/traap/plugins/fugitive🧹 (dry-run) would clean gits at /home/traap/traap/gits🧹 (dry-run) would clean archlinux at /home/traap/traap/archlinux🧹 (dry-run) would clean vimtex at /home/traap/traap/vimtex🧹 (dry-run) would clean nvims at /home/traap/traap/nvimsgits clean -vHEAD is now at 803bc18 docs: Explain more about how to add and remove autocmds (#105)HEAD is now at 6c3bda4 chore(main): release 11.17.1 (#1927)HEAD is now at 3ec3e97 Support opening GitHub URLs via WSL (#75)🧹 LazyVim: cleaned successfully🧹 fzf: cleaned successfully🧹 lazy.nvim: cleaned successfullyHEAD is now at a13eb03 Add wiki.fzfHEAD is now at 8813180 Merge pull request #289 from JaKooLit/development🧹 everything: cleaned successfullyHEAD is now at ee8eb7a Update README.de.md🧹 Arch: cleaned successfully🧹 Dots: cleaned successfullyHEAD is now at c7f38e3bc8 fix(api): nvim_parse_cmd parses :map incorrectly #34068HEAD is now at 3f1dd2d fix(renderer): fix cut & paste stack overflow on hidden root (#1792)HEAD is now at 4a745ea Remove antiquated `a` mapHEAD is now at b4da76b fix(lsp): stop using deprecated `client.supports_method` function (#3468)🧹 fugitive: cleaned successfully🧹 neo-tree: cleaned successfully🧹 telescope: cleaned successfullyHEAD is now at ef3e4db Add hyprland and bspwm.HEAD is now at 806d8f6 Update repository locations.HEAD is now at c6d4631 Add installation done message.🧹 neovim: cleaned successfully🧹 archlinux: cleaned successfully🧹 nvims: cleaned successfully🧹 gits: cleaned successfullyHEAD is now at 4b4f18b1 merge: fix test-tkz-euclide.vimRemoving new-file🧹 vimtex: cleaned successfullygits clean -v -r traap -n🧹 (dry-run) would clean archlinux at /home/traap/traap/archlinux🧹 (dry-run) would clean gits at /home/traap/traap/gits🧹 (dry-run) would clean vimtex at /home/traap/traap/vimtex🧹 (dry-run) would clean nvims at /home/traap/traap/nvimsDoctor does not support dryrun or verbose.
gits doctor🧪 Running system diagnostics. ✅ Python >= 3.8: 3.13.3 ✅ git found in PATH ✅ /home/traap/.config/gits/repository_locations.yml found🗂️ None ✅ Repos: 14 ✅ Alias: LazyVim 🧠 Target_path: True ⚠️ path: not found ⚠️ Not Found: /home/traap/editor ✅ Alias: lazy.nvim 🧠 Target_path: True ⚠️ path: not found ⚠️ Not Found: /home/traap/editor ✅ Alias: neovim 🧠 Target_path: True ⚠️ path: not found ⚠️ Not Found: /home/traap/editor ✅ Alias: fzf 🧠 Target_path: True ⚠️ path: not found ⚠️ Not Found: /home/traap/fzf ✅ Alias: everything 🧠 Target_path: True ⚠️ path: not found ⚠️ Not Found: /home/traap/fzf ✅ Alias: Dots 🧠 Target_path: True ⚠️ path: not found ⚠️ Not Found: /home/traap/hyprland ✅ Alias: Arch 🧠 Target_path: True ⚠️ path: not found ⚠️ Not Found: /home/traap/hyprland ✅ Alias: neo-tree 🧠 Target_path: True ⚠️ path: not found ⚠️ Not Found: /home/traap/plugins ✅ Alias: telescope 🧠 Target_path: True ⚠️ path: not found ⚠️ Not Found: /home/traap/plugins ✅ Alias: fugitive 🧠 Target_path: True ⚠️ path: not found ⚠️ Not Found: /home/traap/plugins ✅ Alias: archlinux 🧠 Target_path: True 🧠 path: /home/traap/traap/archlinux 🧠 Found: /home/traap/traap ✅ Alias: gits 🧠 Target_path: True 🧠 path: /home/traap/traap/gits 🧠 Found: /home/traap/traap ✅ Alias: nvims 🧠 Target_path: True 🧠 path: /home/traap/traap/nvims 🧠 Found: /home/traap/traap ✅ Alias: vimtex 🧠 Target_path: True 🧠 path: /home/traap/traap/vimtex 🧠 Found: /home/traap/traap🧪 Diagnostics complete.gits doctor -r traap🧪 Running system diagnostics. ✅ Python >= 3.8: 3.13.3 ✅ git found in PATH ✅ /home/traap/.config/gits/repository_locations.yml found🗂️ traap ✅ Repos: 4 ✅ Alias: archlinux 🧠 Target_path: True 🧠 path: /home/traap/traap/archlinux 🧠 Found: /home/traap/traap ✅ Alias: gits 🧠 Target_path: True 🧠 path: /home/traap/traap/gits 🧠 Found: /home/traap/traap ✅ Alias: nvims 🧠 Target_path: True 🧠 path: /home/traap/traap/nvims 🧠 Found: /home/traap/traap ✅ Alias: vimtex 🧠 Target_path: True 🧠 path: /home/traap/traap/vimtex 🧠 Found: /home/traap/traap🧪 Diagnostics complete.🛠️ Development Clone and test locally:
git clone https://github.com/Traap/gits ~/.gits
cd~/.gits
uv venv .venv
source .venv/bin/activate
uv pip install -e .gits --helpDelete will remove all repos within a group and the group itself unless 1) a repo is marked do_not_delete or repo untracked. Untracked repos are not listed in repository_locations.yml.
gits delete🗂️ editor ⚠️ Not Empty: editor -> /home/traap/editor🗂️ fzf 🗑️ Deleted: fzf 🗑️ Deleted: everything 🗑️ Deleted: fzf🗂️ hyprland 🗑️ Deleted: Dots 🗑️ Deleted: Arch 🗑️ Deleted: hyprland🗂️ plugins 🗑️ Deleted: neo-tree 🗑️ Deleted: telescope 🗑️ Deleted: fugitive 🗑️ Deleted: plugins🗂️ traap ⚠️ Not Empty: traap -> /home/traap/traapgits delete -v -n🗂️ editor 🗑️ (dry-run) would remove: LazyVim -> /home/traap/editor/LazyVim 🗑️ (dry-run) would remove: lazy.nvim -> /home/traap/editor/lazy.nvim 🗑️ (dry-run) would remove: neovim -> /home/traap/editor/neovim ⚠️ Not Empty: editor -> /home/traap/editor🗂️ fzf 🗑️ (dry-run) would remove: fzf -> /home/traap/fzf/fzf 🗑️ (dry-run) would remove: everything -> /home/traap/fzf/everything ⚠️ Not Empty: fzf -> /home/traap/fzf🗂️ hyprland 🗑️ (dry-run) would remove: Dots -> /home/traap/hyprland/Dots 🗑️ (dry-run) would remove: Arch -> /home/traap/hyprland/Arch ⚠️ Not Empty: hyprland -> /home/traap/hyprland🗂️ plugins 🗑️ (dry-run) would remove: neo-tree -> /home/traap/plugins/neo-tree 🗑️ (dry-run) would remove: telescope -> /home/traap/plugins/telescope 🗑️ (dry-run) would remove: fugitive -> /home/traap/plugins/fugitive ⚠️ Not Empty: plugins -> /home/traap/plugins🗂️ traap 🗑️ (dry-run) would remove: archlinux -> /home/traap/traap/archlinux 🧠 Skipped gits (do_not_delete = true) 🧠 Skipped nvims (do_not_delete = true) 🗑️ (dry-run) would remove: vimtex -> /home/traap/traap/vimtex ⚠️ Not Empty: traap -> /home/traap/traap 🧠 No repositories deleted.gits delete -v -r traap🗂️ traap 🗑️ Deleted: archlinux -> /home/traap/traap/archlinux 🧠 Skipped gits (do_not_delete = true) 🧠 Skipped nvims (do_not_delete = true) 🗑️ Deleted: vimtex -> /home/traap/traap/vimtex ⚠️ Not Empty: traap -> /home/traap/traapgits delete -v -r editor🗂️ editor 🗑️ Deleted: LazyVim -> /home/traap/editor/LazyVim 🗑️ Deleted: lazy.nvim -> /home/traap/editor/lazy.nvim 🗑️ Deleted: neovim -> /home/traap/editor/neovim 🗑️ Deleted: editor -> /home/traap/editorClone and test locally:
git clone https://github.com/Traap/gits ~/.gits
cd~/.gits
uv venv .venv
source .venv/bin/activate
uv pip install -e .gits --help