Suppose I have tracked file empty.txt.
Now I remove file from working directory using rm empty.txt .
Now I am removing file from index using git rm empty.txt and now file should be untracked since I have removed it from index.
After this I used git commit -a -m "remove empty.txt" but how it is working as -a parameter is used to skip explicitly adding tracked file to staging area but I already removed file from index?
It should be untracked.
how can git commit -a work after i remove a file from index
276 Views Asked by Akshay Malik AtThere are 2 best solutions below
On
Initially I thought the docs were pretty clear about this, but after testing there is a bit of a weird case here...
So for the most part, the -a flag is going to skip the index and apply the changes from your worktree. Deleting a file is a change. My reading of the (perhaps ambiguous) docs would suggest that the index would be basically ignored, except that new files wouldn't be added.
There's some weirdness in the case where a file in the previous commit is removed from the stage, though. What my tests show is, in this case the file is removed from the new commit based on being removed from the index; and then any further changes in the work tree (i.e. if the file was recreated) are ignored. In that sense, what OP observed is consistent - it's just hard to get that out of a reading of the docs.
It is too bad, because it ruins a bunch of seemingly-true simple statements that would describe the behavior; but here it is:
git init
touch file1
git add .
git commit -m "initial commit"
echo CHANGES > file1
git rm --cached file1
git status
# this will show a staged change to remove the file, and an untracked file
# with the CHANGES
git commit -a -mtest
...and now the commit has an empty directory, and file1 is untracked. And with that in mind, the case in the question is just the degenerate case where the change in the worktree is the same as the change in the index.
You have two possible misconceptions:
This has nothing to do with "tracking".
A git commit is not about changes. It is a snapshot, a photograph, of your entire set of files, as reflected in the index, which is itself a complete copy of your entire set of files.
If you take a photograph of a dog standing among two trees, the photograph contains a dog and two trees. That is a commit.
If the dog walks away and you take another photograph, the photograph contains the two trees but not the dog. It wasn't there when you took that photograph. That is another commit.
There is no "removal" action involved in the creation of the second commit. It isn't a modification of the first photograph. It's just a photograph of what is.
In the case of a git commit that you create, "what is" is the index, plain and simple (by default; there are ways around this, by saying
git commit someFile, but ignore that for our purposes).Okay, so, on to the details of your question. You say:
So:
If you remove a file from the working tree,
git commit -aautomatically removes that file from the index as well (as if by callinggit rm --cached) before making the commit. The file is now not in the index and therefore the commit created from it is missing that file (just like the dog).In your case, you yourself removed the file from both the working tree and the index. So now the
-apart ofgit commit -ahas no work to do with regard to the index as far as this file is concerned; you already did that work. And now very same operation occurs: the file is now not in the index and therefore the commit created from it is missing that file (just like the dog).