Skip to main content

02 · CLI Command Reference

Status: manual chapter. Audience: users and operators. Last updated: 2026-10-05.

This chapter is the complete command surface of igit. Grammar is quoted from the CLI's own usage text. Where a command has subcommands not listed in the short usage, they are documented here as well.

How to read this chapter​

  • Syntax uses igit <literal> [optional] <required>... notation.
  • Key — — means the command is read-only and never loads a signer. key means it signs and broadcasts a transaction.
  • Who — who is authorized on chain, independent of who can technically broadcast. The contract enforces authorization; the CLI only reports the resulting revert.

Two conventions apply everywhere:

  1. Anything not listed here is forwarded to Git. igit add, igit commit, igit status, igit log, igit branch, igit remote, … all run real Git. Commands listed here shadow Git commands of the same name — use git config for Git's own config.
  2. Read-only commands use contract-only validation. igit repos, igit refs, igit collab list, igit suite info, igit suite verify, igit transfer show, igit guardians show, igit badge list, igit splits show, igit username show, igit release verify, igit doctor, and every igit archive subcommand work with no key.

Repository lifecycle​

CommandSyntaxKeyWho
Create on chainigit init <name> [description]keyanyone (becomes owner)
Local git initigit init [-b <branch>] [.]—local only
Mirror a GitHub repoigit import <github-url> [name]keyanyone
Cloneigit clone <owner>/<repo> [dir]—anyone
Pushigit push [remote] [refspec...]keyowner / maintainer
Pulligit pull [remote] [refspec...]—anyone
Print your clone URLigit clone-url <name>—anyone
List repositoriesigit repos [--all] [owner]—anyone
List refsigit refs <owner> <repo>—anyone
Edit metadataigit repo edit <repo> description <text...>keyowner
Edit default branchigit repo edit <repo> branch <name>keyowner
Forkigit fork <owner> <repo> [new-name]keyanyone

igit init <name> [description]​

Creates the repository on chain with default branch main, then prints the remote setup for you:

$ igit init demo-showcase "igit demo repository"
repository created on chain.

add it as a git remote:
igit remote add inj igit://inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5/demo-showcase
igit push inj main

With no arguments, with a leading -, or with . it passes through to local Git instead:

$ igit init -b main . # local git init

igit import <github-url> [name]​

Bare-clones a GitHub repository, creates the on-chain repository using the source's own default branch, then pushes all branches and (best effort) tags.

Accepted source spellings: github.com/user/repo, https://github.com/user/repo, https://github.com/user/repo.git, git@github.com:user/repo, user/repo.

$ igit import github.com/Hny0305Lin/next-injective-git
cloning https://github.com/Hny0305Lin/next-injective-git.git ...
creating on-chain repo "next-injective-git" (default branch "dev") ...
pushing all branches to igit://inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5/next-injective-git ...
pushing tags ...

imported! your mirror is live:
igit clone igit://inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5/next-injective-git

The default branch is read from the source with git symbolic-ref --short HEAD, falling back to main.

igit clone <owner>/<repo> [dir]​

Wraps git clone. A bare owner/repo is expanded to igit://owner/repo.

$ igit clone inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5/demo-showcase
$ igit clone igit://inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5/demo-showcase
$ igit clone inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5/demo-showcase demo-local

Git flags must come after the repository argument, because the first positional selects the repository:

$ igit clone owner/repo -q # correct
$ igit clone -q owner/repo # error, with a hint telling you this

igit push / igit pull​

Thin wrappers over git push / git pull in the current repository.

$ igit push inj main
$ igit push inj --all
$ igit push inj --tags
$ igit push inj +main # force
$ igit pull

Suppress or expand igit's own progress lines:

$ igit push -q # or: export IGIT_QUIET=1
$ igit push -v # or: export IGIT_VERBOSE=1

igit repos [--all] [owner]​

Lists active repositories. Without an owner it uses your signing key's address. --all includes non-active repositories and marks them.

$ igit repos inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5
demo-showcase default:main igit demo repository

$ igit repos --all inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5
demo-showcase default:main igit demo repository
old-experiment default:main retired [delisted]

igit refs <owner> <repo>​

$ igit refs inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5 demo-showcase
<commit-sha> refs/heads/main packfiles:1

An empty repository prints no refs (empty repository).

igit repo edit​

$ igit repo edit demo-showcase description "igit demo repository, second take"
repo demo-showcase updated

$ igit repo edit demo-showcase branch trunk
repo demo-showcase updated

Fields are description (all remaining words joined) and branch (exactly one word). Owner only.

igit clone-url <name>​

$ igit clone-url demo-showcase
igit://inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5/demo-showcase

