I would like to understand what Git actually is storing when moving files into the “staging” state.
Consider the following sequence:
A new file is added and committed to the local repository:
touch file.txt
git add file.txt
git commit
I make changes to the file:
echo text1 > file.txt
git add file.txt
I then edit the file again, before committing it:
echo text2 > file.txt
A git status shows:
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: file.txt
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: file.txt
#
I then commit the file:
git commit file.txt
How is git able to handle staging the new, second update to file.txt without being told to? The “status” output looks as if it would try to check the first revision in, but withhold the unstaged changes without checking them in.
Is there an implicit stage that is done in this case?
Think of Git as two things – commits (snapshots of files) and labels (branches, among other things).
Git actually creates a commit when you
git add, not when yougit commit. So when you executedgit addon the changed file, it created a commit with those changes, and assigned the “staging” label to that particular commit.When you changed the file again before executing
git commit, it now has the “staged commit” (that hasn’t hadgit commitexecuted on it yet), and the new changes to the file that has been neither added nor committed. That’s howgit statusis able to show you both.When you
git commit, it is actually moving your current branch label to that particular commit (and removing the “staging” label), so the commit is no longer marked as “staging” but “master” (or whatever branch you’re currently on).