How to fix fatal: can not move directory into itself in Git
The 'can not move directory into itself' error occurs when using git mv with wildcards that include the destination directory. Use the -k flag to skip problematic moves, or exclude the destination from the pattern.
Quick fix
Fixes fatal: can not move directory into itself
# Skip moves that would fail (including moving directory into itself)
git mv -k * destination_folder/- Use the -k flag to skip problematic moves
- Use extended globbing to exclude the destination
- Move files individually with a loop
- Create destination first, then move in two steps
# Skip moves that would fail (including moving directory into itself)git mv -k * destination_folder/fatal: can not move directory into itself
What this error means
The "fatal: can not move directory into itself" error occurs when you use `git mv` with a wildcard pattern (like `*`) that expands to include the destination directory itself. For example, when you run `git mv * subdirectory/`, the shell expands `*` to include ALL items in the current directory, including the destination `subdirectory`. Git then attempts to move `subdirectory` into itself, which is logically impossible and would create an infinite loop, so Git aborts the entire operation with this error. This is a common user error when trying to reorganize project structure, such as moving all files into a new subdirectory. The fix is straightforward: either use the `-k` flag to skip problematic moves, exclude the destination from your pattern, or move files in a different way.
Typical symptoms
- git mv command fails immediately with 'fatal: can not move directory into itself'
- Using wildcards like 'git mv * folder/' produces this error
- The move operation is completely aborted and no files are moved
- The same command works with regular 'mv' but fails with 'git mv'
- Error occurs when trying to restructure a repository
Common causes
- Using wildcards (*) that expand to include the destination directory
- Running 'git mv * subdirectory/' where subdirectory is in the current folder
- Shell glob expansion including the target directory in the source list
- Attempting to move a folder into a subdirectory of itself
- Not realizing that * matches all files and directories including the destination
How to fix "fatal: can not move directory into itself"
The -k flag tells Git to skip any move operations that would cause errors, while still processing the valid ones:
# Skip moves that would fail (including moving directory into itself)
git mv -k * destination_folder/This is the simplest solution. Git will move all files and subdirectories except the destination folder itself.
Note: The -k flag may not work on all systems (some report issues on macOS Sierra and Ubuntu). If it doesn't work for you, try the alternative methods below.
In Bash, you can use extended globbing to exclude specific directories from the pattern:
# Enable extended globbing
shopt -s extglob
# Move everything except the destination folder
git mv !(destination_folder) destination_folder/
# Disable extended globbing when done (optional)
shopt -u extglobThe !(pattern) syntax matches everything that doesn't match the pattern.
Use a loop to move each item separately, excluding the destination:
# Move all items except 'destination_folder'
for file in $(ls | grep -v 'destination_folder'); do
git mv "$file" destination_folder/
doneOr more robustly with find:
# Move files and directories, excluding the destination
find . -maxdepth 1 -not -name 'destination_folder' -not -name '.' | while read item; do
git mv "$item" destination_folder/
doneIf the destination doesn't exist yet, create it and then move items:
# Create the destination directory
mkdir -p new_folder
# Move specific files/folders explicitly
git mv file1.txt file2.txt subfolder/ new_folder/
# Or use the -k flag now that the directory exists
git mv -k * new_folder/Being explicit about what you're moving avoids wildcard issues entirely.
To move only Git-tracked files (ignoring untracked files and directories):
# Move all tracked files to a subdirectory
for f in $(git ls-files); do
mkdir -p "destination_folder/$(dirname $f)"
git mv "$f" "destination_folder/$f"
doneThis approach is particularly useful when you want to preserve the directory structure within the destination.
If git mv is giving you trouble, you can use the regular mv command and let Git detect the changes:
# Create destination if needed
mkdir -p destination_folder
# Move files with regular mv (which handles this case fine)
mv file1.txt file2.txt other_folder/ destination_folder/
# Stage the changes
git add -A
# Verify Git detected the moves
git statusGit is smart enough to detect that files were moved (not deleted and re-added) when the content is identical.
After moving files, verify everything is correct:
# Check git status
git status
# Verify the renamed/moved files show correctly
git diff --staged --name-status
# Commit the changes
git commit -m "Move files to destination_folder"The status should show files as "renamed" (R) rather than deleted and added, indicating Git tracked the move correctly.
Advanced notes
### Understanding Shell Glob Expansion
When you type git mv * destination/, your shell expands * BEFORE passing arguments to Git. So Git receives something like:
git mv file1.txt file2.txt destination/ destination/Git then tries to move each item, including destination/ into destination/, which is impossible.
### The -k Flag Behavior
The -k (skip) flag tells Git to silently skip any move operations that would fail, rather than aborting the entire command. This includes:
- Moving a directory into itself
- Source files that don't exist
- Destination already exists (without -f)
### Case-Sensitive Renames
On case-insensitive filesystems (default macOS, Windows), renaming a directory to change only case requires a two-step approach:
# Won't work directly on case-insensitive systems:
git mv Folder folder # fatal: renaming 'Folder' failed: Invalid argument
# Instead, use a temporary name:
git mv Folder temp_folder
git mv temp_folder folder### Preserving History with Moves
Git tracks content, not files, so moves are automatically detected. However, for cleaner history:
# Use git log --follow to track file history across renames
git log --follow -- destination_folder/file.txt### PowerShell Users
In PowerShell on Windows, use this syntax instead:
git mv -k (Get-ChildItem *) destination_folder/### Dry Run Before Moving
Always preview what will happen before executing:
# Dry run - shows what would be moved without actually doing it
git mv -n * destination_folder/This helps you identify potential issues before they occur.
Frequently asked questions
- What does "fatal: can not move directory into itself" mean?
- The "fatal: can not move directory into itself" error occurs when you use git mv with a wildcard pattern (like ) that expands to include the destination directory itself. For example, when you run git mv subdirectory/, the shell expands * to include ALL items in the current directory, including the destination subdirectory. Git then attempts to move subdirectory into itself, which is logically impossible and would create an infinite loop, so Git aborts the entire operation with this error.
- How do I fix "fatal: can not move directory into itself"?
- The 'can not move directory into itself' error occurs when using git mv with wildcards that include the destination directory. Use the -k flag to skip problematic moves, or exclude the destination from the pattern.
- What causes "fatal: can not move directory into itself"?
- Using wildcards (*) that expand to include the destination directory Running 'git mv * subdirectory/' where subdirectory is in the current folder Shell glob expansion including the target directory in the source list
- Is the "fatal: can not move directory into itself" error serious?
- It is a low-severity error โ more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- ๐Git Official Documentation
- ๐Git - git-mv Documentation(Official Docs)
- ๐ฌ
- ๐ฌIn a Git repository, how to properly rename a directory?(Stack Overflow)
- ๐ฌGit move folder one level down and maintain history(Stack Overflow)
- ๐ฌGit command to move a folder inside another(Stack Overflow)
- ๐ฌGIT move files from folder to subfolder(Stack Overflow)
- ๐
- ๐
- ๐git-mv(1) Manual Page(Official Docs)
- ๐