{"record":{"id":"f914338c929507e0","repo":"abhigyanpatwari/GitNexus","slug":"refusing-to-update-safetarget-local-changes-de","errorCode":null,"errorMessage":"Refusing to update ${safeTarget}: local changes detected. Set overwrite_local_changes: true to overwrite them.","messagePattern":"Refusing to update (.+?): local changes detected\\. Set overwrite_local_changes: true to overwrite them\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gitnexus/src/server/git-clone.ts","lineNumber":393,"sourceCode":"    if (options?.allowedCloneRoot) {\n      await assertNoSymlinkPath(cloneRoot, path.join(safeTarget, '.git'), true);\n    }\n    await assertPostRealpathContainment(cloneRoot, safeTarget);\n    // Confirm the existing clone is actually the same repository the caller\n    // requested. Without this check, a pull would silently succeed against\n    // whatever remote the dir was originally cloned from.\n    await assertRemoteMatchesRequestedUrl(safeTarget, url, options?.timeoutMs);\n    onProgress?.({ phase: 'pulling', message: 'Pulling latest changes...' });\n    const runGitImpl = options?.runGitForTest ?? runGit;\n    if (options?.branch) {\n      if (!options.overwriteLocalChanges) {\n        const status = await runGitImpl(['status', '--porcelain'], safeTarget, {\n          token: options?.token,\n          url,\n          timeoutMs: options?.timeoutMs,\n        });\n        if (status.trim()) {\n          throw new Error(\n            `Refusing to update ${safeTarget}: local changes detected. Set overwrite_local_changes: true to overwrite them.`,\n          );\n        }\n      }\n      await runGitImpl(\n        [\n          'fetch',\n          '--depth',\n          '1',\n          'origin',\n          `refs/heads/${options.branch}:refs/remotes/origin/${options.branch}`,\n        ],\n        safeTarget,\n        {\n          token: options?.token,\n          url,\n          timeoutMs: options?.timeoutMs,\n        },","sourceCodeStart":375,"sourceCodeEnd":411,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/0d1aed942f0e8b5d3bac27519fff441aceea722d/gitnexus/src/server/git-clone.ts#L375-L411","documentation":"During a pull/update, cloneOrPull runs 'git status --porcelain' in the existing target; if the output is non-empty the working tree has local modifications, and the update is refused rather than silently clobbered. The error tells you to opt in explicitly with overwrite_local_changes: true. It protects uncommitted user work in the clone.","triggerScenarios":"Calling cloneOrPull for a repo whose targetDir already exists as a git repo with uncommitted modifications or untracked files, without overwrite_local_changes: true.","commonSituations":"A developer edited files inside the auto-synced clone; build artifacts or generated files left untracked in the target; a crashed previous run left partial edits; hotfixes applied directly in the synced checkout.","solutions":["Commit or discard the local changes in the target repo, then retry the sync.","Pass overwrite_local_changes: true in the cloneOrPull options if the changes are disposable.","Move/stash the changes (git stash) or copy them aside before re-running the sync.","Clean untracked files (git clean -fd) if they are the trigger and are not needed."],"exampleFix":"// before\nawait cloneOrPull({ url, targetDir });\n// after (changes are intentionally disposable)\nawait cloneOrPull({ url, targetDir, overwrite_local_changes: true });","handlingStrategy":"try-catch","validationCode":"const { stdout } = await exec('git status --porcelain', { cwd: targetDir });\nif (stdout.trim()) {\n  console.warn('target has local changes; commit, stash, or set overwrite_local_changes: true');\n}\nawait cloneOrPull({ url, targetDir, overwrite_local_changes: stdout.trim() ? true : false });","typeGuard":null,"tryCatchPattern":"try {\n  await cloneOrPull(opts);\n} catch (err) {\n  if ((err as Error).message.includes('local changes detected')) {\n    // surface to operator instead of silently overwriting\n    throw new Error(`Sync blocked: ${opts.targetDir} has uncommitted work. Resolve or set overwrite_local_changes.`, { cause: err });\n  }\n  throw err;\n}","preventionTips":["Never edit auto-synced clones directly; work in separate worktrees.","Add the clone dir to .gitignore hygiene so generated files do not accumulate as untracked changes.","Run git status before scheduled syncs and alert instead of force-overwriting.","Only set overwrite_local_changes: true after confirming the changes are disposable."],"tags":["git","sync","conflict"],"backgroundTag":"git-command-failed","analyzedSha":"0d1aed942f0e8b5d3bac27519fff441aceea722d","analyzedAt":"2026-09-08T00:40:44.970Z","contentChangedAt":"2026-09-08T00:40:44.970Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}