machine.git is a first-class operation surface. Clone, status, log, branch, checkout, add, commit, pull, and push run as a structured RPC that returns parsed results (current branch, ahead/behind counts, a typed changed-file list, commit shas) instead of raw command output. The same methods are available in the Python and TypeScript SDKs and over the HTTP API at /v1/machines/{id}/git/*.

Clone

from nullspace import GitHttpsAuth, Machine

with Machine.create(template="base") as machine:
    machine.git.clone(
        "https://github.com/pypa/sampleproject.git",
        path="/workspace/sampleproject",
        depth=1,
    )

Authenticated clone

auth = GitHttpsAuth(username="x-access-token", password="ghp_...")

machine.git.clone(
    "https://github.com/your-org/private-repo.git",
    path="/workspace/repo",
    auth=auth,
)
machine.git.pull(path="/workspace/repo", auth=auth)
Pass credentials from your orchestrator through environment variables or secret storage. Avoid committing tokens into the machine filesystem.

Branch, edit, and diff

machine.git.create_branch("/workspace/repo", "agent/change")
machine.files.write("/workspace/repo/README.md", "updated\n")
machine.git.add(path="/workspace/repo", files=["README.md"])
print(machine.git.diff(path="/workspace/repo"))

Inspect status and history

status and log return structured results, not strings:
status = machine.git.status(path="/workspace/repo")
print(status.branch, status.ahead, status.behind, status.clean)
for change in status.changed:
    print(change.status, change.path)

for commit in machine.git.log(path="/workspace/repo", limit=10):
    print(commit.sha[:8], commit.message)

Commit and push

machine.git.configure_user("Agent", "agent@example.com", path="/workspace/repo")
machine.git.commit("Apply agent change", path="/workspace/repo")
machine.git.push(path="/workspace/repo", auth=auth)

SSH keys and remotes

machine.git.add_ssh_key(private_key)
machine.git.remote_add(
    path="/workspace/repo",
    name="origin-ssh",
    url="git@github.com:your-org/private-repo.git",
)

TypeScript

The TypeScript SDK exposes the same surface, camelCased:
import { Machine } from "@nullspace/sdk";

const machine = await Machine.create({ template: "base" });
await machine.git.clone("https://github.com/pypa/sampleproject.git", "/workspace/repo", {
  depth: 1,
});
const status = await machine.git.status("/workspace/repo");
console.log(status.branch, status.clean, status.changed);
await machine.git.commit("Apply agent change", "/workspace/repo");
await machine.git.push("/workspace/repo", {
  auth: { kind: "https", username: "x-access-token", password: "ghp_..." },
});

Auth and credentials

Credentials passed via auth= are scoped to a single operation: the guest agent materialises them into a temporary path that is removed when the operation completes, so nothing is written to durable machine state. SSH keys can be supplied per-operation too (GitSshAuth in TypeScript). dangerously_authenticate is the explicit, named-unsafe path that writes a persistent credential store — use it only when you intend the credentials to outlive a single command.

Other helpers

machine.git also supports pull, checkout, delete_branch, branches, log, remote_add, set_config, get_config, configure_user, diff, dangerously_authenticate, and add_ssh_key.