Skip to content

Commit

Permalink
Merge commit 'cok/book' into book
Browse files Browse the repository at this point in the history
  • Loading branch information
schacon committed Sep 2, 2008
2 parents a5f85ba + ca28040 commit 63df61a
Show file tree
Hide file tree
Showing 14 changed files with 115 additions and 113 deletions.
6 changes: 3 additions & 3 deletions text/01_Introduction/0_ Introduction.markdown
Expand Up @@ -18,16 +18,16 @@ minutes to read through.
Next we will go over **Intermediate Git Usage** - things that are slightly more
complex, 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
comforatble after you know the basic commands.
comfortable after you know the basic commands.

After you have all of that mastered, we will cover **Advanced Git** - commands
that most people probably don't use very often, but can be very helpful in
certain situations. Learning these commands should round out your day-to-day
git knowledge, you will be a master of the Git.
git knowledge; you will be a master of the Git!

Now that you know Git, we will then cover **Working with Git**. Here we will go
over how to use Git in scripts, with deployment tools, with editors and more.
These sections are meant to help you integrate Git into your environement.
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 may
help the Git hackers who want to learn how the actual internals and protocols
Expand Down
18 changes: 9 additions & 9 deletions text/02_Git_Object_Db_Basics/0_ Git_Object_Db_Basics.markdown
Expand Up @@ -11,7 +11,7 @@ looks something like this:
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 impossible to find two different
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:

Expand All @@ -32,7 +32,7 @@ type of object it is, and there are four different types of objects:

- 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 (ie. files and sub-directories)
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
Expand All @@ -42,14 +42,14 @@ type of object it is, and there are four different types of objects:
along those lines.

Almost all of Git is built around manipulating this simple structure of four
different object types. It is sort of it's own little filesystem that sits
on top of your filesystem.
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 are probably used to. 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 each time you commit in this tree structure. This
is a very important concept to understand when using Git.
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.
21 changes: 10 additions & 11 deletions text/02_Git_Object_Db_Basics/1_Trees_and_Blobs.markdown
Expand Up @@ -5,7 +5,7 @@ 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 a SHA for a blob, we can examine its contents like this:
Assuming we have the SHA for a blob, we can examine its contents like this:

$ git show 6ff87c4664

Expand All @@ -14,7 +14,7 @@ Assuming we have a SHA for a blob, we can examine its contents like this:
v2.2 or v3.x or whatever), unless explicitly otherwise stated.
...

A "blob" object is nothing but a binary blob of data. It doesn't refer
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
Expand All @@ -32,7 +32,7 @@ trees - it generally represents the contents of a directory or subdirectory.

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 a SHA for a tree, we can examine it like this:
details. Assuming we have the SHA for a tree, we can examine it like this:

$ git ls-tree fb3a8bdd0ce
100644 blob 63c918c667fa005ff12ad89437f2fdc80926e21c .gitignore
Expand All @@ -49,14 +49,13 @@ As you can see, a tree object contains a list of entries, each with a
mode, object type, SHA1 name, and name, sorted by name. It represents
the contents of a single directory tree.

The object type may be a blob, representing the contents of a file, or
another tree, representing the contents of a subdirectory. Since trees
and blobs, like all other objects, are named by the SHA1 hash of their
contents, two trees have the same SHA1 name if and only if their
contents (including, recursively, the contents of all subdirectories)
are identical. This allows git to quickly determine the differences
between two related tree objects, since it can ignore any entries with
identical object names.
An object referenced by a tree may be blob, representing the contents of a
file, or another tree, representing the contents of a subdirectory. Since
trees and blobs, like all other objects, are named by the SHA1 hash of their
contents, two trees have the same SHA1 name if and only if their contents
(including, recursively, the contents of all subdirectories) are identical.
This allows git to quickly determine the differences between two related tree
objects, since it can ignore any entries with identical object names.

