This error occurs when you try to rename or move a file using git mv but a file already exists at the destination path. Git refuses to overwrite existing files by default to protect against accidental data loss.
When you run `git mv source destination`, Git attempts to rename or move a tracked file from one location to another. Unlike the regular Unix `mv` command which silently overwrites existing files, Git's `git mv` command has a built-in safety check. If a file already exists at the destination path—whether tracked by Git or not—the command fails with "fatal: destination exists". This is a safety feature designed to prevent you from accidentally overwriting important files or losing uncommitted changes. This error commonly appears when renaming files to match case changes on case-insensitive file systems (Windows, macOS), when reorganizing project structure, or when two files with similar names need to be consolidated.
First, verify what file exists at the destination path:
ls -la newfile.txt
git statusCheck if the destination file is tracked by Git:
git ls-files newfile.txtIf this returns the filename, the file is tracked. If empty, it's untracked or doesn't exist in Git's index.
If you intentionally want to overwrite the destination file, use the -f (force) flag:
git mv -f file.txt newfile.txtWarning: This will permanently overwrite the destination file. Make sure you don't need its contents, or back it up first:
cp newfile.txt newfile.txt.backup
git mv -f file.txt newfile.txtThe -f flag tells Git to proceed even though the destination exists.
If you want to replace the destination file but want more control over the process:
# Remove the destination from Git (keeps it in working directory)
git rm --cached newfile.txt
# Or remove it completely
git rm newfile.txt
# Now perform the move
git mv file.txt newfile.txtThis approach gives you a chance to verify what you're removing before the move.
On case-insensitive filesystems (Windows, macOS), renaming file.txt to File.txt triggers this error because the OS considers them the same file.
Solution 1: Use the -f flag (Git 2.0.1+):
git mv -f file.txt File.txtSince Git 2.0.1, Git detects case-only renames automatically, but older versions may still need -f.
Solution 2: Two-step rename via intermediate name:
git mv file.txt temp-file.txt
git mv temp-file.txt File.txtThis works on any Git version and any filesystem.
When moving multiple files and some destinations already exist, use -k to skip problematic files instead of failing entirely:
git mv -k *.txt archive/The -k flag skips any move that would cause an error (destination exists, source doesn't exist, source not tracked). Files that can be moved successfully will be moved.
This is useful for batch reorganization where some files may already be in place.
Before running a batch move, use -n (dry-run) to see what would happen:
git mv -n *.js src/This shows which files would be moved without actually moving them. Combine with -v for verbose output:
git mv -n -v file.txt newfile.txtIf the dry-run shows "fatal: destination exists", you'll know to use -f or handle the conflict.
After successfully renaming, the change is staged automatically. Commit it:
git status
git commit -m "Rename file.txt to newfile.txt"Git tracks renames through content similarity detection. To preserve clear history, commit renames separately from content changes when possible.
### Git mv Flags Reference
| Flag | Description |
|------|-------------|
| -f, --force | Force rename/move even if destination exists |
| -k | Skip moves that would cause errors |
| -n, --dry-run | Show what would happen without doing it |
| -v | Verbose output showing each file moved |
### git mv vs Regular mv
The git mv command is equivalent to:
mv source destination
git rm source
git add destinationYou can use regular mv followed by git add and git rm, but git mv is safer because it checks for conflicts first.
### Preserving History Across Renames
Git doesn't actually store renames—it detects them through content similarity. To view history across renames:
git log --follow -- newfile.txtFor the clearest history, perform renames in isolated commits without other changes.
### Handling Submodules
If moving a submodule, git mv will also update the .gitmodules file and the submodule's core.worktree setting. This only works for submodules initialized with Git 1.7.8+.
### When -f Doesn't Work
If git mv -f still fails, your Git index may be out of sync:
git reset HEAD
git statusThen retry the move operation.
warning: BOM detected in file, this may cause issues
UTF-8 Byte Order Mark (BOM) detected in file
fatal: Server does not support --shallow-exclude
Server does not support --shallow-exclude
warning: filtering out blobs larger than limit
Git partial clone filtering large blobs warning
fatal: Server does not support --shallow-since
Server does not support --shallow-since in Git
kex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server