Restructuring a project
Move a group of source files into a new package directory in one command, so that the commit records the files as moved.
Git · Command
git mv renames or moves a tracked file, directory or symlink in your working tree. In the same step it records that change in the index (staging area).
Last updated
The command has two forms. If you give one source and one destination, Git renames the source to the destination path. If the last argument is a directory that already exists, Git moves every listed source into that directory. Each move happens on disk and in the index together, so you don't need a separate git add or git rm. Nothing goes into history until you commit. Options control how it behaves: -f overwrites an existing destination, -k skips moves that would fail, -n only shows what would happen, and -v prints each name as it is moved. For submodules, it also updates the gitfile, core.worktree and the path setting in .gitmodules.
git mv [-v] [-f] [-n] [-k] <source> <destination>
git mv [-v] [-f] [-n] [-k] <source>... <destination-directory>| Name | Type | Description |
|---|---|---|
<source> | path | The file, directory or symlink to rename or move. It must exist and be tracked by Git. The second form accepts several sources. |
<destination> | path | The new name for a single source (first form). |
<destination-directory> | path | An existing directory that all the listed sources are moved into (second form). |
-f, --force | flag | Rename or move even when the destination already exists, overwriting it. |
-k | flag | Skip any move or rename that would cause an error and carry on with the others. |
-n, --dry-run | flag | Change nothing; only show what would be done. |
-v, --verbose | flag | Print the name of each file as it is moved. |
#!/usr/bin/env bash
set -euo pipefail
# Rename a single tracked file
git mv README.txt README.md
# Preview a bulk move first
mkdir -p docs
git mv -n -v guide.md faq.md docs/
# Perform it, skipping anything that would error
git mv -k -v guide.md faq.md docs/
# Changes are staged; inspect and commit
git status --short
git commit -m "Rename README and move docs into docs/"The script renames one file, previews a bulk move into an existing directory, runs the move while skipping any failures, and then commits the staged result.
Move a group of source files into a new package directory in one command, so that the commit records the files as moved.
Rename a misnamed config or documentation file without having to delete it and add it again by hand.
Move a vendored submodule to another path and have Git update its gitfile and the .gitmodules entry for you.
A shell mv only changes files on disk. git mv also updates the index, so the old path is removed from staging and the new path is added. Without it, you would have to stage the deletion and the addition yourself before committing.
Follow-up: Is the rename visible to other people right after git mv? No. Only the index has changed, so the rename stays local until you commit it and push.
Use the second form: list the sources and put the target directory last. That directory must already exist, and every source is moved into it.
Follow-up: What if some of the sources are untracked or missing? Without -k the command reports an error. With -k Git skips those entries and moves the rest.
git mv treats this as an error and refuses to overwrite the existing file. -f/--force makes it go ahead and replace the destination. Running with -n first lets you see what would happen.
Follow-up: Can -k and -f be combined meaningfully? Yes. -f turns an existing destination into an allowed overwrite rather than an error, so -k then only skips the remaining problems, such as sources that don't exist or aren't tracked.
git rmgit addgit statusgit commitgit submodulegitmodules