Skip to main content

Repositories

Repositories are the core unit of JJHub. They store your code, track changes via jj, and host landing requests, issues, workflows, and more. JJHub repositories are jj-native — they use bookmarks instead of branches, stable Change IDs instead of commit SHAs, and first-class conflict tracking.

Creating Repositories

Via CLI

# Create a public repository
jjhub repo create my-project --description "A new project"

# Create a private repository
jjhub repo create my-project --private

# Create a repository under an organization
jjhub repo create my-org/my-project --description "Org repository"
FlagDescription
-d, --description <text>Repository description
--publicMake the repository public (default)
--privateMake the repository private

Via API

# Create a user-owned repository
curl -X POST https://api.jjhub.tech/api/user/repos \
  -H "Authorization: token jjhub_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-project",
    "description": "A new project",
    "private": false
  }'

# Create an org-owned repository
curl -X POST https://api.jjhub.tech/api/orgs/my-org/repos \
  -H "Authorization: token jjhub_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-project",
    "description": "Org repository",
    "private": true
  }'

Cloning Repositories

# Clone by owner/repo
jjhub repo clone alice/my-project

# Clone into a specific directory
jjhub repo clone alice/my-project ./local-dir
The jjhub repo clone command clones via your preferred git protocol (SSH or HTTPS, configurable with jjhub config set git_protocol). After cloning, you work with standard jj commands.

Listing and Viewing

# List your repositories
jjhub repo list

# Limit results
jjhub repo list --limit 10

# Include archived repositories (excluded by default)
jjhub repo list --archived

# View repository details
jjhub repo view
jjhub repo view -R alice/my-project

# JSON output
jjhub repo view --json

Bookmarks

Bookmarks are jj’s replacement for git branches. They are named pointers to changes, and they are the primary reference type in JJHub.

Key Differences from Branches

AspectGit Branchesjj Bookmarks
IdentityTied to commit hashTied to stable Change ID
RebaseChanges the hashChange ID persists
TrackingImplicit (remote tracking)Explicit (push/pull)
Defaultmain or mastermain (configurable)

Managing Bookmarks

# List bookmarks (local jj-lib operation)
jjhub bookmark list

# List bookmarks from remote API
jjhub bookmark list --remote

# Create a bookmark at the current working copy
jjhub bookmark create feature-auth

# Create a bookmark at a specific change
jjhub bookmark create feature-auth --change-id kxyz1234

# Delete a bookmark
jjhub bookmark delete feature-auth

# Remote operations
jjhub bookmark create feature-auth --remote --change-id kxyz1234 -R owner/repo
jjhub bookmark delete feature-auth --remote -R owner/repo

Bookmark Protection

Protect important bookmarks with rules that gate landing:
# Require 1 approval before landing into main
jjhub bookmark protect main --require-review --approvals 1

# Require CI checks and 2 approvals
jjhub bookmark protect main \
  --require-review \
  --approvals 2 \
  --require-status-checks \
  --dismiss-stale-reviews \
  --no-force-push

# Protect release bookmarks with a glob pattern
jjhub bookmark protect "release/*" --require-review --approvals 2

# View all protection rules
jjhub bookmark protections

# Remove protection
jjhub bookmark unprotect main
See the Landing Requests guide for full details on protection rules.

API Endpoints

MethodEndpointDescription
GET/api/repos/:owner/:repo/bookmarksList bookmarks
POST/api/repos/:owner/:repo/bookmarksCreate a bookmark
DELETE/api/repos/:owner/:repo/bookmarks/:nameDelete a bookmark

Changes & Change IDs

Changes are the fundamental unit of work in jj. Every edit you make creates a change with a stable Change ID that persists across rebases, amends, and rewrites.

Viewing Changes

# List recent changes (local jj-lib operation)
jjhub change list

# Show details for a specific change
jjhub change show kxyz1234

# Show the diff for a change
jjhub change diff kxyz1234

# Diff the working copy
jjhub change diff

How Change IDs Work

Unlike git commit hashes, which change every time you amend or rebase, jj Change IDs are stable:
# Create a change
jj new -m "Add feature"
# Change ID: kxyz1234

# Amend the change (add more edits)
jj describe -m "Add feature (updated)"
# Change ID is still kxyz1234

# Rebase onto latest main
jj rebase -d main
# Change ID is still kxyz1234
This stability is what makes landing requests, stacked changes, and CI statuses work seamlessly. A landing request tracks changes by their stable IDs, so amending or rebasing automatically updates the LR.

Change IDs in the API

Changes are accessible via API endpoints that use the stable Change ID:
MethodEndpointDescription
GET/api/repos/:owner/:repo/changesList changes
GET/api/repos/:owner/:repo/changes/:change_idGet a change
GET/api/repos/:owner/:repo/changes/:change_id/diffGet the diff
GET/api/repos/:owner/:repo/changes/:change_id/filesList files in change
GET/api/repos/:owner/:repo/changes/:change_id/conflictsList conflicts

Repository Settings

Visibility

Repositories can be public or private:
  • Public: Visible to everyone, cloneable without authentication
  • Private: Visible only to the owner, org members with access, and explicit collaborators