(Note: in the presence of submodules, trees may also have commits as
entries. See the **Submodules** section.)
Expand Down
8 changes: 4 additions & 4 deletions text/02_Git_Object_Db_Basics/2_Commits.markdown
Expand Up @@ -34,9 +34,9 @@ As you can see, a commit is defined by:
- an **author**: The name of the person responsible for this change, together
with its date.
- a **committer**: The name of the person who actually created the commit,
with the date it was done. This may be different from the author, for
example, if the author was someone who wrote a patch and emailed it
to the person who used it to create the commit.
with the date it was done. This may be different from the author; for
example, if the author wrote a patch and emailed it to another person who
used the patch to create the commit.
- a **comment** describing this commit.

Note that a commit does not itself contain any information about what
Expand All @@ -53,7 +53,7 @@ taken from the content currently stored in the index.

### The Object Model ###

So, now that we've looked at the 3 main object types (the blob, tree and commit),
So, now that we've looked at the 3 main object types (blob, tree and commit),
let's take a quick look at how they all fit together.

If we had a simple project with the following directory structure:
Expand Down
7 changes: 4 additions & 3 deletions text/02_Git_Object_Db_Basics/3_Trust_and_Tags.markdown
Expand Up @@ -3,9 +3,10 @@

[fig:object-tag]

A tag object contains an object, object type, tag name, the name of the
person ("tagger") who created the tag, and a message, which may contain
a signature, as can be seen using linkgit:git-cat-file[1]:
A tag object contains an object name (called simply 'object'), object type,
tag name, the name of the person ("tagger") who created the tag, and a
message, which may contain a signature, as can be seen using
linkgit:git-cat-file[1]:

$ git cat-file tag v1.5.0
object 437b1b20df4b356c9342dac8d38849f24ef44f27
Expand Down
Expand Up @@ -2,14 +2,14 @@

### The Git Directory ###

The 'git directory' is the directory that stores all the Git meta information
about your project - including all of the objects (commits, trees, blobs, tags),
all of the pointers to where different branches are and more.
The 'git directory' is the directory that stores all Git's history and meta
information for your project - including all of the objects (commits, trees,
blobs, tags), all of the pointers to where different branches are and more.

There is only one Git Directory per project (as opposed to one per subdirectory like SVN or CVS),
and that directory is (by default, though not neccesarily) found in the '.git'
directory in the root of your project. If you look at the contents of that
directory, you can see all of our important files:
There is only one Git Directory per project (as opposed to one per
subdirectory like with SVN or CVS), and that directory is (by default, though
not necessarily) '.git' in the root of your project. If you look at the
contents of that directory, you can see all of your important files:

$>tree -L 1
.
Expand All @@ -29,6 +29,6 @@ directory, you can see all of our important files:
The Git 'working directory' is the directory that holds the current checkout
of the files you are working on. Files in this directory are often removed
or replaced by Git as you switch branches - this is normal. All your history
is stored in the Git Directory, the working directory is simply a temporary
is stored in the Git Directory; the working directory is simply a temporary
checkout place where you can modify the files until your next commit.

12 changes: 6 additions & 6 deletions text/03_The_Git_Index/0_ The_Git_Index.markdown
Expand Up @@ -2,15 +2,15 @@

The Git index is used as a staging area between your working directory
and your repository. You can use the index to build up a set of changes
that you want to commit together relatively easily. When you create a commit,
what is committed is what is currently in the index, not what is in your working
directory.
that you want to commit together. When you create a commit, what is committed
is what is currently in the index, not what is in your working directory.

### Looking at the Index ###

The easiest way to see what is in the index is with the linkgit:git-status[1]
command. When you run the status, you can see what files are staged (currently in your index),
which are modified but not yet staged, and which are completely untracked.
command. When you run git status, you can see which files are staged
(currently in your index), which are modified but not yet staged, and which
are completely untracked.

