# Update a batch change

<p className="subtitle">
	Learn in detail about how to update your Batch Changes.
</p>

Updating a batch change works by applying a batch spec to an **existing** batch change in the same namespace.

Since batch changes are uniquely identified by their [`name`](/batch-changes/batch-spec-yaml-reference#name) and the namespace in which they were created, you can edit any other part of a batch spec and apply it again.

When a new batch spec is applied to an existing batch change, the existing batch change is updated, and its changesets are updated to match the new desired state.

## Requirements

To update a changeset, you need:

-   [Admin permissions for the batch change](/batch-changes/permissions-in-batch-changes#permission-levels-for-batch-changes)
-   Write access to the changeset's repository (on the code host)
-   A [personal access token](/batch-changes/configuring-credentials#personal-access-tokens) or a [global service account token](/batch-changes/configuring-credentials#global-service-account-tokens) configured for the code host

For more information, see [Code host interactions in Batch Changes](/batch-changes/permissions-in-batch-changes#code-host-interactions-in-batch-changes).

## Preview and apply a new batch spec

To update a batch change after previewing the changes, do the following:

-   Edit the [batch spec](/batch-changes/batch-spec-yaml-reference) with which you created the batch change to include the changes you want to make to the batch change. For example, change [the commit message in the `changesetTemplate`](/batch-changes/batch-spec-yaml-reference#changesettemplatecommitmessage), or add a new changeset id [to the importedChangesets](/batch-changes/batch-spec-yaml-reference#importchangesets), or [modify the repositoriesMatchingQuery](/batch-changes/batch-spec-yaml-reference#onrepositoriesmatchingquery) to return different search results
-   Use the [Sourcegraph CLI (`src`)](https://github.com/sourcegraph/src-cli) to execute and preview the batch spec

```bash
src batch preview -f YOUR_BATCH_SPEC.yaml

```

-   Open the URL to preview the changes that will be made by applying the new batch spec
-   Click **Apply** to update the batch change.

All changesets on your code host will be updated to the desired state shown in the preview.

## Apply a new batch spec directly

To update a batch change directly, without preview, do the following:

-   Edit the [batch spec](/batch-changes/batch-spec-yaml-reference) with which you created the batch change to include the changes you want to make to the batch change
-   Use the [Sourcegraph CLI (`src`)](https://github.com/sourcegraph/src-cli) to execute, upload, and the batch specs

```bash
src batch apply -f YOUR_BATCH_SPEC.yaml
```

The new batch spec will be applied directly, and the batch change and its changesets will be updated.

## How batch change updates are processed

Changes in the batch spec that affect the batch change, such as the [`description`](/batch-changes/batch-spec-yaml-reference#description), are applied directly when you apply the new batch spec.

Changes affecting the changesets are processed asynchronously to update the desired state. Different fields are processed differently.

Here are some examples:

-   When the diff or attributes that affect the resulting commit of a changeset directly (such as the [`changesetTemplate.commit.message`](/batch-changes/batch-spec-yaml-reference##changesettemplatecommitmessage) or the [`changesetTemplate.commit.author`](/batch-changes/batch-spec-yaml-reference#changesettemplatecommitauthor)) and the changeset has been published, the commit on the code host will be overwritten by a new commit that includes the updated diff
-   When the [`changesetTemplate.title`](/batch-changes/batch-spec-yaml-reference#changesettemplatetitle) or the [`changesetTemplate.body`](/batch-changes/batch-spec-yaml-reference#changesettemplatecommitauthor) are changed and the changeset has been published, the changeset on the code host will be updated accordingly
-   When the [`changesetTemplate.branch`](/batch-changes/batch-spec-yaml-reference#changesettemplatetitle) is changed after the changeset has been published on the code host, the existing changeset will be closed on the code host and the new one, with the new branch, will be created
-   When the batch spec is changed in such a way that no diff is produced in a repository in which the batch change has already created and published a changeset, the existing changeset will be closed on the code host and archived in the batch change
-   When the changeset has been published and the batch spec is changed in such a way that a commit on the code host will be overwritten, any commits that have been manually added to the changeset on the code host will be deleted

<Callout type="note">
	See the [Batch Changes design](/batch-changes/design) docs for more
	information on the declarative nature of the Batch Changes system.
</Callout>

## Updating a batch change to change its scope

### Adding changesets

You can gradually increase the number of repositories to which a batch change applies by modifying the entries in the [`on`](/batch-changes/batch-spec-yaml-reference#on) property of the batch spec.

That means you can start with an `on` property like this in your batch spec:

```yaml
# [...]

# Find all repositories that contain a README file, in the GitHub my-company org.
on:
    - repositoriesMatchingQuery: file:README repo:github.com/my-company
# [...]
```

After you applied that batch spec, you can extend the scope of batch change by changing the `on` property to result in more repositories:

```yaml
# [...]

# Find all repositories that contain a README file, in the GitHub my-company and my-company-ci org.
on:
    - repositoriesMatchingQuery: file:README repo:github.com/my-company|github.com/my-company-ci
# [...]
```

The updated [`repo:` filter](/code-search/queries#filters-all-searches) in the search query will result in more repositories being returned by the search.

If you apply the updated batch spec, new changesets will be created for each additional repository.

### Removing changesets

You can also decrease the number of repositories to which a batch change applies by modifying the entries in the [`on`](/batch-changes/batch-spec-yaml-reference#on) property.

For example, let's say you started with this batch spec:

```yaml
# [...]

# Find all repositories that contain a README file, in the GitHub my-company org.
on:
    - repositoriesMatchingQuery: file:README repo:github.com/my-company
# [...]
```

Next, you applied it and [published changesets](/batch-changes/publishing-changesets) to multiple repositories. You can then modify your repo query only to target a subset of the repositories, for example, by adding the `repo` parameter:

```yaml
# [...]

# Find all repositories that contain a README file, in the GitHub my-company org.
on:
    - repositoriesMatchingQuery: file:README repo:github.com/my-company/my-one-repository
# [...]
```

When you apply this new batch spec, all the changesets published in repositories other than `my-one-repository` will be closed on the code host and archived from the batch change. Archived changesets are still associated with the batch change, but they will appear under the **Archived** tab on the batch change page instead:

![archived-tab](https://sourcegraphstatic.com/docs/images/batch_changes/archived-tab.png)

To fully remove the changesets from the batch change, you can detach them from this tab in the UI.

<Callout type="info">
	Unpublished and [imported
	changesets](/batch-changes/tracking-existing-changesets) will skip archiving
	and immediately be detached from the batch change instead.
</Callout>

#### Unarchiving changesets

Archiving is not permanent, and published changesets can be unarchived by reversing the process that archived them. To unarchive a changeset, modify your `on` property once more to match the repository whose changeset you want to bring back. The easiest way to target an individual repository is by adding an [`on.repository`](/batch-changes/batch-spec-yaml-reference#onrepository) statement for it:

```yaml
# [...]

# Find all repositories that contain a README file, in the GitHub my-company org.
on:
    - repositoriesMatchingQuery: file:README repo:github.com/my-company
    # Also include one repository from outside my-company.
    - repository: github.com/another-org/my-one-repository
# [...]
```
