Path Renaming Options
Path renaming options allow you to restructure your repository by renaming or moving files and directories throughout history.
Path renaming does NOT select paths - it only renames paths that are selected by filter options. You need both filter AND rename options for most use cases.
Basic Path Renaming
—path-rename
Rename paths matching OLD_NAME to NEW_NAME.Format: OLD_NAME:NEW_NAMEAliases: --path-rename-matchMultiple: Yes - can be specified multiple timesApplies to: Both files and directoriesTrailing slashes: Optional for directoriesBasic examples:# Rename a directory
git filter-repo --path-rename old-dir/:new-dir/
# Rename a file
git filter-repo --path-rename old-name.txt:new-name.txt
# Move to subdirectory
git filter-repo --path-rename src/:lib/src/
# Move from subdirectory to root
git filter-repo --path-rename subdir/file.txt:file.txt
Rename Patterns
Moving to Root
# Make subdirectory the new root
git filter-repo --path-rename mysubdir/:
The colon (:) with nothing after it means “move to root”.
Moving from Root
# Move everything to a subdirectory
git filter-repo --path-rename :newsubdir/
The colon (:) with nothing before it means “apply to root”.
Multiple Renames
# Rename and merge multiple directories
git filter-repo \
--path-rename cmds/:tools/ \
--path-rename src/scripts/:tools/
Both cmds/ and src/scripts/ are renamed to tools/.
Handling Collisions
If renaming causes path collisions, rename one first:
# Avoid collision by renaming one file differently
git filter-repo \
--path-rename cmds/run.sh:tools/do_release.sh \
--path-rename cmds/:tools/ \
--path-rename src/scripts/:tools/
Common Use Cases
Using shortcut:
git filter-repo --subdirectory-filter mysubdir/
Equivalent long form:
git filter-repo --path mysubdir/ --path-rename mysubdir/:
Move Project to Subdirectory
Using shortcut:
git filter-repo --to-subdirectory-filter myproject/
Equivalent long form:
git filter-repo --path-rename :myproject/
The long form requires understanding that : means root level.
Merge Two Directories
git filter-repo --path-rename old-api/:api/ --path-rename new-api/:api/
Both directories are merged into api/.
Reorganize Directory Structure
git filter-repo \
--path-rename src/:lib/ \
--path-rename tests/:test/ \
--path-rename doc/:docs/
Rename and Filter
# Keep only two directories and rename them
git filter-repo \
--path src/main/ \
--path src/utils/ \
--path-rename src/main/:app/ \
--path-rename src/utils/:lib/
Order matters! Filters must select paths in their FINAL names after renames:# Correct - filter uses final name
git filter-repo --path-rename old/:new/ --path new/
# Wrong - new/ doesn't exist when filter runs
git filter-repo --path new/ --path-rename old/:new/
Advanced Renaming
Conditional Renaming with Callbacks
For complex renaming logic, use --filename-callback:
git filter-repo --filename-callback '
if filename.startswith(b"old/"):
return b"new/" + filename[4:]
return filename
'
Learn more about callbacks →
Regex-Based Renaming
Use --paths-from-file with regex for pattern-based renaming:
Create paths.txt:
regex:^old-(.*)/==new-\1/
regex:^src/v([0-9]+)/==src/version-\1/
Apply renames:
git filter-repo --paths-from-file paths.txt
Handling Special Cases
Renamed Files in History
If a file was renamed during repository history:
# Include both old and new names
git filter-repo \
--path oldname.txt \
--path newname.txt \
--path-rename oldname.txt:unified.txt \
--path-rename newname.txt:unified.txt
Case-Only Renames
# Rename with only case change
git filter-repo --path-rename README.md:readme.md
On case-insensitive filesystems (Windows, macOS), you may need to use a temporary intermediate name.
Wildcard Alternatives
Since --path-rename doesn’t support wildcards directly, use --filename-callback:
# Rename all .txt files to .md
git filter-repo --filename-callback '
if filename.endswith(b".txt"):
return filename[:-4] + b".md"
return filename
'
Important Considerations
Path Filtering vs Path Renaming
Path renaming does NOT filter!This is empty (no paths selected):git filter-repo --path-rename old/:new/
This works (paths explicitly selected):git filter-repo --path old/ --path-rename old/:new/
Rename Processing Order
Renames are applied in the order specified:
# Source -> Intermediate -> Final
git filter-repo \
--path-rename sources/:intermediate/ \
--path-rename intermediate/:final/
The result is sources/ → final/
Incompatibility with —use-base-name
# This will ERROR
git filter-repo --use-base-name --path-rename old/:new/
--use-base-name and --path-rename cannot be used together.
Verification
After renaming, verify the results:
# Check structure of resulting history
git ls-tree -r --name-only HEAD
# Verify specific files exist
git log --all --name-only -- new-path/
# Compare before/after
git filter-repo --analyze # Before
# ... perform filtering ...
git filter-repo --analyze # After
See Also