https://www.kernel.org/pub/software/scm/git/docs/gitglossary.html#def_dirty A working tree is said to be "dirty" if it contains modifications which have not been committed to the current branch.
http://www.gitguys.com/topics/glossary/ Dirty working directory If files have been updated in the working directory after they were updated in the index then the working directory is considered “dirty”. The working directory is clean if all modified files in the working directory have been added to the index.
If I understand correctly, the "index" is also known as the "staging area" and is a place where files will be stored (copied to? symlinked?) when you have changed them, want to commit them, but haven't done a commit yet. (The first glossary says the staging area can also be used for merging. The second glossary says files are moved there by 'git add'.)
So the two glossaries seem to be saying incompatible things. Which is correct? Or is there some way they could both be correct?
According to the official Git documentation, in the section on Stashing, a dirty state is defined as ... the dirty state of your working directory — that is, your modified tracked files and staged changes . From this definition, files staged for commit are dirty as well.
It means the same as with a non-submodule: "dirty" means the index differs from HEAD and/or the work-tree differs from the index. Each submodule is its own repository, so to test if a submodule is dirty, "cd" into the submodule and test whether the repository is dirty.
The git status command displays the state of the working directory and the staging area. It lets you see which changes have been staged, which haven't, and which files aren't being tracked by Git. Status output does not show you any information regarding the committed project history.
They're actually both reasonable claims. I think the "best answer" is that both are wrong, although the former (the kernel.org version) is probably closer.
Consider:
$ mkdir /tmp/repo && cd /tmp/repo $ git init Initialized empty Git repository in /tmp/repo/.git/ $ echo contents > file $ git add file $ git commit -m initial [master (root-commit) e1731a6] initial 1 file changed, 1 insertion(+) create mode 100644 file
We now have a repository with one commit containing one file.
$ echo second line >> file; git add file; echo contents > file
At this point, the index has file
with two lines in it. But the work-tree version of file
has just the one line in it, and matches what's in the repository.
Is file
dirty? Well, git status --short
says that it is, twice (two M
s). Both git diff
and git diff --cached
show changes (so yes, it's "dirty"), but git diff HEAD
says there's no change, and if we git add
it again and try git status
:
$ git status --short MM file $ git diff HEAD $ git add file $ git status # On branch master nothing to commit, working directory clean
Let's put that odd change back and do one more thing. This time let's use the long form of git status
so that it gives us more information:
$ echo second line >> file; git add file; echo contents > file $ git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: file # # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: file #
It says we can use git reset
(which is the same as git reset --mixed
) with HEAD
and the file name to un-stage; surely that will make the working directory dirty? :-)
$ git reset HEAD file $ git status # On branch master nothing to commit, working directory clean
No, in fact, it makes the working directory clean again! This follows from the (lack of) output of git diff HEAD
: "un-staging" the change that adds the second line makes the index refer to the HEAD
version, and the working-directory version is the same as the HEAD
version, so un-staging the "changes to be committed" causes there to be nothing to commit and no working-directory changes.
The "right" definition is, I think, that your tree is "clean" if there are no changes to commit and no changes between "tree staged for commit" (contents of index) and "work directory". However, it's reasonable to ask separately whether the index is clean (i.e., there is nothing staged for commit) and/or the work-tree is clean (unchanged) with respect to fill-in-the-blank, where the blank can be filled in with "the staging area" or "the HEAD
commit".
What git status
tells you is both the answer to "what, if anything, is staged for commit" and "what, if anything, is different between the work-tree and the index". You have to use git diff HEAD
(you may want to add --name-only
or similar) to see what, if anything, is different between the work-tree and the HEAD
commit unless (as is often the case) the index matches the HEAD
commit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With