Skip to content

Atomic Transactions

Transactions collect multiple file changes and commit them as a single atomic operation. No partial commits — either all changes land or none do.

import { Client } from "@githosted/sdk";
const client = new Client();
const repo = client.repo("my-project");
await repo.transaction("Refactor auth module", async (tx) => {
await tx.write("src/auth.ts", newAuthCode);
await tx.write("src/auth.test.ts", newTestCode);
await tx.delete("src/old_auth.ts");
});

Execute a transaction. The callback receives a Transaction object to stage changes.

const result = await repo.transaction(
"Add feature",
async (tx) => {
await tx.write("src/feature.ts", code);
await tx.write("src/feature.test.ts", tests);
},
);
console.log(result.commitSha); // SHA of the created commit
await repo.transaction(
"Fix bug on feature branch",
async (tx) => {
await tx.write("src/main.ts", fixedCode);
},
{
ref: "feature/fix", // target branch
expectedHead: file.headSha, // optimistic concurrency
},
);

Stage a file write. Content can be string or Uint8Array.

Stage a file deletion.

const file = await repo.read("package.json");
const pkg = JSON.parse(file.content);
pkg.version = "2.0.0";
await repo.transaction(
"Bump version to 2.0.0",
async (tx) => {
await tx.write("package.json", JSON.stringify(pkg, null, 2));
await tx.write("CHANGELOG.md", changelogEntry);
},
{ expectedHead: file.headSha },
);

Agents can use transactions to create atomic “save points” of their work:

const changes = await generateCode(prompt, existingFiles);
await repo.transaction(
`Agent: ${prompt.slice(0, 60)}`,
async (tx) => {
for (const [path, content] of Object.entries(changes)) {
await tx.write(path, content);
}
},
);

If expectedHead is set and the branch has moved, the transaction throws a StaleHeadError. See Error Handling.