$>git status
# On branch master
Expand Down Expand Up @@ -40,5 +40,5 @@ information as long as you have the name of the tree that it described.
And with that, you should have a pretty good understanding of the basics of
what Git is doing behind the scenes, and why it is a bit different than most
other SCM systems. Don't worry if you don't totally understand it all right
now, we'll revisit all of these topics in the next sections. Now we're ready
now; we'll revisit all of these topics in the next sections. Now we're ready
to move on to installing, configuring and using Git.
7 changes: 4 additions & 3 deletions text/05_Installing_Git/3_Mac_105.markdown
@@ -1,8 +1,9 @@
### Mac 10.5 ###

With Leopard, you can also install via MacPorts, but you also have the option of
using a nice installer, which you can download from here :
[Git OSX Installer](http://code.google.com/p/git-osx-installer/downloads/list?can=3)
With Leopard, you can also install via MacPorts, but here you have the
additional option of using a nice installer, which you can download from here:
[Git OSX
Installer](http://code.google.com/p/git-osx-installer/downloads/list?can=3)

If you prefer to install it from source, these guides may be particularly helpful to you :

Expand Down
18 changes: 10 additions & 8 deletions text/06_Setup_and_Initialization/1_Git_Config.markdown
@@ -1,19 +1,21 @@
### Git Config ###

The first thing you're going to want to do is to setup your name and
email address for Git to use to sign your commits.
The first thing you're going to want to do is set up your name and email
address for Git to use to sign your commits.

$ git config --global user.name "Scott Chacon"
$ git config --global user.email "schacon@gmail.com"

That will setup a file in your home directory that stores your name and email
in any Git project where it's not overridden. By default that file is *~/.gitconfig*
and the contents will then look like this:
That will set up a file in your home directory which may be used by any of
your projects. By default that file is *~/.gitconfig* and the contents will
look like this:

[user]
name = Scott Chacon
email = schacon@gmail.com
If you want to override those values for a specific project (change to using a
work email address, for example), you can run the *git config* command without
the *--global* option while in that project.
If you want to override those values for a specific project (to use a work
email address, for example), you can run the *git config* command without the
*--global* option while in that project. This will add a [user] section like
the one shown above to the *.git/config* file in your project's root
directory.
41 changes: 21 additions & 20 deletions text/06a_Getting_A_Repo/1_Getting_a_Git_Repo.markdown
@@ -1,40 +1,41 @@
## Getting a Git Repository ##

So now that we're all setup, we need a Git repository. We can do this one of
So now that we're all set up, we need a Git repository. We can do this one of
two ways - we can *clone* one that already exists, or we can *initialize* one
either from existing files that aren't in source control yet, or just create
a new project.
either from existing files that aren't in source control yet, or from an empty
directory.

### Cloning a Repository ###

In order to get a copy of a project, you will need to know the projects Git
URL - the location of the repository. Git can operate over many different
protocols, so it may begin with ssh://, http(s):// or git://, or just a username,
in which case it will assume ssh. Some repositories have more than one way to
clone it. For example, the source code to Git itself can be cloned either through
the git:// protocol:
In order to get a copy of a project, you will need to know the project's Git
URL - the location of the repository. Git can operate over many different
protocols, so it may begin with ssh://, http(s)://, git://, or just a username
(in which case git will assume ssh). Some repositories may be accessed over
more than one protocol. For example, the source code to Git itself can be
cloned either over the git:// protocol:

git clone git://git.kernel.org/pub/scm/git/git.git

or over http:

git clone http://www.kernel.org/pub/scm/git/git.git

The git:// protocol is faster and more efficient, but sometimes it is necessary
to use the simpler http based one behind corporate firewalls or what have you.
In either case you should then have a new directory named 'git' that contains
all the Git source code and history - it is basically a complete copy of what
was on the server.
The git:// protocol is faster and more efficient, but sometimes it is
necessary to use http when behind corporate firewalls or what have you. In
either case you should then have a new directory named 'git' that contains all
the Git source code and history - it is basically a complete copy of what was
on the server.

By default, Git will name the new directory it has checked
out your cloned code into after whatever comes directly before the '.git' in
the name of the cloned project. (ie. *git clone http://git.kernel.org/linux/kernel/git/torvalds/linux-2.6.git* will
result in a new directory named 'linux-2.6')
By default, Git will name the new directory it has checked out your cloned
code into after whatever comes directly before the '.git' in the path of the
cloned project. (ie. *git clone
http://git.kernel.org/linux/kernel/git/torvalds/linux-2.6.git* will result in
a new directory named 'linux-2.6')

### Initializing a New Repository ###

Assume you have a tarball project.tar.gz with your initial work. You
can place it under git revision control as follows.
Assume you have a tarball named project.tar.gz with your initial work. You can
place it under git revision control as follows.

$ tar xzf project.tar.gz
$ cd project
Expand Down
4 changes: 2 additions & 2 deletions text/07_Normal_Workflow/0_ Normal_Workflow.markdown
Expand Up @@ -28,7 +28,7 @@ newly modified content to the index. Finally, commit your changes with:

$ git commit

This will again prompt your for a message describing the change, and then
This will again prompt you for a message describing the change, and then
record a new version of the project.

Alternatively, instead of running `git add` beforehand, you can use
Expand All @@ -43,7 +43,7 @@ begin the commit message with a single short (less than 50 character)
line summarizing the change, followed by a blank line and then a more
thorough description. Tools that turn commits into email, for
example, use the first line on the Subject: line and the rest of the
commit in the body.
commit message in the body.


#### Git tracks content not files ####
Expand Down
Expand Up @@ -79,7 +79,7 @@ linkgit:git-merge[1]:

$ git merge branchname

merges the development in the branch "branchname" into the current
merges the changes made in the branch "branchname" into the current
branch. If there are conflicts--for example, if the same file is
modified in two different ways in the remote branch and the local
branch--then you are warned; the output may look something like this:
Expand All @@ -93,10 +93,10 @@ branch--then you are warned; the output may look something like this:
Conflict markers are left in the problematic files, and after
you resolve the conflicts manually, you can update the index
with the contents and run git commit, as you normally would when
creating a new file.
modifying a file.

If you examine the resulting commit using gitk, you will see that it
has two parents, one pointing to the top of the current branch, and
has two parents: one pointing to the top of the current branch, and
one to the top of the other branch.

### Resolving a merge ###
Expand Down Expand Up @@ -145,22 +145,20 @@ Or, if you've already committed the merge that you want to throw away,

$ git reset --hard ORIG_HEAD

However, this last command can be dangerous in some cases--never
throw away a commit you have already committed if that commit may
itself have been merged into another branch, as doing so may confuse
further merges.
However, this last command can be dangerous in some cases--never throw away a
commit if that commit may itself have been merged into another branch, as
doing so may confuse further merges.

### Fast-forward merges ###

There is one special case not mentioned above, which is treated
differently. Normally, a merge results in a merge commit, with two
parents, one pointing at each of the two lines of development that
were merged.
There is one special case not mentioned above, which is treated differently.
Normally, a merge results in a merge commit with two parents, one for each of
the two lines of development that were merged.

However, if the current branch is a descendant of the other--so every
commit present in the one is already contained in the other--then git
just performs a "fast forward"; the head of the current branch is moved
forward to point at the head of the merged-in branch, without any new
commits being created.
However, if the current branch has not diverged from the other--so every
commit present in the current branch is already contained in the other--then
git just performs a "fast forward"; the head of the current branch is moved
forward to point at the head of the merged-in branch, without any new commits
being created.

[gitcast:c6-branch-merge]("GitCast #6: Branching and Merging")

0 comments on commit 63df61a

Please sign in to comment.