mv Git Command Guide
The git mv command moves or renames files, directories, or symlinks in the working directory and updates the Git index to reflect the changes. It combines the functionality of Unix mv with Git index management.
git mv Syntax:
Section titled “git mv Syntax:”git mv [-v] [-f] [-n] [-k] <source> <destination>git mv [-v] [-f] [-n] [-k] <source>... <destination-directory>Command Options:
Section titled “Command Options:”| Option | Description |
|---|---|
-v, --verbose | Report renamed files |
-f, --force | Overwrite destination if it exists |
-n, --dry-run | Show what would be done without doing it |
-k, --skip-errors | Skip rename errors and continue |
Parameters:
Section titled “Parameters:”| Parameter | Description |
|---|---|
<source> | File, directory, or symlink to move/rename |
<destination> | New name/path for the item |
<destination-directory> | Directory to move sources into |
Understanding Git mv Operations:
Section titled “Understanding Git mv Operations:”Index vs Working Directory:
Section titled “Index vs Working Directory:”git mv combines two operations:1. Unix mv: Move/rename in working directory2. Git add/rm: Update index to reflect changes
Equivalent to:git rm <source>mv <source> <destination>git add <destination>Move vs Rename:
Section titled “Move vs Rename:”# Rename (same directory)git mv old-name.txt new-name.txt
# Move (different directory)git mv file.txt subdir/file.txt
# Move multiple filesgit mv file1.txt file2.txt docs/Basic Usage Examples:
Section titled “Basic Usage Examples:”Renaming Files:
Section titled “Renaming Files:”# Rename a single filegit mv old-file.txt new-file.txt
# Rename with verbose outputgit mv -v README.md README.rst
# Rename multiple files to new directorygit mv script.py test.py bin/Moving Files and Directories:
Section titled “Moving Files and Directories:”# Move file to subdirectorygit mv config.yml config/settings.yml
# Move directorygit mv old-package new-package
# Move multiple items to directorygit mv file1.txt file2.txt docs/Force Operations:
Section titled “Force Operations:”# Force overwrite existing destinationgit mv -f new-file.txt existing-file.txt
# Force move read-only filesgit mv -f readonly-file.txt destination/Dry Run Operations:
Section titled “Dry Run Operations:”# Preview what would be movedgit mv -n old-name new-name
# Check multiple file movesgit mv -n *.log logs/Advanced File Management Scenarios:
Section titled “Advanced File Management Scenarios:”Batch File Organization:
Section titled “Batch File Organization:”#!/bin/bash# Organize project files by type
organize_project() { echo "Organizing project files..."
# Create directories if they don't exist mkdir -p src include docs tests scripts
# Move source files git mv -v *.c *.cpp *.h src/ 2>/dev/null || true git mv -v include/*.h include/ 2>/dev/null || true
# Move documentation git mv -v *.md *.rst *.txt docs/ 2>/dev/null || true
# Move test files git mv -v test_*.py test-*.js tests/ 2>/dev/null || true
# Move scripts git mv -v *.sh *.py scripts/ 2>/dev/null || true
echo "File organization complete" git status --porcelain}
organize_projectRefactoring Directory Structure:
Section titled “Refactoring Directory Structure:”# Refactor package structurerefactor_structure() { echo "Refactoring directory structure..."
# Create new structure mkdir -p src/core src/utils src/api tests/unit tests/integration
# Move core modules git mv lib/core/* src/core/ git mv lib/utils/* src/utils/
# Move API files git mv api/* src/api/
# Move tests git mv tests/unit/* tests/unit/ git mv tests/integration/* tests/integration/
# Remove empty directories find . -type d -empty -delete
echo "Structure refactoring complete" git status}
refactor_structureSafe File Operations:
Section titled “Safe File Operations:”# Safe file operations with backupsafe_move() { local source="$1" local destination="$2"
# Check if source exists if [ ! -e "$source" ]; then echo "Error: Source '$source' does not exist" return 1 fi
# Create backup if destination exists if [ -e "$destination" ]; then cp "$destination" "${destination}.backup" echo "Created backup: ${destination}.backup" fi
# Perform move if git mv "$source" "$destination"; then echo "Successfully moved '$source' to '$destination'" else echo "Failed to move '$source'" # Restore backup if it exists [ -e "${destination}.backup" ] && mv "${destination}.backup" "$destination" return 1 fi}
# Usagesafe_move "important-file.txt" "archive/important-file.txt"Integration with Development Workflows:
Section titled “Integration with Development Workflows:”Code Refactoring Workflow:
Section titled “Code Refactoring Workflow:”#!/bin/bash# Complete code refactoring workflow
refactor_component() { local old_component="$1" local new_component="$2"
echo "Refactoring component: $old_component -> $new_component"
# Rename main file git mv "${old_component}.py" "${new_component}.py"
# Rename test file git mv "test_${old_component}.py" "test_${new_component}.py"
# Update imports in all Python files find . -name "*.py" -exec sed -i "s/from $old_component import/from $new_component import/g" {} \; find . -name "*.py" -exec sed -i "s/import $old_component/import $new_component/g" {} \;
# Update documentation sed -i "s/$old_component/$new_component/g" README.md
# Stage all changes git add .
echo "Component refactoring complete" echo "Review changes with: git diff --cached"}
# Usagerefactor_component "old_module" "new_module"Asset Management:
Section titled “Asset Management:”# Manage project assetsorganize_assets() { echo "Organizing project assets..."
# Create asset directories mkdir -p assets/images assets/fonts assets/audio assets/video
# Move image files git mv *.png *.jpg *.jpeg *.gif *.svg assets/images/ 2>/dev/null || true
# Move font files git mv *.ttf *.woff *.woff2 assets/fonts/ 2>/dev/null || true
# Move audio files git mv *.mp3 *.wav *.ogg assets/audio/ 2>/dev/null || true
# Move video files git mv *.mp4 *.avi *.mov assets/video/ 2>/dev/null || true
echo "Asset organization complete" git status --short}
organize_assetsConfiguration Management:
Section titled “Configuration Management:”# Manage configuration filesmanage_configs() { echo "Managing configuration files..."
# Create config directory mkdir -p config
# Move configuration files git mv *.config *.cfg *.ini *.yaml *.yml config/ 2>/dev/null || true
# Move environment files git mv .env* config/ 2>/dev/null || true
# Create .gitignore for sensitive configs cat >> config/.gitignore << EOF*.local*.secret*password*EOF
git add config/.gitignore
echo "Configuration management complete"}
manage_configsConfiguration and Best Practices:
Section titled “Configuration and Best Practices:”Git Configuration for mv:
Section titled “Git Configuration for mv:”# Configure mv behaviorgit config core.ignorecase false # Case-sensitive renames
# Set up aliases for common operationsgit config alias.mv 'mv -v' # Always verbosegit config alias.rename 'mv' # Alias for rename operationsHandling Special Cases:
Section titled “Handling Special Cases:”# Handle case-sensitive renamesgit mv oldName newName # Works on case-sensitive filesystems
# Handle symlinksgit mv symlink.txt new-symlink.txt
# Handle directories with contentgit mv old-dir/ new-dir/
# Handle files with special charactersgit mv "file with spaces.txt" "renamed file.txt"Performance Considerations:
Section titled “Performance Considerations:”# Batch operations for performancebatch_rename() { local pattern="$1" local replacement="$2"
# Find files matching pattern find . -name "*$pattern*" -type f | while read file; do new_name=$(echo "$file" | sed "s/$pattern/$replacement/g") mkdir -p "$(dirname "$new_name")" git mv "$file" "$new_name" done}
# Usagebatch_rename "_old" "_new"Troubleshooting Common Issues:
Section titled “Troubleshooting Common Issues:”File Not Found Errors:
Section titled “File Not Found Errors:”# Check if file existsls -la file-to-move.txt
# Check Git statusgit status --porcelain | grep file-to-move.txt
# Check if file is ignoredgit check-ignore file-to-move.txtPermission Errors:
Section titled “Permission Errors:”# Check file permissionsls -la file.txt
# Fix permissionschmod 644 file.txt
# Handle read-only fileschmod u+w file.txtgit mv file.txt destination/Case Sensitivity Issues:
Section titled “Case Sensitivity Issues:”# Check filesystem case sensitivitytouch test.txtmv test.txt TEST.txt 2>/dev/null && echo "Case-insensitive" || echo "Case-sensitive"
# Handle case-insensitive filesystemsgit mv oldname.txt newname.txt # May not work on case-insensitive FSDirectory Move Issues:
Section titled “Directory Move Issues:”# Check if destination directory existsls -la destination/
# Create destination if neededmkdir -p destination/git mv source/ destination/
# Handle nested directoriesgit mv -k source/ destination/ # Skip errorsIndex Synchronization Issues:
Section titled “Index Synchronization Issues:”# Check index statusgit status
# Reset index if neededgit reset HEAD file.txtgit mv file.txt new-location/
# Handle staged changesgit stashgit mv file.txt new-location/git stash popReal-World Usage Examples:
Section titled “Real-World Usage Examples:”Project Restructuring:
Section titled “Project Restructuring:”#!/bin/bash# Complete project restructuring
restructure_project() { echo "Restructuring project layout..."
# Create new directory structure mkdir -p src/main src/test src/docs scripts tools
# Move source files git mv *.java src/main/ 2>/dev/null || true git mv src/*.java src/main/ 2>/dev/null || true
# Move test files git mv *Test.java src/test/ 2>/dev/null || true git mv test/*.java src/test/ 2>/dev/null || true
# Move documentation git mv *.md src/docs/ 2>/dev/null || true git mv docs/* src/docs/ 2>/dev/null || true
# Move build scripts git mv build.sh scripts/ 2>/dev/null || true git mv *.gradle scripts/ 2>/dev/null || true
# Move tools and utilities git mv tools/* tools/ 2>/dev/null || true git mv utils/* tools/ 2>/dev/null || true
# Clean up empty directories find . -type d -empty -delete
echo "Project restructuring complete" echo "Review changes: git status" echo "Commit when ready: git commit -m 'Restructure project layout'"}
restructure_projectComponent Extraction:
Section titled “Component Extraction:”# Extract component to separate directoryextract_component() { local component_name="$1" local target_dir="$2"
echo "Extracting component: $component_name"
# Create component directory mkdir -p "$target_dir"
# Find component files find . -name "*$component_name*" -type f | while read file; do # Calculate relative path rel_path="${file#./}" target_path="$target_dir/$rel_path"
# Create target directory mkdir -p "$(dirname "$target_path")"
# Move file git mv "$file" "$target_path" done
echo "Component extraction complete" echo "Component files moved to: $target_dir"}
# Usageextract_component "auth" "components/authentication"Automated File Organization:
Section titled “Automated File Organization:”# Automated file organization by typeauto_organize() { echo "Auto-organizing project files..."
# Define file type mappings declare -A file_types=( ["*.py"]="src/" ["*.js"]="src/" ["*.ts"]="src/" ["*.java"]="src/" ["*.c"]="src/" ["*.cpp"]="src/" ["*.h"]="include/" ["*.hpp"]="include/" ["*.md"]="docs/" ["*.txt"]="docs/" ["*.rst"]="docs/" ["*.html"]="docs/" ["*.css"]="assets/css/" ["*.scss"]="assets/scss/" ["*.js"]="assets/js/" ["*.png"]="assets/images/" ["*.jpg"]="assets/images/" ["*.svg"]="assets/images/" ["*.ttf"]="assets/fonts/" ["*.woff"]="assets/fonts/" ["test_*.py"]="tests/" ["*Test.java"]="tests/" ["*.spec.js"]="tests/" ["*.sh"]="scripts/" ["Makefile"]="scripts/" )
# Process each file type for pattern in "${!file_types[@]}"; do target_dir="${file_types[$pattern]}" mkdir -p "$target_dir"
# Move matching files git mv $pattern "$target_dir" 2>/dev/null || true done
echo "Auto-organization complete" git status --short}
auto_organizeWhat’s the difference between git mv and regular mv?
Section titled “What’s the difference between git mv and regular mv?”git mv moves files in working directory and updates Git index automatically; regular mv only affects working directory, requiring separate git add/rm commands.
Can git mv move directories?
Section titled “Can git mv move directories?”Yes, git mv can move entire directories and their contents recursively, updating the index for all moved files.
What happens if git mv fails?
Section titled “What happens if git mv fails?”Working directory changes are reverted, index remains unchanged. No partial moves occur - operation is atomic.
Can git mv overwrite existing files?
Section titled “Can git mv overwrite existing files?”Use -f/—force flag to overwrite existing destination files. Without force, git mv refuses to overwrite.
How do I preview git mv operations?
Section titled “How do I preview git mv operations?”Use -n/—dry-run to show what would be moved without actually performing the operation.
Can git mv move untracked files?
Section titled “Can git mv move untracked files?”No, git mv only works on files tracked by Git. Use regular mv for untracked files, then git add.
What’s the impact of git mv on Git history?
Section titled “What’s the impact of git mv on Git history?”File moves are tracked in Git history. git log —follow shows file history across renames and moves.
Can git mv move files between branches?
Section titled “Can git mv move files between branches?”No, git mv operates on current working directory and index. File moves must be committed before affecting other branches.
How do I undo a git mv operation?
Section titled “How do I undo a git mv operation?”Use git reset HEAD
Can git mv handle symlinks?
Section titled “Can git mv handle symlinks?”Yes, git mv properly handles symbolic links, preserving link targets and updating index appropriately.
What’s the performance impact of git mv on large directories?
Section titled “What’s the performance impact of git mv on large directories?”Similar to regular mv for working directory, plus index update overhead. Use git mv -k to skip errors and continue with large operations.
How do I handle git mv in scripts?
Section titled “How do I handle git mv in scripts?”Use -n for dry runs, check exit codes, and use -k to continue on errors. Always verify operations with git status.
Can git mv work with Git LFS files?
Section titled “Can git mv work with Git LFS files?”Yes, git mv works normally with LFS-tracked files. LFS handles the large file content separately from Git operations.
What’s the relationship between git mv and git rm/git add?
Section titled “What’s the relationship between git mv and git rm/git add?”git mv is equivalent to: git rm
How do I handle encoding issues with git mv?
Section titled “How do I handle encoding issues with git mv?”git mv preserves file content and encoding. Use consistent encoding across repository to avoid issues.
Can git mv work in bare repositories?
Section titled “Can git mv work in bare repositories?”No, requires working directory for file operations. Use in non-bare repositories only.
What’s the difference between git mv and git mv —force?
Section titled “What’s the difference between git mv and git mv —force?”—force allows overwriting existing destination files; normal git mv refuses to overwrite.
How do I handle git mv with merge conflicts?
Section titled “How do I handle git mv with merge conflicts?”Resolve conflicts first, then use git mv. Avoid moving conflicted files until conflicts are resolved.
Applications of the git mv command
Section titled “Applications of the git mv command”- Code Refactoring: Rename classes, modules, and functions while preserving Git history
- Project Restructuring: Reorganize directory layouts and file hierarchies
- Asset Management: Organize media files, documentation, and project resources
- Configuration Management: Move configuration files to dedicated directories
- Component Extraction: Move related files into separate component directories
- Build System Organization: Restructure build scripts and configuration files