vcs

package module
v0.0.0-...-f64f92c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 26, 2026 License: Apache-2.0 Imports: 0 Imported by: 0

README

vcs

A unified command-line interface for multiple version control systems. Compiled Go binaries that provide a consistent set of subcommands across Git, Mercurial, Jujutsu, and Perforce.

Originally a set of bash shell functions; reimplemented in Go for speed and portability (works in bash, fish, zsh, or any shell).

Supported VCS

VCS Binary Notes
Git vcs-git
Mercurial vcs-hg Uses chg when available for faster startup
Jujutsu vcs-jj Supports both git and piper backends
Perforce vcs-p4 Translation backend for p4/g4

Usage

vcs <subcommand> [args...]

The vcs command auto-detects the VCS for the current directory (caching the result in .vcs_cache) and dispatches to the appropriate vcs-* binary.

vcs status
vcs commit -m "fix bug"
vcs graph
vcs diff foo.go

You can also call the per-VCS binaries directly:

vcs-git status
vcs-hg --hg-path=/usr/bin/chg log
Flags
Flag Description
--vcs=NAME Skip auto-detection; use the given VCS (git, hg, jj, p4).
--hg-path=PATH Path to hg or chg binary (passed through to vcs-hg). Useful for callers that cache the lookup.
-n, --dry-run, --simulate Print the underlying VCS command to stderr instead of running it. Must appear before the subcommand. Can also be toggled via the VCS_DRY_RUN environment variable.
--list-commands Print all supported subcommand names, one per line. Useful for shell integration (see below).
--version, -V Print the version, git commit, and build date on one line and exit.

Example:

$ vcs -n commit -m "fix bug"
+ git commit -m 'fix bug' --all
Special subcommands
Subcommand Description
detect Print the detected VCS name.
rootdir Print the repository root directory.
backend Print the VCS backend (e.g. git for jj-on-git).
hosting Print the hosting platform (e.g. github).
prompt-info Print all prompt info (project, subdir, branch, status, behind) in one invocation. See --format, --color.
prompt-line Print the full preprompt first line (hostname, shpool tag, directory/VCS info, auth warning) in one invocation. See --hostname, --production, --shpool, --color, --no-ssh.
auto-fetch Spawn a detached background fetch (git fetch / hg pull / jj git fetch, or jj piper pull on a non-git backend) when the repo is stale: older than --max-age (default 1h) by the fetch marker's mtime, or — for non-git jj backends with no marker file — by the last sync recorded in jj op log. Silent on no-op paths; intended to be called from shell prompt hooks after a cd. Use --verbose to print the action taken (not-in-repo / fresh / fetched / unsupported).
clearcache Remove .vcs_cache files under the current directory.
version Print the version, git commit, and build date on separate lines.

Commands

All subcommands work across all supported VCS, translating to the native equivalent. Some commands are no-ops where the concept doesn't apply (e.g. addremove in jj, which auto-tracks files).

