Путеводитель по Руководству Linux

  User  |  Syst  |  Libr  |  Device  |  Files  |  Other  |  Admin  |  Head  |



   gitcore-tutorial    ( 7 )

основное руководство Git для разработчиков (A Git core tutorial for developers)

COMMITTING GIT STATE

Now, we want to go to the next stage in Git, which is to take the files that Git knows about in the index, and commit them as a real tree. We do that in two phases: creating a tree object, and committing that tree object as a commit object together with an explanation of what the tree was all about, along with information of how we came to that state.

Creating a tree object is trivial, and is done with git write-tree. There are no options or other input: git write-tree will take the current index state, and write an object that describes that whole index. In other words, we're now tying together all the different filenames with their contents (and their permissions), and we're creating the equivalent of a Git "directory" object:

$ git write-tree

and this will just output the name of the resulting tree, in this case (if you have done exactly as I've described) it should be

8988da15d077d4829fc51d8544c097def6644dbb

which is another incomprehensible object name. Again, if you want to, you can use git cat-file -t 8988d... to see that this time the object is not a "blob" object, but a "tree" object (you can also use git cat-file to actually output the raw object contents, but you'll see mainly a binary mess, so that's less interesting).

However — normally you'd never use git write-tree on its own, because normally you always commit a tree into a commit object using the git commit-tree command. In fact, it's easier to not actually use git write-tree on its own at all, 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.