Change visibility via the API:
curl -X PATCH https://api.jjhub.tech/api/repos/owner/repo \
  -H "Authorization: token jjhub_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{"private": true}'

Topics

Topics tag your repository for discoverability:
# View topics
curl -H "Authorization: token jjhub_xxxxx" \
  https://api.jjhub.tech/api/repos/owner/repo/topics

# Set topics
curl -X PUT https://api.jjhub.tech/api/repos/owner/repo/topics \
  -H "Authorization: token jjhub_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{"topics": ["jj", "typescript", "ai"]}'

Stars

Star a repository to bookmark it and show appreciation:
# Star a repository
curl -X PUT -H "Authorization: token jjhub_xxxxx" \
  https://api.jjhub.tech/api/user/starred/owner/repo

# Unstar a repository
curl -X DELETE -H "Authorization: token jjhub_xxxxx" \
  https://api.jjhub.tech/api/user/starred/owner/repo

# List stargazers
curl https://api.jjhub.tech/api/repos/owner/repo/stargazers

Repository Archiving

Archiving puts a repository into a read-only state. No pushes, no new issues, no new landing requests, and no new workflow runs are accepted. The repository remains cloneable and browsable for reference.
# Archive a repository
jjhub repo archive owner/repo

# Unarchive a repository
jjhub repo unarchive owner/repo
Who can archive/unarchive: repository owner, organization owners (for org-owned repos), and platform admins. What archiving does:
  • Repository becomes read-only (no pushes, no new issues/LRs/workflows)
  • Existing data is fully preserved and browsable
  • Repository is filtered from default listings (use --archived to include)

API Endpoints

MethodEndpointDescription
POST/api/repos/:owner/:repo/archiveArchive a repository
DELETE/api/repos/:owner/:repo/archiveUnarchive a repository

Repository Transfer

Transfer moves a repository from one owner to another (user-to-org, org-to-user, or org-to-org).
# Transfer a repo to an organization
jjhub repo transfer alice/my-repo acme-org

# Skip confirmation prompt
jjhub repo transfer alice/my-repo acme-org -y
What happens during transfer:
  • The repository URL changes (e.g., alice/my-repo becomes acme-org/my-repo). The old URL redirects for a grace period.
  • All collaborators, issues, landing requests, workflows, webhooks, stars, and watches are preserved.
  • The target user or org owner may need to accept the transfer.
Who can transfer: repository owner, organization owners (for org-owned repos), and platform admins.

API Endpoint

MethodEndpointDescription
POST/api/repos/:owner/:repo/transferTransfer a repository (body: {"new_owner": "acme-org"})

Deploy Keys

Deploy keys are SSH keys scoped to a single repository. They are useful for CI/CD pipelines and deployment automation where you need repository access without a personal account.
# List deploy keys
jjhub repo deploy-key list -R owner/repo

# Add a read-only deploy key
jjhub repo deploy-key add -R owner/repo \
  --title "CI Runner" \
  --key "ssh-ed25519 AAAAC3..." \
  --read-only

# Add a read-write deploy key
jjhub repo deploy-key add -R owner/repo \
  --title "Dependency Bot" \
  --key "$(cat ~/.ssh/bot.pub)"

# Delete a deploy key
jjhub repo deploy-key delete -R owner/repo 3
See the Deploy Keys guide for detailed usage and security best practices.

API Endpoints

MethodEndpointDescription
GET/api/repos/:owner/:repo/keysList deploy keys
POST/api/repos/:owner/:repo/keysAdd a deploy key
GET/api/repos/:owner/:repo/keys/:idGet a deploy key
DELETE/api/repos/:owner/:repo/keys/:idDelete a deploy key

File Content Access

Access file contents via the API:
# Get file contents
curl -H "Authorization: token jjhub_xxxxx" \
  https://api.jjhub.tech/api/repos/owner/repo/contents/src/main.ts

# Get a git tree
curl -H "Authorization: token jjhub_xxxxx" \
  https://api.jjhub.tech/api/repos/owner/repo/git/trees/main

API Endpoints

MethodEndpointDescription
GET/api/repos/:owner/:repo/contents/:pathGet file or directory contents
GET/api/repos/:owner/:repo/git/trees/:shaGet a git tree
GET/api/repos/:owner/:repo/git/commits/:shaGet a git commit
GET/api/repos/:owner/:repo/git/refsList git refs

Operation Log

jj maintains an operation log of every repository operation. This provides a full audit trail and enables undo:
# View operation log via API
curl -H "Authorization: token jjhub_xxxxx" \
  https://api.jjhub.tech/api/repos/owner/repo/operations
MethodEndpointDescription
GET/api/repos/:owner/:repo/operationsList jj operations

Full Repository API

MethodEndpointDescription
GET/api/repos/:owner/:repoGet repository
POST/api/user/reposCreate user repository
POST/api/orgs/:org/reposCreate org repository
PATCH/api/repos/:owner/:repoUpdate repository
DELETE/api/repos/:owner/:repoDelete repository

Next Steps