Skip to content

Repositories

Publishing

Run ngit init inside an existing git repository:

bash
ngit init --name "My Project" --description "What it does" --defaults

This publishes a repository announcement and adds a nostr:// remote. With no --grasp-server, it uses your preferred GRASP server if you have one configured and falls back to the built-in defaults otherwise.

Choosing where it lives

A GRASP server is a relay and a git server in one, and creates the repository for you:

bash
ngit init --name "My Project" --grasp-server grasp.example.com --defaults

Anything beyond GRASP is explicit, and empty by default:

bash
ngit init \
  --name "My Project" \
  --additional-relay wss://relay.example.com \
  --additional-clone https://git.example.com/my-project.git \
  --defaults

The effective sets are additive:

relays = grasp-derived relays + additional relays
clones = grasp-derived clones + additional clones

Other flags

FlagPurpose
--name (alias --title)Human-readable name
--identifierShortname, no spaces — not editable later
--descriptionOne-line description
--webHomepage URL
--hashtagDiscovery hashtags, repeatable
-u, --upstreamMark this as a fork of another repo (informational)
--earliest-unique-commitUsually the root commit; a later one for forks
--private / --publicRestrict discovery to repository relays, or lift that
--cleanDrop unknown tags when republishing instead of preserving them

--identifier is permanent

It becomes the NIP-34 d tag. Changing it doesn't rename the repository — it creates a different one at a different coordinate.

Cloning

bash
git clone nostr://<npub>/<relay-hint>/<identifier>   # preferred
git clone nostr://<npub>/<identifier>                # slower discovery
git clone nostr://user@domain.com/<identifier>       # NIP-05, if given to you

The relay hint is a bare domain (relay.ngit.dev). Including it skips the discovery step.

Inspecting

bash
ngit repo                    # what this repository is
ngit repo --offline          # from cache, no network

Shows the name, description, nostr:// URL, maintainers, relays, git servers, GRASP servers and hashtags. Run git fetch origin first if the cache may be stale.

Editing metadata

ngit repo edit preserves anything you don't mention:

bash
ngit repo edit --description "New description"

Collections use targeted add/remove actions rather than replacing the whole list:

SettingAddRemove
GRASP server--add-grasp-server URL--remove-grasp-server URL
Additional relay--add-additional-relay URL--remove-additional-relay URL
Additional clone--add-additional-clone URL--remove-additional-clone URL
Hashtag--add-hashtag TAG--remove-hashtag TAG

They repeat and combine:

bash
ngit repo edit \
  --remove-additional-relay wss://old.example.com \
  --add-additional-relay wss://new.example.com \
  --add-hashtag rust

To empty a collection, remove each value currently reported by ngit repo.

A few rules the CLI enforces:

  • A GRASP-derived entry can't be removed as an additional entry. Remove the GRASP server instead — its paired relay and clone URL go together.
  • An edit that would leave the repository with no relay, or no git server, fails before publishing anything.

Swapping git servers

This is the payoff of keeping refs on nostr. Add the new server, remove the old one, and contributors do nothing:

bash
ngit repo edit \
  --add-additional-clone https://new-host.example.com/my-project.git \
  --remove-additional-clone https://old-host.example.com/my-project.git

Every successful edit republishes the announcement. When the repository already has nostr state, ngit republishes that too, so newly added relays and servers get the authoritative refs immediately. If that second step fails, ngit prints an ngit sync recovery command — run it.

Keeping servers in sync

bash
ngit sync                     # push nostr state out to the git servers
ngit sync --ref-name main     # just one ref

Use it after adding a server, or when a server has fallen behind. See Troubleshooting for diverged refs.

Next

Contribute with ngit: nostr://danconwaydev.com/relay.ngit.dev/ngit