Skip to content
Foxipa

Suggest an edit

Tell us what should be corrected, clarified, or improved. Submission will be connected to Foxipa’s contribution service later.

No information is sent anywhere yet. Your suggestion is only prepared in your browser.

Learning

Git Removing and Moving Tracked Files

Remove tracked paths, remove paths from the index without deleting the working-tree file, and move or rename tracked paths while understanding exactly what changes before a commit.

Levels: Beginner ~20 min read

Basic

Change tracked paths as part of the next snapshot

A tracked file can be removed or moved while preserving Git’s knowledge of that change for the next commit. This lesson owns the path-change operations `git rm` and `git mv`. The earlier foundations lesson introduced the index and the basic staging model; here the focus is specifically on how path removal and movement update the working tree and index together.

Remove a tracked file with `git rm`

`git rm <path>` removes the path from the working tree and removes its entry from the index. The deletion is therefore already staged for the next commit. It does not itself create that commit.

bash
printf "keep me\n" > keep.txt
printf "remove me\n" > obsolete.txt
git add keep.txt obsolete.txt
git commit -m "Add files"
git rm obsolete.txt
git status --short

After `git rm`, `obsolete.txt` is gone from the working tree and the index records its deletion relative to `HEAD`. `git status --short` reports the staged deletion. The history still contains the file until a new commit records the removal.

Quick check

Which two repository surfaces does ordinary `git rm obsolete.txt` update immediately?

git rm obsolete.txtgit status --short && test ! -e obsolete.txt

Remove a directory of tracked files

When the pathspec names a directory, `git rm` requires `-r` for recursive removal. This prevents a directory name from implicitly authorizing recursive deletion.

bash
mkdir docs
printf "guide\n" > docs/guide.txt
printf "api\n" > docs/api.txt
git add docs
git commit -m "Add docs"
git rm -r docs
git status --short

Quick check

Why is `-r` required when `git rm` is given a directory path for recursive removal?

git rm -r docsgit status --short && test ! -e docs/guide.txt && test ! -e docs/api.txt

Keep the working-tree file but remove it from the index

`git rm --cached <path>` changes a different boundary: it removes the path from the index but leaves the working-tree file alone. This is useful when a file should stop being tracked while remaining on disk. It does not itself add an ignore rule.

bash
printf "local settings\n" > local.txt
git add local.txt
git commit -m "Track local file"
git rm --cached local.txt
git status --short
test -f local.txt

Quick check

After `git rm --cached local.txt`, what remains?

git rm --cached local.txttest -f local.txt && ! git ls-files --error-unmatch local.txt >/dev/null 2>&1

Understand why `git rm` can refuse a modified file

By default, `git rm` protects changes that do not match the branch tip or that are already staged. The command can be forced with `-f`, but this lesson does not use force deletion as a routine workflow. The important learner boundary is that Git checks whether removing the path would discard staged or working-tree content.

bash
printf "original\n" > important.txt
git add important.txt
git commit -m "Add important file"
printf "local change\n" > important.txt
git rm important.txt

The final command is expected to fail because the working-tree content differs from the committed version. A failed `git rm` is useful information: Git refused to turn an uncommitted local change into a deletion without explicit force.

Quick check

Why can `git rm important.txt` refuse after the tracked file was modified but not staged?

printf "local change\n" > important.txtgit rm important.txt

Rename or move a tracked path with `git mv`

`git mv <source> <destination>` moves or renames the path in the working tree and updates the index after successful completion. The movement is still only a staged change until a commit records it.

bash
printf "chapter one\n" > chapter-1.txt
git add chapter-1.txt
git commit -m "Add chapter"
git mv chapter-1.txt introduction.txt
git status --short
test ! -e chapter-1.txt
test -f introduction.txt

Quick check

What does successful `git mv chapter-1.txt introduction.txt` update before the next commit?

git mv chapter-1.txt introduction.txtgit status --short && test -f introduction.txt && test ! -e chapter-1.txt

A rename is still a change that must be committed

`git mv` does not create history by itself. After the command, the index represents the new path and the working tree contains it, but `HEAD` still names the previous commit. A subsequent `git commit` is what makes the path change part of history.

bash
git mv introduction.txt chapter-one.txt
git rev-parse HEAD
git status --short
git commit -m "Rename chapter"
git status --short
git show --name-status --format=HEAD HEAD

Quick check

Which operation makes a successful `git mv` part of repository history?

git mv old.txt new.txtgit commit -m "Rename old file"

Moving a file is not the same as deleting it

At the command level, `git mv` is a coordinated working-tree and index operation. Conceptually, it expresses one path moving to another location. Git may later describe the committed change as a rename when comparing snapshots, but learners should not treat “rename” as a special object stored in place of the old and new paths. The important state change is the path recorded by the index and, after commit, by the tree for the new snapshot.

bash
printf "same contents\n" > before.txt
git add before.txt
git commit -m "Add source path"
git mv before.txt after.txt
git diff --cached --name-status

Quick check

Before the move is committed, where can you observe the staged path change?

git mv before.txt after.txtgit diff --cached --name-status

Practice what you learned

Use the dedicated Git code-completion exercise for this lesson.

Official-source boundary

This lesson is grounded only in the official Git project documentation for `git-rm` and `git-mv`. The current official manuals are Git 2.56.0; their version histories show no `git-rm` or `git-mv` changes between the local verification baseline Git 2.47.3 and the current documentation baseline. The lesson intentionally does not infer Git behavior from third-party tutorials or hosting-provider documentation.

Was this page helpful?

Mark this learning resource complete to track your learning progress.