angular/angular-cli · error

Repository is not clean. Update changes will be mixed with p

Error message

Repository is not clean. Update changes will be mixed with pre-existing changes.

What it means

Before `ng update` modifies packages it checks that the git working tree is clean via checkCleanGit. If it is dirty and the user did not pass --allow-dirty, the update is aborted with a CommandModuleError; if --allow-dirty was passed, this warning is logged instead, cautioning that the CLI's changes will be intermingled with the user's uncommitted work.

Source

Thrown at packages/angular/cli/src/commands/update/cli.ts:142

        type: 'boolean',
        alias: ['C'],
        default: false,
      })
      .middleware((argv) => {
        if (argv.name) {
          argv['migrate-only'] = true;
        }

        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        return argv as any;
      })
      .check(({ packages, 'allow-dirty': allowDirty, 'migrate-only': migrateOnly }) => {
        const { logger } = this.context;

        // This allows the user to easily reset any changes from the update.
        if (packages?.length && !checkCleanGit(this.context.root)) {
          if (allowDirty) {
            logger.warn(
              'Repository is not clean. Update changes will be mixed with pre-existing changes.',
            );
          } else {
            throw new CommandModuleError(
              'Repository is not clean. Please commit or stash any changes before updating.',
            );
          }
        }

        if (migrateOnly) {
          if (packages?.length !== 1) {
            throw new CommandModuleError(
              `A single package must be specified when using the 'migrate-only' option.`,
            );
          }
        }

        return true;

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Commit or stash all changes: `git stash` (or `git add -A && git commit -m "wip"`) before running ng update.
  2. Re-run the update after the tree is clean; use `git stash pop` afterwards to restore WIP.
  3. If mixing is intentional and understood, pass `--allow-dirty` to proceed past the check (accepting the warning).
  4. Create a safety branch first: `git checkout -b pre-update-backup` before updating a dirty tree.

Example fix

// before
git status            # dirty
ng update @angular/core
// after
git add -A && git commit -m "wip"
ng update @angular/core
Defensive patterns

Strategy: validation

Validate before calling

import { execSync } from 'node:child_process';
const status = execSync('git status --porcelain', { cwd: projectRoot }).toString().trim();
if (status) {
  throw new Error('Working tree not clean. Commit or stash before `ng update`.');
}

Try / catch

try {
  await ngUpdate(['@angular/core']);
} catch (e) {
  if (String(e.message).includes('Repository is not clean')) {
    execSync('git stash');
    await ngUpdate(['@angular/core']);
    execSync('git stash pop');
  }
}

Prevention

When it happens

Trigger: Running `ng update <packages>` (with packages specified and not migrate-only) while `git status` reports uncommitted changes, and either (a) throwing when --allow-dirty is absent, or (b) warning when --allow-dirty is present.

Common situations: Forgetting to commit or stash WIP before updating; CI or scripts running updates in dirty checkouts; developers intentionally using --allow-dirty for quick experiments.

Related errors


AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30). Data as JSON: /api/errors/f5c1cc2c5616b3d5. Report an issue: GitHub.