Everyday commands
Command Description Git Hg Jj P4
status Show working copy status git status --short hg status jj diff --summary (if undescribed) p4 status
commit Record changes git commit hg commit jj commit p4 submit
amend Amend the current commit git commit --amend hg amend jj squash p4 change
diff / diffs Show changes git diff hg diff jj diff p4 diff
diffstat Show change statistics git diff --stat hg diff --stat jj diff --stat p4 diff
add Track files git add --intent-to-add hg add jj file track p4 add
addremove Track new, remove missing git add --all hg addremove (no-op, auto-tracked) p4 reconcile
graph Show commit graph git log --graph hg log --graph jj log p4 changes
changelog One-line log git log --oneline hg log --template jj log --template p4 changes
show Show a commit git show hg export jj show p4 describe
count Count commits reachable from HEAD git rev-list --count HEAD hg log -r ancestors(.)+. jj log -r ancestors(@)|@ p4 changes
Navigation
Command Description Git Hg Jj P4
checkout / goto Switch to revision git checkout hg checkout / hg update jj new p4 sync
next Move to child commit children search hg update -r min(children(.)) jj next (not supported)
prev Move to parent commit git checkout HEAD~ hg update -r .^ jj prev (not supported)
branch Print current branch git rev-parse --abbrev-ref hg branch (no-op) (not supported)
branches List branches git branch hg branches jj bookmark list (not supported)
base Show current commit summary git log -1 --oneline hg log -r . jj log -r @|@- p4 describe
map Show outgoing or graph outgoing if at tip, else graph same same p4 opened + p4 changes
History editing
Command Description Git Hg Jj P4
reword Edit commit message only git commit --amend --allow-empty hg commit --amend -e jj describe p4 change
describe Edit commit message git commit --amend --only hg commit --amend jj describe p4 change
squash Squash commits git merge --squash hg fold jj squash (not supported)
split Split a commit git rebase -i hg split jj split (not supported)
drop Remove a commit git rebase --onto hg prune jj abandon (not supported)
graft / pick Copy a commit git cherry-pick hg graft jj duplicate p4 integrate
rebase Rebase commits git rebase hg rebase jj rebase (not supported)
histedit / diffedit Interactive history edit git rebase -i hg histedit jj diffedit (not supported)
undo Undo last operation git reset --mixed HEAD~ hg undo jj undo (not supported)
unamend Undo last amend git reset --mixed HEAD@{1} hg unamend jj undo (not supported)
uncommit Undo commit, keep changes git reset --soft HEAD~ hg uncommit jj squash --from @- (not supported)
File operations
Command Description Git Hg Jj P4
copy Copy file (VCS-aware) cp + git add hg copy cp p4 integrate / cp + p4 add
move / rename / mv Rename file git mv hg rename mv p4 move
remove / rm Remove file git rm hg remove rm + jj file untrack p4 delete
restore Restore file to committed state git checkout -- hg revert jj restore p4 revert
revert Revert all changes git reset --hard hg revert jj restore p4 revert
ignore Add to ignore file append to .gitignore append to .hgignore append to .gitignore append to .p4ignore
track Track file git add --intent-to-add hg add jj file track p4 add
untrack Stop tracking file git rm --cached hg forget jj file untrack p4 revert -k
Remote operations
Command Description Git Hg Jj P4
pull Fetch and update git pull --rebase --log hg pull --update --rebase jj git fetch / jj sync p4 sync
push Push changes git push hg push jj git push / jj upload p4 submit
fastforward Fast-forward only git pull --ff-only hg sync --tool=internal:fail jj git fetch (not supported)
incoming / unpulled Show what would be pulled git log HEAD..@{upstream} hg incoming jj op log p4 sync -n
outgoing / unpushed Show what would be pushed git log HEAD --not --remotes hg log -r draft() jj log -r mutable() p4 opened
unmerged List branches not merged to main git branch -v --no-merged origin/main hg log -r "bookmark() and draft()" jj log -r "bookmarks() & mutable()" p4 opened
pending Show uncommitted/unpushed outgoing or status hg status jj log -r mutable() p4 changes -s pending
review / upload Push and create PR git push + gh pr create (not supported) jj git push + gh pr create p4 change
submit Push to remote git push hg submit jj git push / jj submit p4 submit
Inspection
Command Description
annotate / blame Show line-by-line authorship
changed List changed files
at_tip Check if working copy is at branch tip
fetchtime Unix timestamp of last fetch
unknown List untracked files
Other
Command Description
absorb Absorb changes into relevant commits
commitforce Commit bypassing hooks
evolve Evolve obsolete commits (hg only)
fix / lint Run code formatters/linters
precommit Run pre-commit hook
presubmit Run pre-push hook
recommit Amend commit
submitforce Push bypassing hooks
uploadchain Upload chain of commits

Cache

VCS detection results are cached in .vcs_cache in the current directory. Format (2 lines):

<vcs> <backend> <hosting>
<rootdir>

Fields use - as a sentinel for empty values. Example:

git git github
/home/user/myrepo

Use vcs clearcache to remove cache files.

Building

Requires Go 1.21 or later.

make          # build all binaries
make test     # run tests
make install  # install to PREFIX/bin
make clean    # remove built binaries

make uses real file targets, so re-running it is free when sources haven't changed. This makes it safe to run from a login script.

Installing

For non-root users, make install defaults to ~/.local/bin:

make install

For root, it defaults to /usr/local/bin. Override with:

make install PREFIX=/opt/vcs

Ensure PREFIX/bin is on your PATH (most distros include ~/.local/bin by default).

Shell integration

Since these are standalone binaries, they work in any shell. Use --list-commands to generate wrappers for all commands automatically:

bash/zsh:

for cmd in $(vcs --list-commands); do
    eval "$cmd() { vcs $cmd \"\$@\"; }"
done

Or pick specific short aliases:

alias st='vcs status'
alias ci='vcs commit'
alias di='vcs diffs'
alias gr='vcs graph'

fish:

for cmd in (vcs --list-commands)
    alias $cmd "vcs $cmd"
