简体   繁体   中英

Is Git rm necessary to delete a file from the repo?

If I rename or delete a file using local operating system commands or in an IDE, it seemed like Git was aware of this and I was able to commit the delete just as if I had changed the contents of the file but I may have done this wrong. So my question is, after I delete a file locally, what does Git know about this and do I both have to perform the delete using the IDE and do Git rm to get rid of the file from the Git repo?

EDIT: To make more clear the practical situation: Now that I have deleted the file using, in my case, Eclipse (which I would have thought handled the whole git thing transparently) or simply using the Windows command-line, would I still be able to use Git rm? It does not seem to be working.

So I think this is an exercise in understanding the difference between your working directory and the stage in GIT.

Your working directory is what we would think of as your OS directory. You can remove files using OS commands (rm, IDE, etc). GIT is aware of your working directory.

The stage is the "cache" GIT uses to review changes before the final commit. (ex git status screen)

With that being said, performing a git rm will remove the file from the 'working directory' AND the 'stage'.

Performing an OS 'rm' will only remove from the working directory. This will then require you to perform a 'git add .' to update your stage in preparation for the final commit.

Either way is fine but I am curious if there is a "best practice".

I hope this helps!

Have fun,

-Nick

If Git knows about a file, then it will willfully track its deletion. Simply deleting it from Git will allow it to be resurrected at a later date in time.

If you do not wish for Git to know about a file, then using git rm --cached is the appropriate way to remove it from the current stage. You'll need to couple this with an appropriate .gitignore file as well so Git knows never to stage it again.

Well if you have deleted the file with rm command, And you want to remove it from GIT repo. Then you have to use git add ; git commit -m "remove".

But if you will use git rm command, Then git will remove the file and add it to staging, then next time when you will fire git commit. It will be deleted from repo. So you do not need to add it into staging explicitly if you use this command.

There are several somewhat-reasonable answers here but no one has addressed a few key points. I'll put them below the first section marker.

Note that if you want to look at history (ie, at commits) for a file that may appear and disappear over various commits, you often have to tell git log that the file name is a file name, and not anything else:

git log --all --full-history -- path/to/file.java

for instance. The -- separates file path names from other arguments, so Git knows not to attempt to turn path/to/file.java into a revision specifier. (A commit that has the effect of deleting the file will be shown, but you won't necessarily know why . Add --name-status to the git log options to get that information.)

You can't remove a file from a Git repository (well, mostly)

The problem is that the repository doesn't hold files. The repository holds commits .

Now, it's true that commits hold files, but you also can't—well, mostly can't, and generally should not—remove commits. Commits are (mostly) permanent and (entirely) unchangeable. This means that if the file exists in commits c0ffee1 and deadcab , it exists in those two commits forever .

The file may, or may not, exist in other commits. When you make Git check out commit feedb0b , will file x.java exist? The (slightly oversimplified simple) answer is: it will if it's in feedb0b , and not if it's not.

What git rm does is, in part, to remove a file from Git's index , which is also called the staging area . When you make the next commit, whenever that is and whatever big ugly hash ID it gets then, whatever files are in the index right now are the ones that will be in that next commit.

If you remove a file from the work-tree , which is where you do your work, you have not affected your index. Git places this index in between your work-tree and your commits so that it can annoy you. :-) Well, that's not the real reason, but that's the initial effect: the index acts as an annoyance. It's why you must constantly keep running git add : git add x.java copies the file x.java from your work-tree, where you can work on it, into the index, so that it can be in the next commit.

Once copied into the index, a file remains in the index until something takes it out. Using git rm --cached x.java will take x.java out of the index. Using git rm x.java , ie, without --cached , will take it out of the index and remove it from your work-tree. If it's already gone from your work-tree, both commands do the same thing (remove from index only).

Curiously, if you've already removed it from your work-tree, git add x.java will also remove it from your index! This is an odd meaning for "add". Note that in modern Git, "add all files" will "add" removed files this way (in Git before 2.x it did not do this by default).

As long as the file is in your index, though, it will also be in the next commit you make.

Some notes on untracked files

As soon as any particular file is not in your index, it becomes an untracked file. In fact, that's the definition of "untracked file": an untracked file is any file that is not in the index.

Whenever you have untracked files, Git tends to whine at you. It constantly reminds you: hey, this file is untracked, and that one, and these five! You can tell Git to stop complaining by listing these untracked files in a .gitignore file. This does two things:

  • it shuts up the complaints; and
  • it makes Git not add those files if you use an "add all files" operation.

It does not take the files out of the index if they are already there! An ignore entry for a file is only meaningful if the file is currently untracked.

Since the index changes over time, doing git rm <file> and committing makes the file untracked, but as soon as you check out one of the older commits that has the file in it, the file comes back into both your index and your work-tree. The file is now tracked again. So "tracked" or "untracked" is always a question of whether the file is in your index right now . That's not something you can answer once and forever.

This, too, is part of why you can't quite remove a file from the repository . You can remove it from the next commit , and anyone who works from that commit will not have the file. But anyone who works from some other commit, might have the file.

(You can strip out commits, but it's tricky.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM