# Version control

Commit everything deployoor writes. The `deployments/` record is the product, and the generated `deployers/` are what make a fresh clone typecheck and deploy without anyone knowing to run a command first.

```text
deployments/
  8453-base/Token.json        ← commit: the record — the source of truth
  10-optimism/Token.json      ← commit
  sources/0x8f3a….json        ← commit: pinned verification input, shared by both records
deployers/
  Token.ts                    ← commit: the typed deployer
  types/Token.ts              ← commit: its name + ABI
  index.ts                    ← commit
```

## Commit `deployments/`

Each `<Name>.json` is the source of truth — address, ABI, creation bytecode, compiler, and the [history](/concepts/deployment-records#history) of every (re)deploy. It is small, vanilla JSON, read by your app, [`@wagmi/cli`](/guides/consumption), humans, and any other tool. Its `sourcesHash` points into `deployments/sources/`, which pins the exact solc standard-json input used for that deploy — see [verifying later](#verifying-later).

## Commit `deployers/` too

A generated deployer holds a name, a fully-qualified name, and an ABI. Everything else — creation bytecode, compiler version, the standard-json input — is read from your compiled artifacts at the moment you deploy, so none of it is copied into the file:

```ts
// deployers/types/Token.ts
const abi = [...] as const;

export const tokenArtifact = {
  name: "Token",
  fullyQualifiedName: "contracts/Token.sol:Token",
  abi,
} satisfies GeneratedArtifact<typeof abi>;
```

```ts
// deployers/Token.ts
export const getOrDeployToken = defineDeployer(tokenArtifact, config);
```

That is an ABI and four lines, so the file changes only when your contract's interface changes — which is a diff worth reading. Committing it means a clone can typecheck, run its tests, and deploy against the same interface the repo was written for.

:::info
Until 0.7 these files inlined the whole `standardJsonInput` — every source file in the compilation unit, per contract — which made them large, churn on every solc bump, and worth ignoring. That is why the old advice was the opposite. See [upgrading](/guides/upgrading).
:::

The ABI is the one thing that stays inline, and it has to: a `.json` import widens `"uint256"` to `string`, which costs you `args` typing and `contract.read.*` entirely. Because it is a copy, it is also checked — a deploy compares it against the compiled artifact and refuses to run on drift rather than encoding your constructor arguments against an interface that no longer exists.

## What to ignore

Your framework's build output, which it already ignores: `artifacts/` and `cache/` for Hardhat, `out/` and `cache/` for Foundry. deployoor reads those; it does not write them.

If a rule in your `.gitignore` covers deployoor's output, both `deployoor generate` and `deployoor init` say so and offer to remove it — see [upgrading](/guides/upgrading#3-commit-deployers).

## Tell your formatter to skip them

An ABI is emitted as one long line — 532 characters for a four-function contract, and it grows with the interface — so past a certain size every formatter wants to rewrite it, and regenerating then undoes the rewrite. A repo that both commits `deployers/` and checks formatting in CI then fails on files nothing hand-edits. Exclude the directory instead:

```text
# .prettierignore
deployers
```

```jsonc
// .oxlintrc.json
{ "ignorePatterns": ["deployers"] }
```

ESLint's flat config spells it differently, and has to be JS or TS rather than JSON:

```js
// eslint.config.js
export default [{ ignores: ["deployers/**"] }];
```

## Verifying later

A record's pinned sources hold everything a standard-json block-explorer verify needs — the exact sources, settings, compiler version, and fully-qualified name used for that deploy. Committing them keeps the material for a later verification in the repo, so you never have to reconstruct the old source or find the commit it came from.

They are **content-addressed**: the filename is a hash of the input, and the record references it by `sourcesHash`. A standard-json input is the whole compilation unit — every source file — so this is what keeps one contract deployed to six chains from meaning six copies of your entire source tree. Deploys that recompile nothing rewrite nothing, so the files stay out of your diffs.

`reset` collects any pinned sources no remaining record references; blobs another chain still points at survive.

[`deployoor verify`](/reference/cli#verify) is what reads them. It verifies a recorded deployment from its record and its pinned sources, with no recompile and no redeploy, however long after the fact — including contracts deployed before you had an API key, and contracts whose sources have since changed, because the blob that was pinned at deploy time is still the one the record points at.
