When you run git diff or git diff <some commit> you're implicitly diffing the current state of the repo (whether staged or unstaged) implicitly against HEAD implicitly in the first case or whatever commit is specified in the latter case.
My question is: how do I explicitly refer to the current state of the repo?
Ideally, I'd like to be calling something like git diff CURRENT_STATE HEAD.
how do I explicitly refer to the current state of the [work tree]?
git diff is already an explicit reference to that, Git compares against the current state of the work tree unless you override it and tell it to compare against content somewhere else instead, but if you're after a further override like --no-cached to override any earlier --cached override, that, git diff doesn't have at the moment, you'll have to write a little options preprocessor to strip out anything you don't like rather than just tacking the override on the end.
edit:
Ideally, I'd like to be calling something like
git diff CURRENT_STATE HEAD
You can get this effect with -R, a reverse diff that swaps the usual order. You'd do that specific diff with just git diff -R HEAD (I much prefer the @ synonym for HEAD, git diff -R @).
jthill's answer is fine; I just want to address this comment directly, with much more detail and formatting than will fit into a comment:
Basically, I'm asking: Does the uncommitted state of the repo explicitly have its own ref?
The short answer is "no".
A ref, like HEAD or master or (fully spelled out) refs/heads/master, ultimately resolves to a hash ID.1 If it's a branch name or remote-tracking name, it resolves specifically to a commit hash ID; if it's a tag name, it may resolve to any of Git's four internal object types: commit, tree, blob, or (annotated) tag.
A tree object is the closest thing you can get to the work-tree, but it's not the work-tree at all. In fact, there are two uncommitted representations, in a normal Git repository, that you cannot refer to by name. One of these is the stuff that is in the index—essentially, the proposed next commit—and the other is the stuff in the work-tree.
If the index is in a good state,2 you can run git write-tree. The result is a hash ID. This is not a reference name at all, it's just a hash ID, but a hash ID is usually just as good. So if you'd like some Git command to take notice of the proposed next commit, you can run git write-tree to write it to a tree object, and then use the resulting hash ID.
The work-tree, however, isn't at all suitable for this. To turn the work-tree into a hash ID, you need to write it to the—or at least an—index and then run git write-tree. You can use the environment variable GIT_INDEX_FILE to name a temporary file that will hold a temporary index.
The git diff and git status commands have built-in tricks to use the index and work-tree as if they were commits, but most other Git commands don't.
1If the ref is symbolic—as HEAD usually is—it just contains the name of another ref. If that other ref doesn't actually exist, the symbolic ref won't resolve to a hash ID at all, and git rev-parse will fail on it, but git symbolic-ref will let you examine the target.
2The index can be in the merge conflict state, in which it can't be converted into a tree object. In this case git write-tree just errors out. Unfortunately, there is no good way to deal with this other than just to resolve the merge conflicts. I say "unfortunately" because it would sometimes be very handy to stash (as if by git stash or some such) the conflicted state for safekeeping and/or transport, and the way Git is today, that's simply not possible. You can get pretty close, using git ls-files --stage to translate the index into text and git update-index to invert that, but protecting temporary blob hashes from GC is a problem.
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