Remotes And Branches
Graft repository mode follows Git’s shape closely enough that common branch and remote workflows should feel familiar.
Branches
Section titled “Branches”Create and switch branches:
graft branch feature/searchgraft switch feature/searchCreate and switch in one step:
graft switch -c feature/search mainList branches:
graft branchgraft branch -rgraft branch -aBranches live under .graft/refs/heads/.
Named Remotes
Section titled “Named Remotes”Add multiple remotes:
graft remote add origin fs:///srv/graft/appgraft remote add backup fs:///srv/graft/app-backupgraft remote listAdd an S3-compatible remote:
export AWS_ACCESS_KEY_ID="..."export AWS_SECRET_ACCESS_KEY="..."export AWS_REGION="auto" # Cloudflare R2
graft remote add origin 's3_compatible://my-bucket/prod/app?endpoint=https://account.r2.cloudflarestorage.com'Remote URLs store the bucket, optional prefix, and optional endpoint. S3 credentials stay outside the repository config and are loaded from the process environment or standard AWS config files.
Update or inspect URLs:
graft remote get-url origingraft remote set-url origin fs:///srv/graft/new-appgraft remote rename backup archivegraft remote remove archiveFetch one branch:
graft fetch origin mainFetch all branches:
graft fetch --all originFetch updates remote-tracking refs such as:
refs/remotes/origin/mainrefs/remotes/origin/feature/searchIt does not automatically change your current branch.
Pull uses the current branch upstream when no remote and branch are supplied:
graft pullOr specify them explicitly:
graft pull origin mainA fast-forward pull updates the current branch and materializes the target database snapshots into the worktree. A non-fast-forward pull enters merge state and records conflict stages in the index.
Push the current branch to its upstream:
graft pushPush explicitly:
graft push origin mainPush all local branches:
graft push --all originForce push is available for deliberate non-fast-forward updates:
graft push --force origin mainUse it with the same care you would use git push --force.
Remote Smoke Test
Section titled “Remote Smoke Test”This sequence exercises the full push and download path against a remote. Use a dedicated bucket prefix so the test objects are easy to inspect or delete later.
export AWS_ACCESS_KEY_ID="..."export AWS_SECRET_ACCESS_KEY="..."export AWS_REGION="auto"REMOTE_URI='s3_compatible://my-bucket/graft-smoke-test?endpoint=https://account.r2.cloudflarestorage.com'
mkdir -p /tmp/graft-smoke/source /tmp/graft-smoke/clonecd /tmp/graft-smoke/source
graft init app.dbgraft sql --db app.db "CREATE TABLE people (id INTEGER PRIMARY KEY, name TEXT NOT NULL); INSERT INTO people(name) VALUES ('Alice');"graft add --db app.db app.dbgraft commit --db app.db -m "initial smoke test"graft remote add --db app.db origin "$REMOTE_URI"graft push --db app.db origin maingraft ls-remote --db app.db origin
cd /tmp/graft-smoke/clonegraft clone --db app.db "$REMOTE_URI"graft sql --db app.db "SELECT id, name FROM people ORDER BY id;"
cd /tmp/graft-smoke/sourcegraft sql --db app.db "INSERT INTO people(name) VALUES ('Bob');"graft add --db app.db app.dbgraft commit --db app.db -m "second smoke test"graft push --db app.db origin main
cd /tmp/graft-smoke/clonegraft pull --db app.db origin maingraft sql --db app.db "SELECT id, name FROM people ORDER BY id;"After the final query, the clone should show both Alice and Bob. The remote prefix should contain HEAD, refs/heads/main, repository objects/, and SQLite storage data under logs/ and segments/.