KhueApps
Home/DevOps/Fix Git error: destination path exists and is not an empty directory

Fix Git error: destination path exists and is not an empty directory

Last updated: October 07, 2025

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

ApproachKeeps existing files?Risk
Clone to new directoryNo (existing dir untouched)Low
Empty then cloneNo (you delete/move files)Medium
Init + fetch, then resetNo (overwrites with remote)High
Init + fetch, then merge/rebaseYes (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)

  1. Pick a unique directory name.
  2. Run:
    git clone <url> <new-dir>
    
  3. 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

  1. Back up any important files.
  2. Remove or move everything out of the target directory so it is empty.
  3. 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.

  1. Initialize and attach the remote:

    cd <existing-dir>
    git init
    git remote add origin <url>
    git fetch origin
    
  2. Pick 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
      
  • 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 main
    
  • How 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.

Series: Git

DevOps