Table of Contents
Overview
This Git error appears when you run git clone into a path that already exists and contains files:
fatal: destination path 'X' already exists and is not an empty directory
Git refuses to overwrite existing files during clone to prevent data loss.
Quickstart (choose one)
- Clone into a new directory (safest, simplest):
- git clone <url> <new-dir>
- Make the target directory empty, then clone:
- Move or delete its contents, then git clone <url> <existing-dir>
- Keep the existing files and connect to the remote using git init + fetch:
- cd <existing-dir>; git init; git remote add origin <url>; git fetch
- Then either align to remote (reset) or merge with remote.
When to use which
| Approach | Keeps existing files? | Risk |
|---|---|---|
| Clone to new directory | No (existing dir untouched) | Low |
| Empty then clone | No (you delete/move files) | Medium |
| Init + fetch, then reset | No (overwrites with remote) | High |
| Init + fetch, then merge/rebase | Yes (resolve conflicts) | Medium |
Minimal working example
Reproduce the error and fix it two ways.
# Reproduce
mkdir app && echo "local" > app/local.txt
git clone https://github.com/example/repo.git app
# -> fatal: destination path 'app' already exists and is not an empty directory.
# Fix A: clone to a new directory
git clone https://github.com/example/repo.git app-repo
# Fix B: convert existing dir to a repo and align to remote (destructive)
cd app
git init
git remote add origin https://github.com/example/repo.git
git fetch origin
# Choose a branch that exists on the remote, e.g., main
git switch -C main --track origin/main
# If files conflict or you want exact remote state, do:
# WARNING: overwrites local changes
git reset --hard origin/main
Detailed steps
1) Clone into a new directory (recommended)
- Pick a unique directory name.
- Run:
git clone <url> <new-dir> - Enter the directory and work normally.
Pros: zero risk to existing files. Cons: you’ll have two directories.
2) Make the existing directory empty, then clone
- Back up any important files.
- Remove or move everything out of the target directory so it is empty.
- Run:
git clone <url> <existing-dir>
Pros: clean checkout at the desired path. Cons: you must manage backups manually.
3) Keep the existing files: init + fetch
Use this when the directory already has content you want to keep or reconcile with a remote repo.
Initialize and attach the remote:
cd <existing-dir> git init git remote add origin <url> git fetch originPick the remote branch, e.g., main or master. Then choose one of the flows below:
A) Replace local files with the remote (destructive):
- Back up anything important.
- Hard reset to the remote branch:
git switch -C main --track origin/main git reset --hard origin/main - Result: your working tree exactly matches the remote.
B) Keep local files and merge with the remote (non-destructive):
- Commit your local files first so you can merge cleanly:
git add -A git commit -m "feat: import local files" - Create a branch tracking the remote and rebase your work:
git switch -C main --track origin/main git pull --rebase origin main - Resolve any conflicts, then continue the rebase:
git add -A git rebase --continue - Push when ready:
git push -u origin main
Notes:
- Replace main with your actual default branch if different (e.g., master).
- If git switch is unavailable, use git checkout with equivalent flags.
4) Need the repo as a subfolder instead
If you want the remote repo inside a subdirectory of an existing project:
mkdir -p third_party/lib
git clone <url> third_party/lib
This avoids clobbering the parent directory.
Pitfalls to avoid
- There is no --force flag for git clone into a non-empty directory. Use the methods above.
- git reset --hard discards uncommitted changes. Back up before running it.
- Removing .git to “start over” deletes history metadata in that directory. Prefer backups or the new directory approach.
- Checking out a branch after init may fail with “would be overwritten by checkout” if files conflict. Commit or move conflicting files first, or reset hard if you intend to overwrite.
- Be mindful of the default branch name (main vs master) to avoid tracking the wrong branch.
Performance notes
- Large repos: use partial clone to reduce data size during fetch/clone.
- New directory:
git clone --filter=blob:none <url> <new-dir> - Existing directory (init + sparse-checkout):
cd <existing-dir> git init git remote add origin <url> git sparse-checkout init --cone git fetch --filter=blob:none origin git switch -C main --track origin/main
- New directory:
- Narrow your checkout with sparse-checkout for faster syncs of monorepos:
git sparse-checkout set path/to/subdir1 path/to/subdir2 git pull --rebase
FAQ
Can I force git clone into a non-empty directory? No. Clone refuses to write into a non-empty path. Use a new directory, empty the target, or init+fetch.
What if I already have the project files and just want to “attach” Git? Run git init, add/commit your files, create a remote, then push:
git init git add -A git commit -m "initial commit" git remote add origin <url> git branch -M main git push -u origin mainHow do I avoid overwriting local files when connecting to a remote? Commit your local files first, then merge or rebase onto the remote branch and resolve conflicts.
I only need one folder from a big repo. What’s the best approach? Use git sparse-checkout to select paths after init + remote add, or clone then sparse-checkout.
Does --separate-git-dir help here? No. It changes where Git stores its metadata, but does not bypass the non-empty directory restriction during clone.