igit fork <owner> <repo> [new-name]​

$ igit fork alice awesome-lib my-awesome-lib
forked alice/awesome-lib
clone your fork: git clone igit://inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5/my-awesome-lib

Fork lineage is recorded on chain and rendered on the repository page as forked from <owner>/<repo>.

Collaboration and ownership​

CommandSyntaxKeyWho
Add collaboratorigit collab add <repo> <address> [maintainer|reader]keyowner
Remove collaboratorigit collab remove <repo> <address>keyowner
List collaboratorsigit collab list <owner> <repo>—anyone
Start transferigit transfer <repo> <new-owner>keyowner
Acceptigit transfer accept <owner> <repo>keyproposed new owner
Rejectigit transfer reject <owner> <repo>keyproposed new owner
Clear expiredigit transfer expire <owner> <repo>keyanyone
Canceligit transfer cancel <repo>keycurrent owner
Show pendingigit transfer show <owner> <repo>—anyone

Collaborator roles​

$ igit collab add demo-showcase inj1kwq44vsld7zk2l9d8vvgn7dkjh4jgvlffhqp3d maintainer
collaborator inj1kwq44vsld7zk2l9d8vvgn7dkjh4jgvlffhqp3d added to demo-showcase as maintainer

$ igit collab add demo-showcase inj1ylxm0a96uxsfk5j7xza7jyycs6zvz9k4r9vkuc reader

$ igit collab list inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5 demo-showcase
maintainer inj1kwq44vsld7zk2l9d8vvgn7dkjh4jgvlffhqp3d
reader inj1ylxm0a96uxsfk5j7xza7jyycs6zvz9k4r9vkuc

$ igit collab remove demo-showcase inj1ylxm0a96uxsfk5j7xza7jyycs6zvz9k4r9vkuc
collaborator inj1ylxm0a96uxsfk5j7xza7jyycs6zvz9k4r9vkuc removed from demo-showcase

The role defaults to maintainer when omitted. Only maintainer and reader are accepted; anything else is rejected before a transaction is built.

Ownership transfer — the 7-day rule​

Ownership never moves in one step. The owner proposes, and the new owner must accept after the maturation window.

$ igit transfer demo-showcase inj1p6dn32ss5cxnfgcw8n4mu08x9vc2tskhnj7y3j
ownership transfer for demo-showcase started; inj1p6dn32ss5cxnfgcw8n4mu08x9vc2tskhnj7y3j must accept after 7 days

$ igit transfer show inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5 demo-showcase
pending ownership transfer for inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5/demo-showcase: inj1p6dn32ss5cxnfgcw8n4mu08x9vc2tskhnj7y3j (proposed at 1770000000, execute after 1770604800, expires at 1771209600)

The new owner's address must be a valid inj1… bech32 address; the CLI rejects anything else with new owner %q must be an inj1... bech32 address.

$ igit transfer accept inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5 demo-showcase # as the new owner
$ igit transfer reject inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5 demo-showcase # as the new owner
$ igit transfer cancel demo-showcase # as the current owner
$ igit transfer expire inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5 demo-showcase # after expiry

igit transfer pending is an accepted alias for igit transfer show.

Guardian recovery​

Recovery is the only ownership-recovery capability the Core contract accepts. It is a separate, guardian-gated path — it is not an admin override.

CommandSyntaxKeyWho
Configureigit guardians set <repo> <threshold> <address>...keyowner
Proposeigit guardians propose <owner> <repo> <new-owner>keyguardian
Approveigit guardians approve <owner> <repo>keyguardian
Owner vetoigit guardians cancel <repo>keyowner
Acceptigit guardians accept <owner> <repo>keyproposed new owner
Showigit guardians show <owner> <repo>—anyone
$ igit guardians set demo-showcase 2 inj1kwq44vsld7zk2l9d8vvgn7dkjh4jgvlffhqp3d inj1p6dn32ss5cxnfgcw8n4mu08x9vc2tskhnj7y3j
guardians configured for demo-showcase (threshold 2)

$ igit guardians propose inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5 demo-showcase inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5
guardian recovery proposed; wait 7 days and collect approvals

show reports the configuration and any in-flight operations:

$ igit guardians show inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5 demo-showcase
threshold 2
guardians: inj1kwq44vsld7zk2l9d8vvgn7dkjh4jgvlffhqp3d, inj1p6dn32ss5cxnfgcw8n4mu08x9vc2tskhnj7y3j
recovery: inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5 (2/2 approvals; execute after 1770604800)

Constraints enforced by the CLI before broadcast: the threshold parses as a non-zero 8-bit integer, and every guardian address must start with inj1.

