{"record":{"id":"5ebd0125dd77ae53","repo":"composer/composer","slug":"the-git-directory-is-missing-from-path-see","errorCode":null,"errorMessage":"The .git directory is missing from '.$path.', see https://getcomposer.org/commit-deps for more information","messagePattern":"The \\.git directory is missing from '\\.\\$path\\.', see https://getcomposer\\.org/commit-deps for more information","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/Composer/Downloader/GitDownloader.php","lineNumber":155,"sourceCode":"        if ($newRef = $this->updateToCommit($package, $path, (string) $ref, $package->getPrettyVersion())) {\n            if ($package->getDistReference() === $package->getSourceReference()) {\n                $package->setDistReference($newRef);\n            }\n            $package->setSourceReference($newRef);\n        }\n\n        return \\React\\Promise\\resolve(null);\n    }\n\n    /**\n     * @inheritDoc\n     */\n    protected function doUpdate(PackageInterface $initial, PackageInterface $target, string $path, string $url): PromiseInterface\n    {\n        GitUtil::cleanEnv($this->process);\n        $path = $this->normalizePath($path);\n        if (!$this->hasMetadataRepository($path)) {\n            throw new \\RuntimeException('The .git directory is missing from '.$path.', see https://getcomposer.org/commit-deps for more information');\n        }\n\n        $cachePath = $this->config->get('cache-vcs-dir').'/'.Preg::replace('{[^a-z0-9.]}i', '-', Url::sanitize($url)).'/';\n        $ref = $target->getSourceReference();\n\n        if (!empty($this->cachedPackages[$target->getId()][$ref])) {\n            $msg = \"Checking out \".$this->getShortHash($ref).' from cache';\n            $remoteUrl = $cachePath;\n        } else {\n            $msg = \"Checking out \".$this->getShortHash($ref);\n            $remoteUrl = '%url%';\n            if (Platform::getEnv('COMPOSER_DISABLE_NETWORK')) {\n                throw new \\RuntimeException('The required git reference for '.$target->getName().' is not in cache and network is disabled, aborting');\n            }\n        }\n\n        $this->io->writeError($msg);\n","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/composer/composer/blob/c435d285c9120efdca35696769c72ea9fdcc0466/src/Composer/Downloader/GitDownloader.php#L137-L173","documentation":"Thrown by doUpdate (src/Composer/Downloader/GitDownloader.php:154) when hasMetadataRepository($path) returns false, i.e. is_dir($path.'/.git') fails. Composer cannot run git fetch/checkout update commands against a directory that has no git repository, so it aborts and points the user to the commit-deps docs. It indicates the existing checkout was not created from a git source.","triggerScenarios":"doUpdate() is invoked for a package whose install path exists but lacks a .git subdirectory. Typically the package was originally installed via --prefer-dist (a zip archive contains no .git), and a later update tries to perform a VCS-style update.","commonSituations":"Running 'composer update vendor/pkg --prefer-source' after the package was installed via dist; someone manually deleted the .git folder from vendor/; a deploy artifact that strips .git directories; switching source types in composer.json.","solutions":["Delete the package directory (rm -rf vendor/vendor/pkg) and reinstall with --prefer-source so a real git checkout is created.","Run 'composer install --prefer-source' to rebuild all vendors from git sources.","If you intentionally use dist, drop the --prefer-source flag so Composer uses ArchiveDownloader instead of GitDownloader.","Restore the missing .git by re-cloning manually into the path if you need to preserve local edits."],"exampleFix":"# before\ncomposer update vendor/pkg --prefer-source   # .git missing -> error\n# after\nrm -rf vendor/vendor/pkg && composer install --prefer-source","handlingStrategy":"validation","validationCode":"// Guard before attempting a source update.\nif (!is_dir($path . '/.git')) {\n    throw new \\LogicException(\n        \"Cannot update $path as git source: .git is missing (installed via dist?). Reinstall with --prefer-source.\"\n    );\n}","typeGuard":"function isGitCheckout(string $path): bool {\n    return is_dir(rtrim($path, '/') . '/.git');\n}","tryCatchPattern":"try {\n    $downloader->update($initial, $target, $path, $url);\n} catch (\\RuntimeException $e) {\n    if (str_starts_with($e->getMessage(), 'The .git directory is missing')) {\n        // reinstall from source instead of updating\n        $filesystem->remove($path);\n        $downloader->download($target, $path);\n        return;\n    }\n    throw $e;\n}","preventionTips":["Pick one of source or dist per package and stick with it.","Don't manually delete .git directories in vendor/.","In deploy artifacts, keep .git if you later update via source."],"tags":["git","filesystem","source","metadata"],"backgroundTag":null,"analyzedSha":"c435d285c9120efdca35696769c72ea9fdcc0466","analyzedAt":"2026-08-07T18:58:23.525Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}