How to stop tracking a file in Git without deleting it?
You added a file to Git, but now you want to stop tracking it. You don't want to delete it, you just want to stop tracking it. How do you do that?
Setup
Let’s say you have a process called doit.sh
that, when run, creates a log file.
alina
alina git:( main ) ./doit.sh
alina git:( main ) cat doit.log
Wed May 31 07:36:20 PDT 2023
alina git:( main ) █
You are satisfied with the process, so you decide to add it to Git.
alina
alina git:( main ) git add -A
alina git:( main ) git commit -m 'add doit process'
[main e423685] add doit process
2 files changed, 4 insertions(+)
create mode 100644 doit.log
create mode 100755 doit.sh
alina git:( main ) █
Your working directory is currently clean.
alina
alina git:( main ) git status
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
alina git:( main ) █
You decide to run the process again.
alina
alina git:( main ) ./doit.sh
alina git:( main ) █
However, you realize that you do not want to track the log file.
alina
alina git:( main ) git status
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
(use "git push" to publish your local commits)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: doit.log
no changes added to commit (use "git add" and/or "git commit -a")
alina git:( main ) █
Your initial instinct may be to use git rm doit.log
, but that would delete the file. This is not what you want if you wish to preserve the file. Instead, you simply want to stop tracking it.
Solution
The first step is to add the file to the .gitignore
file.
alina
alina git:( main ) echo "doit.log" >> .gitignore
alina git:( main ) git add .gitignore
alina git:( main ) git commit -m 'ignore doit.log'
[main da7e3d5] ignore doit.log
1 file changed, 1 insertion(+)
create mode 100644 .gitignore
alina git:( main ) █
However, simply adding the file to .gitignore
is not enough as it will still be tracked:
alina
alina git:( main ) git status
On branch main
Your branch is ahead of 'origin/main' by 2 commits.
(use "git push" to publish your local commits)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: doit.log
no changes added to commit (use "git add" and/or "git commit -a")
alina git:( main ) █
Although the .gitignore
file prevents the file from being added to the index in the future, it does not remove it from the index.
The solution is to use git rm --cached doit.log
. This command will remove the file from the index, while keeping it in your working directory.
alina
alina git:( main ) git rm --cached doit.log
rm 'doit.log'
alina git:( main ) █
When you check the git status
command now, you will see that the file has been removed from the index.
alina
alina git:( main ) git status
On branch main
Your branch is ahead of 'origin/main' by 2 commits.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: doit.log
alina git:( main ) █
However, the file remains intact in your working directory.
alina
alina git:( main ) cat doit.log
Wed May 31 07:36:20 PDT 2023
Wed May 31 07:36:29 PDT 2023
Wed May 31 07:36:55 PDT 2023
alina git:( main ) █
Now it’s time to commit your changes.
alina
alina git:( main ) git commit -m 'remove doit.log from staging area'
[main 00c28d8] remove doit.log from staging area
1 file changed, 2 deletions(-)
delete mode 100644 doit.log
alina git:( main ) █
Once again, your working directory is clean.
alina
alina git:( main ) git status
On branch main
Your branch is ahead of 'origin/main' by 3 commits.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
alina git:( main ) █
If you were to run the process again, the log file would be updated but it would not be tracked by Git.
alina
alina git:( main ) ./doit.sh
alina git:( main ) git status
On branch main
Your branch is ahead of 'origin/main' by 3 commits.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
alina git:( main ) cat doit.log
Wed May 31 07:36:20 PDT 2023
Wed May 31 07:36:29 PDT 2023
Wed May 31 07:36:55 PDT 2023
Wed May 31 07:38:39 PDT 2023
alina git:( main ) █