Moderation​

CommandSyntaxKeyWho
Set statusigit mod <owner> <repo> <active|delisted|frozen> [reason-hash]keycommittee / admin
Submit reportigit mod report <owner> <repo> <reason-hash>keyanyone
Read reportigit mod report-show <report-id>—anyone
Appealigit mod appeal <report-id> <reason-hash>keyrepo owner
Resolve reportigit mod resolve <report-id> <active|delisted|frozen> <reason-hash>keycommittee
Resolve appealigit mod appeal-resolve <report-id> <active|delisted|frozen> <reason-hash>keycommittee
$ igit mod inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5 demo-showcase delisted 0xabc…
inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5/demo-showcase moderation status set to delisted

Reasons are passed as hashes, not free text, so the chain stores no prose. igit mod report-show prints the full record:

$ igit mod report-show 7
#7 inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5/demo-showcase status=delisted reporter=inj1kwq…
reason=0xabc…
resolution=delisted
resolution-reason=0xdef…
created-at=1770000000 updated-at=1770003600

Moderation hooks are mandatory for Core ref mutation and Economic sponsor mutation. A frozen or delisted repository is still readable — moderation changes visibility and write eligibility, not the immutability of published pack bytes.

Economics​

CommandSyntaxKeyWho
Sponsorigit sponsor <owner> <repo> <inj-amount> [message...]keyanyone
Set splitsigit splits set <repo> [addr:bps]...keyowner
Show splitsigit splits show <owner> <repo>—anyone
$ igit sponsor inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5 demo-showcase 0.5 "great tooling"
sponsored inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5/demo-showcase with 0.5 INJ — thank you!

Amounts are decimal INJ, up to 18 decimal places, and must be positive. The CLI converts them to base units (inj) before building the transaction.

Revenue splits use basis points (10000 bps = 100%):

$ igit splits set demo-showcase inj1kwq44vsld7zk2l9d8vvgn7dkjh4jgvlffhqp3d:2500 inj1p6dn32ss5cxnfgcw8n4mu08x9vc2tskhnj7y3j:1500
revenue splits of demo-showcase updated (2 recipients)

$ igit splits show inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5 demo-showcase
25.0% inj1kwq44vsld7zk2l9d8vvgn7dkjh4jgvlffhqp3d
15.0% inj1p6dn32ss5cxnfgcw8n4mu08x9vc2tskhnj7y3j
60.0% (owner remainder)

The owner receives the remainder after the platform fee. New sponsorship is accepted only in native INJ; migrated historical totals remain queryable.

Usernames, badges, and releases​

Usernames​

$ igit username register haohanyh # claim, locks a deposit
$ igit username claim haohanyh # reclaim a migrated V1 username
$ igit username release # give it back
$ igit username show haohanyh # resolve a name
$ igit username show inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5 # reverse lookup

Badges​

Badges are non-transferable trophies tied to a repository and a recipient.

$ igit badge award demo-showcase inj1kwq44vsld7zk2l9d8vvgn7dkjh4jgvlffhqp3d "first external pull request"
badge awarded to inj1kwq44vsld7zk2l9d8vvgn7dkjh4jgvlffhqp3d for "first external pull request"

$ igit badge list inj1kwq44vsld7zk2l9d8vvgn7dkjh4jgvlffhqp3d
#12 inj1sh4v00…/demo-showcase: "first external pull request"

award requires a configured key_name; the recipient may be given as an address or a username.

Releases​

Release checksums are immutable once registered.

$ igit release register v0.9.0 windows-amd64=<sha256> linux-amd64=<sha256>

$ igit release verify v0.9.0 windows-amd64 ./igit-windows-amd64.exe

Registration requires exactly 64 hex characters per digest, rejects duplicate platforms, and normalizes to lowercase. Verification is read-only and fails with checksum mismatch for <platform>: got <a>, want <b> on any difference.

Suite inspection​

CommandSyntaxKey
Bindingigit suite info [--json]—
Verificationigit suite verify [--json]—
$ igit suite verify
suite verification passed

Both accept --json for machine-readable output. The command uses a five-minute context, because a full verification is a sequence of dependent RPC calls.

igit upgrade was removed with the immutable EVM suite. It now fails with a stable error code and tells you to use igit suite verify instead. There is no upgrade path by design: no proxy, no diamond, no delegatecall.

Keys​

CommandSyntaxKey
Show addressigit key show—
Createigit key new <name>—
Importigit key import <name>—
$ igit key show
$ igit key new dev
$ igit key import dev # no terminal echo

key new and key import both persist the configured key_name.

Gateways​