end

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Commands = []string{
	"absorb",
	"add",
	"addremove",
	"amend",
	"annotate",
	"at_tip",
	"base",
	"blame",
	"branch",
	"branches",
	"change",
	"changed",
	"changelog",
	"changes",
	"checkout",
	"commit",
	"commitforce",
	"copy",
	"count",
	"describe",
	"diffedit",
	"diffs",
	"diffstat",
	"drop",
	"evolve",
	"fastforward",
	"fetchtime",
	"fix",
	"goto",
	"graft",
	"graph",
	"histedit",
	"ignore",
	"incoming",
	"lint",
	"map",
	"mergetool",
	"move",
	"next",
	"outgoing",
	"pending",
	"pick",
	"precommit",
	"presubmit",
	"prev",
	"pull",
	"push",
	"rebase",
	"recommit",
	"remove",
	"rename",
	"resolve",
	"restore",
	"revert",
	"review",
	"reword",
	"rootdir",
	"show",
	"split",
	"squash",
	"status",
	"submit",
	"submitforce",
	"track",
	"unamend",
	"uncommit",
	"undo",
	"unknown",
	"unmerged",
	"unpulled",
	"unpushed",
	"untrack",
	"upload",
	"uploadchain",
}

Commands is the canonical list of all subcommands that every vcs-* backend must handle in its dispatch function, even if the implementation is a no-op or returns "not supported".

Coreutils-named aliases (mv, rm) are deliberately NOT listed even though every backend dispatches them: `vcs --list-commands` feeds the README's shell-integration snippet, which defines a shell function per listed command, and a generated mv/rm wrapper would shadow the real /bin/mv and /bin/rm in the user's shell. Their parity is pinned by per-backend tests instead.

Functions

This section is empty.

Types

This section is empty.

Directories

Path Synopsis
Package autofetch implements the `vcs auto-fetch` subcommand: a fast, prompt-friendly entry point that decides whether to spawn a detached background fetch for the current repo.
Package autofetch implements the `vcs auto-fetch` subcommand: a fast, prompt-friendly entry point that decides whether to spawn a detached background fetch for the current repo.
cmd
vcs command
vcs detects the version control system for the current directory and dispatches to the appropriate vcs-* binary.
vcs detects the version control system for the current directory and dispatches to the appropriate vcs-* binary.
vcs-git command
vcs-git translates unified VCS subcommands into git commands.
vcs-git translates unified VCS subcommands into git commands.
vcs-hg command
vcs-hg translates unified VCS subcommands into Mercurial commands.
vcs-hg translates unified VCS subcommands into Mercurial commands.
vcs-jj command
vcs-jj translates unified VCS subcommands into Jujutsu commands.
vcs-jj translates unified VCS subcommands into Jujutsu commands.
vcs-p4 command
vcs-p4 translates unified VCS subcommands into Perforce (p4/g4) commands.
vcs-p4 translates unified VCS subcommands into Perforce (p4/g4) commands.
internal
fetchlock
Package fetchlock serialises concurrent git fetches within a repo using an advisory flock on vcs-fetch.lock so that a background auto-fetch and an interactive vcs pull never write FETCH_HEAD concurrently (which produces "Cannot rebase onto multiple branches").
Package fetchlock serialises concurrent git fetches within a repo using an advisory flock on vcs-fetch.lock so that a background auto-fetch and an interactive vcs pull never write FETCH_HEAD concurrently (which produces "Cannot rebase onto multiple branches").
jjsync
Package jjsync reports when a jj workspace last pulled upstream state.
Package jjsync reports when a jj workspace last pulled upstream state.
testenv
Package testenv provides shared test setup helpers.
Package testenv provides shared test setup helpers.
Package promptinfo gathers VCS prompt information in a single invocation, replacing 6-12 shell forks per prompt with 1 process.
Package promptinfo gathers VCS prompt information in a single invocation, replacing 6-12 shell forks per prompt with 1 process.
Package promptline assembles the first line of the shell prompt in a single process: hostname (with optional production-host coloring), shpool session tag, directory/VCS info, and auth warnings.
Package promptline assembles the first line of the shell prompt in a single process: hostname (with optional production-host coloring), shpool session tag, directory/VCS info, and auth warnings.
Package runner provides helpers for executing VCS subcommands.
Package runner provides helpers for executing VCS subcommands.
Package vcsdetect detects the VCS, backend, hosting, and root directory for a given working directory.
Package vcsdetect detects the VCS, backend, hosting, and root directory for a given working directory.
Package version holds build metadata for the vcs binaries, read from the VCS stamps Go embeds via debug.ReadBuildInfo.
Package version holds build metadata for the vcs binaries, read from the VCS stamps Go embeds via debug.ReadBuildInfo.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL