Projects change shape all the time. You rename style.css to main.css, move images into an assets folder, delete an old logo, and realise a file of personal notes should never have been committed. Each of these is a change that Git needs to record, so the rest of your team gets the same tidy structure when they pull.
Git's own commands, git mv and git rm, make these changes and stage them in one step. git rm --cached stops tracking a file while keeping it on your computer, and git clean clears out clutter that was never tracked.
In this lesson you'll use all of them, learn to preview before deleting anything, and fix the "LF will be replaced by CRLF" warning that puzzles many Windows users.
Renaming and moving: git mv
git mv style.css css/main.cssgit mv renames or moves a file and stages the change, so git status shows it as renamed:
R style.css -> css/main.cssGit doesn't actually store renames. It notices that a file disappeared and a very similar file appeared, and reports a rename. That's why renaming in your editor and then running git add -A works just as well. Avoid renaming and heavily editing a file in the same commit: if the content changes too much, Git shows a delete and an add instead of a rename, which makes history harder to follow.
Deleting: git rm
git rm old-logo.png deletes the file from your folder and stages the deletion. The next commit removes it from the project.
- If you've already deleted a file by hand,
git add old-logo.pngorgit add -Astages the deletion too. git rm -r folder/removes a folder and everything in it.- Deleted files aren't lost: they're still in history, and
git restore --source=HEAD~1 old-logo.pngbrings one back from an earlier commit.
Because history keeps everything, deleting a file containing a password doesn't make it safe. The secret must be changed, as the history lesson explains.
Untracking without deleting: git rm --cached
Sometimes a file was committed by mistake: an .env file, an editor's settings folder, or a large export. You want Git to forget it but keep it on your computer:
git rm --cached notes.txt
echo "notes.txt" >> .gitignore
git add .gitignore
git commit -m "Stop tracking notes.txt"--cached removes the file from the staging area only; your copy stays where it is. Adding it to .gitignore stops it being added again. Note that .gitignore only affects untracked files, which is why the --cached step is needed for a file Git already knows about. git ls-files lists every file Git is tracking.
Clearing clutter: git clean
git clean deletes untracked files: things Git has never been told about, like build output, logs and temporary files. Because they were never committed, they can't be recovered afterwards, so always preview first:
| Command | Does |
|---|---|
git clean -n | Dry run: lists untracked files that would be deleted |
git clean -nd | Dry run including untracked folders |
git clean -fd | Deletes untracked files and folders |
git clean -fdx | Also deletes ignored files, such as node_modules |
Git refuses to clean without -f (force) unless you've changed its settings, as a safety net.
Git Files Syntax
File commands
git mv old-name new-name
git rm file.txt
git rm -r folder/
git rm --cached secret.env
git ls-files
git clean -n # preview
git clean -fd # delete untracked files and folders
git restore --source=HEAD~1 file.txtGit Files Summary
git mv old newrenames or moves a file and stages the change.git rm filedeletes a file and stages the deletion; history still has it.git rm --cached filestops tracking a file but keeps it on disk; add it to .gitignore too.git clean -npreviews andgit clean -fddeletes untracked files and folders permanently..gitattributeswith* text=auto eol=lfkeeps line endings consistent across systems.
Git Files Examples
Each example shows the code, the output it produces and what each part does.
Renaming and deleting
git mv style.css css/main.css
git rm old-logo.png
git status --short
git commit -m "Move stylesheet into css folder, remove old logo"rm 'old-logo.png'
R style.css -> css/main.css
D old-logo.png
[main 8c41d2e] Move stylesheet into css folder, remove old logo
2 files changed, 1 deletion(-)
rename style.css => css/main.css (100%)
delete mode 100644 old-logo.pngLine-by-line explanation
- Line 1The file is moved and the rename is already staged.
- Line 2The file is deleted and the deletion is staged.
- Line 3--short gives a compact status: R for renamed, D for deleted.
- Line 4The commit shows the rename was 100% similar, so Git kept the file's history connected.
Stop tracking a file you committed by mistake
git rm --cached .env
echo ".env" >> .gitignore
git add .gitignore
git commit -m "Stop tracking .env"
git status --short
ls -arm '.env'
[main 3b7e9f1] Stop tracking .env
2 files changed, 1 insertion(+), 1 deletion(-)
delete mode 100644 .env
create mode 100644 .gitignore
. .. .env .git .gitignore css index.htmlLine-by-line explanation
- Line 1Remove .env from Git's tracking, but not from your folder.
- Lines 2 to 3Ignore it from now on, and commit the .gitignore change.
- Line 5The status is clean: .env is now ignored, not untracked.
- Line 6The file is still on disk. If it contained real secrets, change them: they're still in older commits.
Previewing and cleaning untracked files
git status --short
git clean -nd
git clean -fd
git status --short?? build/
?? debug.log
Would remove build/
Would remove debug.log
Removing build/
Removing debug.logLine-by-line explanation
- Line 1Two untracked items: a build folder and a log file.
- Line 2-n means dry run, and -d includes folders. Nothing is deleted yet.
- Line 3-f actually deletes them. This can't be undone, because Git never had copies.
- Line 4The final status is empty: the working tree is clean.
Common Git Files Mistakes
Expecting .gitignore to untrack a committed file
echo "config.local.php" >> .gitignore
git commit -am "Ignore local config" # file is still trackedgit rm --cached config.local.php
echo "config.local.php" >> .gitignore
git add .gitignore
git commit -m "Stop tracking local config"git rm when you meant --cached
git rm .env # deletes your only copy of the filegit rm --cached .env # keeps the file on diskCleaning without a preview
git clean -fdx # also deletes ignored files like .env and node_modulesgit clean -nd # look first
git clean -fd # then delete only untracked files and foldersGit Files in Real Projects
Managing files in practice
Teams reorganise folders with git mv so pull requests show clean renames, newcomers run git rm --cached after committing editor folders like .vscode, and build scripts use git clean -fdx to start completely fresh.
Git Files FAQ
Does Git track file renames?
Git doesn't store renames as such. It stores snapshots and works out renames afterwards by comparing content: a file deleted in one place and a very similar file added elsewhere is shown as a rename. That's why renaming with your file manager and then running git add -A gives the same result as git mv.
How do I keep an empty folder in Git?
Git tracks files, not folders, so an empty folder never appears in a commit. The usual workaround is to put a placeholder file inside, often named .gitkeep, and commit that. The name is only a convention; Git gives it no special meaning.
How do I change only the capitalisation of a file name?
On Windows and macOS the file system usually treats readme.md and README.md as the same name, so a plain rename may not be noticed. The reliable way is two steps: git mv readme.md temp.md and then git mv temp.md README.md, followed by a commit.
How do I get back a file I deleted with git rm?
If you haven't committed yet, run git restore --staged notes.txt and then git restore notes.txt to bring it back. If the deletion is already committed, restore the version from the commit before it: git restore --source=HEAD~1 notes.txt, then git add and commit it again.
What is the difference between git clean -x and git clean -X?
Lower-case -x removes untracked files including ignored ones, such as build output and node_modules. Upper-case -X removes only ignored files and leaves your other untracked files alone. Either can delete a lot, so preview with -n first.
Git Files Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Complete the command that renames a file and stages the change.
git about.htm about.html
What does git rm --cached secrets.txt do?
Which command shows what git clean would delete, without deleting anything?
What does git status --short show after git mv a.txt b.txt?
Why can't files removed by git clean -f be recovered with Git?
Git Files Quiz
5 questions to check what you learned.
Which command lists every file Git is tracking?
- git status
- git log --files
- git ls-files
- git show files
After deleting a file in your file explorer, how do you stage the deletion?
- You can't
- git add with the file name, or git add -A
- git restore
- git clean
What does
.gitattributeswith* text=auto eol=lfhelp with?- Ignoring files
- Making files read-only
- Keeping line endings consistent between Windows, macOS and Linux
- Compressing files
Does deleting a committed file with git rm remove it from history?
- No, earlier commits still contain it
- Yes
- Only after pushing
- Only for large files
What extra does
git clean -fdxdelete compared withgit clean -fd?- Tracked files
- The .git folder
- Remote branches
- Ignored files, such as node_modules and .env