CommandSyntaxKey
Probe healthigit gateway status—
Show orderigit gateway select—
$ igit gateway status
hk ok https://igit-hk.haohanyh.ovh 42ms
us ok https://igit-us.haohanyh.ovh 180ms

$ igit gateway select
1 hk https://igit-hk.haohanyh.ovh
2 us https://igit-us.haohanyh.ovh

Both use a six-second budget. Gateways are probed on /healthz and ordered by latency. These commands matter for the Suite v3 / IPFS read path; the Suite v4 BYOS path does not use gateways.

Storage (BYOS)​

CommandSyntaxKey
Registerigit storage add <file>—
Validateigit storage doctor <file>—
Showigit storage show <file>—

storage is handled before any chain or IPFS configuration is loaded, so it works even when the rest of the config is incomplete.

$ igit storage add ./storage-config.json
storage profile registered (path only; credentials are referenced, never stored)

$ igit storage doctor ./storage-config.json
PASS: local storage configuration (2 profiles, 1 repository bindings). Credentials not resolved; cloud access, CORS and Git integration tested separately.

Two things are worth stating plainly:

  • storage add stores only an absolute path in your config. It does not copy, cache, or embed credentials.
  • storage doctor does no cloud access. It validates the local file's shape only. Cloud reachability, CORS, and Git integration are separate tests.

Credentials are never values in the file. They are named environment variables, resolved at the moment of use. See Chapter 08 for the full profile format and the credential rules.

Doctor and setup​

CommandSyntaxKey
Diagnoseigit doctor [--clone|--push] [--json]—
Prepareigit setup [options]—
Prepare (alias)igit setup push [options]—
Statusigit setup status [--json]—

igit setup with no arguments means igit setup push. igit setup status is igit doctor --push with the same flags forwarded.

igit setup push options​

usage: igit setup push [--yes] [--no-kubo] [--force] [--create-key NAME] [--wsl DISTRO]
OptionEffect
--yes, -ySkip the confirmation prompt
--no-kuboDo not install Kubo (Suite v4; also skips the prompt)
--forceReinstall pinned dependencies even if present
--create-key NAMECreate the signing key if none exists
--wsl DISTROWindows only: forward setup into a WSL distribution

Step by step, igit setup push:

  1. Applies the selected network profile.
  2. Validates the EVM deployment profile (a missing SuiteDirectory fails here, before anything is installed).
  3. Confirms with you — unless --yes or --no-kubo was given.
  4. Creates the signing key if --create-key was passed and none exists.
  5. Installs pinned dependencies under ~/.igit/deps — unless --no-kubo. Existing working Kubo installations are preserved.
  6. Saves the configuration.
  7. Runs the push-mode doctor and prints the report.
  8. Succeeds only if the required checks pass, then prints next steps.

The confirmation text is explicit about scope:

igit will install pinned push dependencies under ~/.igit/deps.
Existing working Kubo installations will be preserved; EVM suite setup does not install injectived.
Continue? [y/N]

With --wsl DISTRO on Windows, the CLI first looks for an igit inside the distribution whose version output matches exactly. If none matches, it installs the released Linux CLI into ~/.local/bin inside the distribution, verifying checksums.txt, and appends the directory to PATH in ~/.profile.

Configuration​

CommandSyntaxKey
Public statusigit config list—
Operator detailigit config list --internal—
Setigit config set <key> <value>—
Clearigit config unset <key>—
$ igit config list
{
"network": "injective-testnet",
"key_name": "dev",
"local_ipfs": "configured",
"upload_service": "configured"
}

The public view deliberately hides backend detail. --internal prints the config file path and the full stored JSON, with upload.authorization redacted:

$ igit config list --internal
# /home/user/.igit/config.json
{
"network": "injective-testnet",
"evm_suite_directory_address": "0x…",
"upload": { "authorization": "<redacted>", … },
…
}

Config keys​

KeyControls
networkSelects the profile; atomically replaces the profile-owned fields below
evm_suite_directory_addressThe single trust root. One 0x + 40 hex address
evm_rpcEVM JSON-RPC endpoint
evm_chain_idExpected EVM chain ID
evm_explorerBlock explorer base URL
evm_keystore_dirEncrypted keystore location
storage_configPath to the BYOS storage reference file (Suite v4)
key_nameWhich encrypted key signs
ipfs_apiLocal Kubo API, default http://127.0.0.1:5001 (Suite v3)
ipfs_binKubo binary name or path (Suite v3)
ipfs_gatewayPreferred read gateway
upload.endpointReplication/upload service endpoint
upload.authorization_endpointWhere to request a short-lived upload token
upload.authorizationExplicit token (redacted in output)
upload.us_peerUS Kubo swarm peer multiaddr
upload.hk_peerHK Kubo swarm peer multiaddr

