{"record":{"id":"c96965d7716c8ed1","repo":"denoland/deno","slug":"git-repository-has-uncommitted-changes-use-allo","errorCode":null,"errorMessage":"Git repository has uncommitted changes. Use --allow-dirty to pack anyway.\n{}","messagePattern":"Git repository has uncommitted changes\\. Use --allow-dirty to pack anyway\\.\n(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/tools/pack/mod.rs","lineNumber":54,"sourceCode":"use extensions::media_type_extension;\nuse npm_tarball::create_npm_tarball;\nuse npm_tarball::default_tarball_filename;\nuse package_json::generate_package_json;\nuse unfurl::unfurl_specifiers;\n\npub async fn pack(\n  flags: Arc<Flags>,\n  pack_flags: PackFlags,\n) -> Result<(), AnyError> {\n  let cli_factory = CliFactory::from_flags(flags);\n  let cli_options = cli_factory.cli_options()?;\n\n  // Check if git repository is clean (unless --allow-dirty)\n  if !pack_flags.allow_dirty\n    && let Some(dirty) =\n      crate::util::git::check_if_git_repo_dirty(cli_options.initial_cwd()).await\n  {\n    bail!(\n      \"Git repository has uncommitted changes. Use --allow-dirty to pack anyway.\\n{}\",\n      dirty\n    );\n  }\n\n  // Get package configs\n  let mut packages = cli_options.start_dir.jsr_packages_for_publish();\n  if packages.is_empty() {\n    match cli_options.start_dir.member_deno_json() {\n      Some(deno_json) => {\n        let Some(name) = deno_json.json.name.clone() else {\n          bail!(\n            \"Missing 'name' field in '{}'. Add a package name like:\\n  {{\\n    \\\"name\\\": \\\"@scope/package-name\\\",\\n    ...\\n  }}\",\n            deno_json.specifier\n          );\n        };\n        if deno_json.json.version.is_none() {\n          bail!(","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/cli/tools/pack/mod.rs#L36-L72","documentation":"`deno pack` refuses to build a package tarball when the git working tree has uncommitted changes, unless `--allow-dirty` is passed. This guarantees the packed artifact corresponds to a reproducible, committed state rather than ephemeral local edits (mirrors `cargo package` / `npm version` hygiene). The dirty file list is appended to the message.","triggerScenarios":"Running `deno pack` in a git repository where `check_if_git_repo_dirty` reports modifications: edited/staged/untracked files, without `--allow-dirty`.","commonSituations":"Bumping the version in deno.json and running `deno pack` before committing; generating README/LICENSE files just before packing; switching branches with leftover changes.","solutions":["Commit or stash the changes, then re-run `deno pack` (most common correct fix).","If the changes are intentional for this pack, re-run with `deno pack --allow-dirty`.","Check `git status` first to catch unintended dirty files (e.g. build artifacts) and add them to .gitignore."],"exampleFix":"# before\ndeno pack\n# after\ngit commit -am \"chore: bump version\" && deno pack\n# or, deliberately:\ndeno pack --allow-dirty","handlingStrategy":"validation","validationCode":"#!/usr/bin/env bash\n# gate packing on a clean tree\n[ -z \"$(git status --porcelain)\" ] || { echo \"dirty tree; commit first\"; exit 1; }\ndeno pack","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Commit or stash before packing in release scripts.","Use --allow-dirty only for throwaway/preview tarballs.","gitignore build artifacts so the tree stays clean."],"tags":["git","pack","publishing"],"backgroundTag":"uncommitted-changes-blocked","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}