Devasish
Devasish

Reputation: 1957

Why git rm --cached my_dir/* deleting local files?

I want to gitignore a folder which has already been committed to upstream and distributed among all forks. I need those files to be removed only from git versioning not to delete for my file system and to not delete from any forks local file system. Is there anyway for this?

I attempted the following steps:

  1. Added the path to folder in my .gitignore file like my_ignore_folder/*.
  2. Then run command git rm -r --cached my_ignore_folder/*
  3. then git add --all
  4. then git commit -am "ignored folder"
  5. then git push origin my_branch name

After doing the all these things I did ls my_ignore_folder/ and found all the files exists in my file system as it is as expected. Then I switched to a different branch by git checkout another_branch where these files are still not ignored. So ls my_ignore_folder/ displays all files. Then again when I switched back to my earlier branch where those files were just ignored and run ls my_ignore_folder/ then I surprisingly found my_ignore_folder/ is missing. I attempted it number of times but same thing is happening. Can anyone please explain why this happening. Am I doing anything wrong? I expected my ignored files to not get deleted from my local file system. Is there any way by which it can be achieved? Please help.

Upvotes: 3

Views: 286

Answers (1)

torek
torek

Reputation: 488003

As soon as you check out a commit in which the files exist in that commit, Git must remove the ignored files and put in the committed files instead.

As long as the contents match, Git can do that safely enough. But now those files are in Git's index, because extracting any historical commit—just like extracting any branch-tip commit—copies all of those files into Git's index and into your working tree (these are separate copies).

If you now switch away from this historical commit, in which these files are tracked, to a recent commit in which the files do not exist, Git must remove them from Git's index and your working tree as part of the commit-switching, as usual.

So this is perfectly normal, but also terribly annoying. You must now get the content of those files back, while keeping them ignored. Since the content presumably matched the commit you switched to, you can use that commit's (non-ignored) content. To get a file whose path is path/to/file into your working tree, use:

git restore --source <commit-hash-or-branch-name> --worktree path/to/file

for instance, if you have git restore. If your Git predates Git 2.23, so that you do not have git restore, consider using:

git show <commit-hash-or-branch-name>:path/to/file > path/to/file

If you committed a file you should never have committed, the commits that contain that file are a sort of trap for the unwary. It's a good idea not to have committed these files in the past. That may require obtaining a time machine: travel to the past, stop yourself from adding and committing these files, and now you have files that aren't committed. I'm not quite sure what the right verb conjugation is here though.

Upvotes: 2

Related Questions