igit config unset <key> clears an override and falls back to the built-in default.

Validation is strict and fails early. A missing or malformed SuiteDirectory produces a stable error code rather than a confusing RPC failure later:

$ igit repos
igit: missing config: evm_suite_directory_address (run `igit config set evm_suite_directory_address 0x…`)

Read-only commands validate the contract selection only. Commands that write additionally require key_name:

igit: missing config: key_name (run `igit config set <key> <value>`)

Archive (CosmWasm v1)​

The archive tools are deliberately isolated: they are dispatched before configuration is loaded, never load a signer, and never broadcast a V1 transaction.

igit archive query --lcd URL --contract inj1... --height N '<smart-query-json>'
igit archive inventory --tx-search FILE --block-evidence FILE --chain-id ID --contract inj1... --height N --output FILE
igit archive verify --snapshot FILE --inventory FILE --tx-search FILE --block-evidence FILE
$ igit archive query --lcd https://testnet.sentry.lcd.injective.network \
--contract inj1mg6x7ht3zyyszed9aq67q6kd0y5rtq7wf756jh --height 139852506 \
'{"repo_info":{"owner":"inj1sh4v00qgzjy25a73mqheew8q200punaglrzec5","repo":"demo-showcase"}}'

inventory and verify write evidence files. Evidence is never overwritten: a second run against an existing file fails with archive evidence <path> already exists and is never overwritten, and files are written 0600.

Full walkthrough: Chapter 06.

Exit codes, output, and locale​

  • Success exits 0.
  • Any error is printed to stderr as igit: <message> and exits 1.
  • The remote helper prints git-remote-igit: <message> to stderr and exits 1.
  • igit doctor exits non-zero when required checks fail.

Error codes are stable identifiers independent of the message text, so scripts can match on them rather than parsing prose.

Locale​

User-visible messages are bilingual. The CLI selects Chinese only for zh-CN, zh-HK, zh-MO, and zh-TW, using the first non-empty value among LC_ALL, LC_MESSAGES, LANG, and LANGUAGE. A bare zh — and every other locale — renders English. On Windows, with no locale environment variables set, the system default locale is consulted.

$ LANG=zh_CN.UTF-8 igit repos
$ LANG=en_US.UTF-8 igit repos

Progress output is controlled independently:

VariableEffect
IGIT_QUIET=1Silence igit progress lines
IGIT_VERBOSE=1Print every step

Values 1, true, yes, and on are accepted, case-insensitively. The environment variables are pinned: a later Git option verbosity cannot override them, which is what makes -q/-v behave predictably inside scripts.

Environment variables​

VariableEffect
IGIT_HOMEOverrides the config directory (default ~/.igit)
IGIT_QUIETSilence progress lines
IGIT_VERBOSEVerbose progress
IGIT_EVM_KEY_PASSWORDSupplies the keystore passphrase non-interactively
LC_ALL, LC_MESSAGES, LANG, LANGUAGELocale selection
GIT_DIRGit directory, honored by the helper
IPFS_PATHKubo repository location (setup and v3 push)

Do not put a keystore passphrase in IGIT_EVM_KEY_PASSWORD in a shared or logged environment. It exists for automation, not for convenience.

URL forms​

FormMeaning
igit://<owner>/<repo>Canonical remote URL
igit::<owner>/<repo>Accepted alias
<owner>/<repo>Accepted by igit clone; expanded to igit://
igit://<owner>/<repo>.gitTrailing .git is stripped

<owner> must be either an inj1… bech32 address or a registered username (3–32 characters, lowercase letters, digits, and hyphens; no leading or trailing hyphen; never starting with inj1). Anything else fails with:

invalid remote URL "…" (expected igit://<owner>/<repo>)
invalid owner "…": expected an inj1... address or a registered username

Version dispatch, seen from the CLI​

You do not choose the storage path. The version you configured chooses it.

$ igit suite info --json | grep '"version"'
"version": 4,
  • version: 4 → the BYOS path. igit push uploads packs to your bucket, verifies a read-back, publishes a canonical JSON manifest, then updates the ref with revision CAS. No Kubo, no IPFS network.
  • version: 3 → the frozen IPFS path. igit push uploads the pack to your local Kubo, confirms the pin, registers replication, then updates the ref with packUris. Kubo is required.
  • Any other version → rejected. The client supports 3 and 4 and fails closed.

The same rule governs cloning: git-remote-igit probes the suite once, then routes every list, fetch, and push to the matching implementation.

Next​