Git Community Book
Translations of this material:
- into Russian: Книга Git сообщества. 93% translated in draft. Almost done, let's finish it!
-
Submitted for translation by shergin.com 10.07.2009
Published 2 years, 1 month ago.
Text
## Welcome to Git ##
Welcome to Git - the fast, distributed version control system.
This book is meant to be a starting point for people new to Git to learn it as quickly and easily as possible.
This book will start out by introducing you to the way Git stores data, to give you the context for why it is different than other VCS tools.
This is meant to take you about 20 minutes.
Next we will cover **Basic Git Usage** - the commands you will be using 90% of the time. These should give you a good basis to use Git comfortably for mostof what you're going to use it for. This section should take you about 30 minutes to read through.
Next we will go over **Intermediate Git Usage** - things that are slightly morecomplex, but may replace some of the basic commands you learned in the first section. This will mostly be tricks and commands that will feel more comfortable after you know the basic commands.
After you have all of that mastered, we will cover **Advanced Git** - commandsthat most people probably don't use very often, but can be very helpful incertain situations. Learning these commands should round out your day-to-daygit knowledge; you will be a master of the Git!
Now that you know Git, we will then cover **Working with Git**. Here we will goover how to use Git in scripts, with deployment tools, with editors and more.
These sections are meant to help you integrate Git into your environment.
Lastly, we will have a series of articles on **low-level documentation** that mayhelp the Git hackers who want to learn how the actual internals and protocols work in Git.
### Feedback and Contributing ###
At any point, if you see a mistake or want to contribute to the book, you can send me an email at [schacon@gmail.com](mailto:schacon@gmail.com), or you can clone the source of this book at
[http://github.com/schacon/gitbook](http://github.com/schacon/gitbook)
and send me a patch or a pull-request.
### References ###
Much of this book is pulled together from different sources and then added to.
If you would like to read some of the original articles or resources, please
visit them and thank the authors:
* [Git User Manual](http://www.kernel.org/pub/software/scm/git/docs/user-manual.html)
* [The Git Tutorial](http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html)
* [The Git Tutorial pt 2](http://www.kernel.org/pub/software/scm/git/docs/gittutorial-2.html)
* ["My Git Workflow" blog post](http://osteele.com/archives/2008/05/my-git-workflow)
#Introduction
## The Git Object Model ##
### The SHA ###
All the information needed to represent the history of a project is stored in files referenced by a 40-digit "object name" that looks something like this:
6ff87c4664981e4397625791c8ea3bbb5f2279a3
You will see these 40-character strings all over the place in Git.
In each case the name is calculated by taking the SHA1 hash of the contents of the object. The SHA1 hash is a cryptographic hash function.
What that means to us is that it is virtually impossible to find two different objects with the same name. This has a number of advantages; among others:
- Git can quickly determine whether two objects are identical or not,
just by comparing names.
- Since object names are computed the same way in every repository, the
same content stored in two repositories will always be stored under
the same name.
- Git can detect errors when it reads an object, by checking that the
object's name is still the SHA1 hash of its contents.
### The Objects ###
Every object consists of three things - a **type**, a **size** and **content**.
The _size_ is simply the size of the contents, the contents depend on what
type of object it is, and there are four different types of objects:
"blob", "tree", "commit", and "tag".
- A **"blob"** is used to store file data - it is generally a file.
- A **"tree"** is basically like a directory - it references a bunch of
other trees and/or blobs (i.e. files and sub-directories)
- A **"commit"** points to a single tree, marking it as what the project
looked like at a certain point in time. It contains meta-information
about that point in time, such as a timestamp, the author of the changes
since the last commit, a pointer to the previous commit(s), etc.
- A **"tag"** is a way to mark a specific commit as special in some way. It
is normally used to tag certain commits as specific releases or something
along those lines.
Almost all of Git is built around manipulating this simple structure of four
different object types. It is sort of its own little filesystem that sits
on top of your machine's filesystem.
### Different from SVN ###
It is important to note that this is very different from most SCM systems
that you may be familiar with. Subversion, CVS, Perforce, Mercurial and the
like all use _Delta Storage_ systems - they store the differences between one
commit and the next. Git does not do this - it stores a snapshot of what all
the files in your project look like in this tree structure each time you
commit. This is a very important concept to understand when using Git.
### Blob Object ###
A blob generally stores the contents of a file.
[fig:object-blob]
You can use linkgit:git-show[1] to examine the contents of any blob.
Assuming we have the SHA for a blob, we can examine its contents like this:
$ git show 6ff87c4664
Note that the only valid version of the GPL as far as this project
is concerned is _this_ particular version of the license (ie v2, not
v2.2 or v3.x or whatever), unless explicitly otherwise stated.
...
A "blob" object is nothing but a chunk of binary data. It doesn't refer
to anything else or have attributes of any kind, not even a file name.
Since the blob is entirely defined by its data, if two files in a
directory tree (or in multiple different versions of the repository)
have the same contents, they will share the same blob object. The object
is totally independent of its location in the directory tree, and
renaming a file does not change the object that file is associated with.
### Tree Object ###
A tree is a simple object that has a bunch of pointers to blobs and other
trees - it generally represents the contents of a directory or subdirectory.
[fig:object-tree]
The ever-versatile linkgit:git-show[1] command can also be used to
examine tree objects, but linkgit:git-ls-tree[1] will give you more
details. Assuming we have the SHA for a tree, we can examine it like this:
$ git ls-tree fb3a8bdd0ce
100644 blob 63c918c667fa005ff12ad89437f2fdc80926e21c .gitignore
100644 blob 5529b198e8d14decbe4ad99db3f7fb632de0439d .mailmap
100644 blob 6ff87c4664981e4397625791c8ea3bbb5f2279a3 COPYING
040000 tree 2fb783e477100ce076f6bf57e4a6f026013dc745 Documentation
100755 blob 3c0032cec592a765692234f1cba47dfdcc3a9200 GIT-VERSION-GEN
100644 blob 289b046a443c0647624607d471289b2c7dcd470b INSTALL
100644 blob 4eb463797adc693dc168b926b6932ff53f17d0b1 Makefile
100644 blob 548142c327a6790ff8821d67c2ee1eff7a656b52 README
...
As you can see, a tree object contains a list of entries, each with a
License: GPL
