In a previous article we reviewed the concepts of adding, committing and pushing changes to a git repository. The first time you look at the workflow it can look like a process you only use for advancing, for adding information, for making a project grow and move forward. But you will also need to delete old unnecessary files from time to time.

Let’s see how it works with an example. This is the directory tree of my repository:

├── newfile2.txt
├── newfile.txt

If I check the status of my repository, I can see there are no changes to be committed or untracked files:

$ git status
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

Let’s assume I needed, for any reason, to delete newfile2.txt. I’ll delete it, and check the status of the repository after that.

$ rm newfile2.txt 
$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	deleted:    newfile2.txt

no changes added to commit (use "git add" and/or "git commit -a")

The deletion of the file is registered as a “change not staged for commit”. It is essentially, the same as any other change (the same as adding a new file or modifying the content of a file). Therefore, to succeed in deleting the file, we need to add it, commit it, and push it.

I remember this was something confusing for me the first time I used git. Now that I’ve used it for a while I think it makes complete sense. But I think it is normal to find it strange the first time because it is like if you need “to move forward, so you can move backwards” if that makes sense.

I will do the steps checking the status at each point so it is clear. First, we add the deletion:

$ git add .
$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	deleted:    newfile2.txt

Now we need to commit it, together with a commit message:

$ git commit -m "delete newfile2.txt"
[main 7e4a4e7] delete newfile2.txt
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 newfile2.txt

If I check the status, we are ready to push to the remote repository:

$ 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

Let’s now push the commit:

$ git push origin main
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 12 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 215 bytes | 215.00 KiB/s, done.
Total 2 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
   dd95bff..7e4a4e7  main -> main

Done. The file has been deleted and the result is reflected in the GitHub web app (you can see how my repository looked after pushing here).

Deleting files isn’t something you have to do separate from file creation or updates. You can add the deletion of many files together with some file creations or updates, all with git add .. This article’s objective was to allow you to stop for a second and embrace that deleting files is the same as the other changes, even if it can be perceived as different.