Home Explore Blog CI



git

5th chunk of `Documentation/gitcore-tutorial.adoc`
6ca05185fbbe8e7c134fef00ded2543f3d07dbd3b661d0e40000000100000fa6
 but to just pass its result in as an
argument to 'git commit-tree'.

'git commit-tree' normally takes several arguments -- it wants to know
what the 'parent' of a commit was, but since this is the first commit
ever in this new repository, and it has no parents, we only need to pass in
the object name of the tree. However, 'git commit-tree' also wants to get a
commit message on its standard input, and it will write out the resulting
object name for the commit to its standard output.

And this is where we create the `.git/refs/heads/master` file
which is pointed at by `HEAD`. This file is supposed to contain
the reference to the top-of-tree of the master branch, and since
that's exactly what 'git commit-tree' spits out, we can do this
all with a sequence of simple shell commands:

------------------------------------------------
$ tree=$(git write-tree)
$ commit=$(echo 'Initial commit' | git commit-tree $tree)
$ git update-ref HEAD $commit
------------------------------------------------

In this case this creates a totally new commit that is not related to
anything else. Normally you do this only *once* for a project ever, and
all later commits will be parented on top of an earlier commit.

Again, normally you'd never actually do this by hand. There is a
helpful script called `git commit` that will do all of this for you. So
you could have just written `git commit`
instead, and it would have done the above magic scripting for you.


Making a change
---------------

Remember how we did the 'git update-index' on file `hello` and then we
changed `hello` afterward, and could compare the new state of `hello` with the
state we saved in the index file?

Further, remember how I said that 'git write-tree' writes the contents
of the *index* file to the tree, and thus what we just committed was in
fact the *original* contents of the file `hello`, not the new ones. We did
that on purpose, to show the difference between the index state, and the
state in the working tree, and how they don't have to match, even
when we commit things.

As before, if we do `git diff-files -p` in our git-tutorial project,
we'll still see the same difference we saw last time: the index file
hasn't changed by the act of committing anything. However, now that we
have committed something, we can also learn to use a new command:
'git diff-index'.

Unlike 'git diff-files', which showed the difference between the index
file and the working tree, 'git diff-index' shows the differences
between a committed *tree* and either the index file or the working
tree. In other words, 'git diff-index' wants a tree to be diffed
against, and before we did the commit, we couldn't do that, because we
didn't have anything to diff against.

But now we can do

----------------
$ git diff-index -p HEAD
----------------

(where `-p` has the same meaning as it did in 'git diff-files'), and it
will show us the same difference, but for a totally different reason.
Now we're comparing the working tree not against the index file,
but against the tree we just wrote. It just so happens that those two
are obviously the same, so we get the same result.

Again, because this is a common operation, you can also just shorthand
it with

----------------
$ git diff HEAD
----------------

which ends up doing the above for you.

In other words, 'git diff-index' normally compares a tree against the
working tree, but when given the `--cached` flag, it is told to
instead compare against just the index cache contents, and ignore the
current working tree state entirely. Since we just wrote the index
file to HEAD, doing `git diff-index --cached -p HEAD` should thus return
an empty set of differences, and that's exactly what it does.

[NOTE]
================
'git diff-index' really always uses the index for its
comparisons, and saying that it compares a tree against the working
tree is thus not strictly accurate. In particular, the list of
files to compare (the "meta-data") *always* comes from the index file,
regardless

Title: Git Committing and Diffing
Summary
This section explains how to create a new commit in Git using `git write-tree` and `git commit-tree`, and how to use `git diff-index` and `git diff` to compare the working tree, index, and committed trees, including how to show differences between the index and working tree, and between a committed tree and either the index or working tree.