Skip to content
This repository has been archived by the owner on Nov 15, 2024. It is now read-only.

Commit

Permalink
First release
Browse files Browse the repository at this point in the history
  • Loading branch information
topfunky committed Apr 29, 2008
1 parent 9f1827f commit a85336a
Show file tree
Hide file tree
Showing 47 changed files with 17,299 additions and 16,343 deletions.
18,556 changes: 10,763 additions & 7,793 deletions artwork/main.graffle

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions artwork/vector/Blob_Expand.eps

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions artwork/vector/Blobs.eps

Large diffs are not rendered by default.

348 changes: 129 additions & 219 deletions artwork/vector/Branch_Story1.eps

Large diffs are not rendered by default.

488 changes: 195 additions & 293 deletions artwork/vector/Branch_Story2.eps

Large diffs are not rendered by default.

566 changes: 233 additions & 333 deletions artwork/vector/Branch_Story3.eps

Large diffs are not rendered by default.

353 changes: 120 additions & 233 deletions artwork/vector/Branches1.eps

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions artwork/vector/Commit.eps

Large diffs are not rendered by default.

48 changes: 24 additions & 24 deletions artwork/vector/Commit_Expand.eps

Large diffs are not rendered by default.

24 changes: 12 additions & 12 deletions artwork/vector/Commit_Expand2.eps

Large diffs are not rendered by default.

961 changes: 435 additions & 526 deletions artwork/vector/DAG_1.eps

Large diffs are not rendered by default.

443 changes: 165 additions & 278 deletions artwork/vector/DAG_Model.eps

Large diffs are not rendered by default.

54 changes: 27 additions & 27 deletions artwork/vector/Fetch_Pull.eps

Large diffs are not rendered by default.

54 changes: 27 additions & 27 deletions artwork/vector/Git_Add_Commit.eps

Large diffs are not rendered by default.

40 changes: 20 additions & 20 deletions artwork/vector/Git_Commit_A.eps

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions artwork/vector/Layout.eps

Large diffs are not rendered by default.

921 changes: 415 additions & 506 deletions artwork/vector/Object_DAG.eps

Large diffs are not rendered by default.

470 changes: 191 additions & 279 deletions artwork/vector/Object_DAG_Tree1.eps

Large diffs are not rendered by default.

781 changes: 345 additions & 436 deletions artwork/vector/Object_DAG_Tree2.eps

Large diffs are not rendered by default.

937 changes: 423 additions & 514 deletions artwork/vector/Object_DAG_Tree3.eps

Large diffs are not rendered by default.

349 changes: 171 additions & 178 deletions artwork/vector/Rebase1.eps

Large diffs are not rendered by default.

637 changes: 271 additions & 366 deletions artwork/vector/Rebase2.eps

Large diffs are not rendered by default.

412 changes: 160 additions & 252 deletions artwork/vector/Rebase3.eps

Large diffs are not rendered by default.

424 changes: 167 additions & 257 deletions artwork/vector/Rebase4.eps

Large diffs are not rendered by default.

655 changes: 278 additions & 377 deletions artwork/vector/Rebase5.eps

Large diffs are not rendered by default.

775 changes: 335 additions & 440 deletions artwork/vector/Rebase6.eps

Large diffs are not rendered by default.

804 changes: 355 additions & 449 deletions artwork/vector/Rebase7_Final.eps

Large diffs are not rendered by default.

304 changes: 107 additions & 197 deletions artwork/vector/Remote_Story1.eps

Large diffs are not rendered by default.

531 changes: 213 additions & 318 deletions artwork/vector/Remote_Story2.eps

Large diffs are not rendered by default.

659 changes: 275 additions & 384 deletions artwork/vector/Remote_Story3.eps

Large diffs are not rendered by default.

1,236 changes: 618 additions & 618 deletions artwork/vector/Tag_Expand.eps

Large diffs are not rendered by default.

862 changes: 369 additions & 493 deletions artwork/vector/Traversing_Git_Objects.eps

Large diffs are not rendered by default.

48 changes: 24 additions & 24 deletions artwork/vector/Tree_Expand.eps

Large diffs are not rendered by default.

771 changes: 349 additions & 422 deletions artwork/vector/Treeish.eps

Large diffs are not rendered by default.

24 changes: 12 additions & 12 deletions artwork/vector/Trees.eps

Large diffs are not rendered by default.

Binary file modified drafts/git-draft.pdf
Binary file not shown.
Binary file added drafts/peepcode-git-preview.pdf
Binary file not shown.
Binary file added drafts/peepcode-git.pdf
Binary file not shown.
Binary file modified layout/layout.indd
Binary file not shown.
Binary file added layout/preview.indd
Binary file not shown.
24 changes: 15 additions & 9 deletions text/s1-c03-object-types.textile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ note. SHA stands for Secure Hash Algorithm. A SHA creates an identifier of fixed

To demonstrate these examples, we will develop a small ruby library that provides very simple bindings to Git, keeping the project in a Git repository. The basic layout of the project is this:

!vector/Layout.eps!
!vector/Layout.eps(Sample project with files and directories)!

Let's take a look at what Git does when this is committed to a repository.

Expand All @@ -18,46 +18,52 @@ h3. The Blob

In Git, the contents of files are stored as *blobs*.

!vector/Blobs.eps!
!vector/Blobs.eps(Files are stored as blobs)!

It is important to note that it is the _contents_ that are stored, not the files. The names and modes of the files are not stored with the blob, just the contents.

This means that if you have two files anywhere in your project that are exactly the same, even if they have different names, Git will only store the blob once. This also means that during repository transfers, such as clones or fetches, Git will only transfer the blob once, then expand it out into multiple files upon checkout.

!vector/Blob_Expand.eps(The contents of a blob, uncompressed)!

break. x

h3. The Tree

Directories in Git basically correspond to *trees*.

!vector/Trees.eps!
!vector/Trees.eps(Trees are pointers to blobs and other trees)!

A tree is a simple list of trees and blobs that the tree contains, along with the names and modes of those trees and blobs. The contents section of a tree object consists of a very simple text file that lists the _mode_, _type_, _name_ and _sha_ of each entry.

!vector/Tree_Expand.eps!
!vector/Tree_Expand.eps(An uncompressed tree)!

break. x

h3. The Commit

So, now that we can store arbitrary trees of content in Git, where does the 'history' part of 'tree history storage system' come in? The answer is the *commit* object.

!vector/Commit.eps!
!vector/Commit.eps(A commit references a tree)!

The commit is very simple, much like the tree. It simply points to a tree and keeps an _author_, _committer_, _message_ and any _parent_ commits that directly preceded it.

!vector/Commit_Expand.eps!
!vector/Commit_Expand.eps(Uncompressed initial commit)!

Since this was my first commit, there are no parents. If I commit a second time, the commit object will look more like this:

!vector/Commit_Expand2.eps!
!vector/Commit_Expand2.eps(A commit with a parent)!

Notice how the _parent_ in that commit is the same SHA-1 value of the last commit we did? Most times a commit will only have a single parent like that, but if you merge two branches, the next commit will point to both of them.

note. The current record for number of commit parents in the Linux kernel is 12 branches merged in a single commit!

break. x

h3. The Tag

The final type of object you will find in a Git database is the *tag*. This is an object that provides a permanent shorthand name for a particular commit. It contains an _object_, _type_, _tag_, _tagger_ and a _message_. Normally the _type_ is a 'commit' and the _object_ is the SHA-1 of the commit you're tagging. The tag can also be GPG signed, providing cryptographic integrity to a release or version.
The final type of object you will find in a Git database is the *tag*. This is an object that provides a permanent shorthand name for a particular commit. It contains an _object_, _type_, _tag_, _tagger_ and a _message_. Normally the _type_ is @commit@ and the _object_ is the SHA-1 of the commit you're tagging. The tag can also be GPG signed, providing cryptographic integrity to a release or version.

!vector/Tag_Expand.eps!
!vector/Tag_Expand.eps(Uncompressed tag)!

We'll talk a little bit more about tags and how they differ from _branches_ (which also point to commits, but are not stored as objects) in the next section, where we'll pull all of this together into how all these objects relate to each other conceptually.
20 changes: 12 additions & 8 deletions text/s1-c05-the-data-model.textile
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
break. x

h2. The Git Data Model

In computer science speak, the Git object data is a Directed Acyclic Graph. That is, starting at any commit you can traverse its parents in one direction and there is no chain that begins and ends with the same object.
In computer science speak, the Git object data is a _directed acyclic graph_. That is, starting at any commit you can traverse its parents in one direction and there is no chain that begins and ends with the same object.

All commit objects point to a tree and optionally to previous commits. All trees point to one or many blobs and/or trees. Given this simple model, we can store and retrieve vast histories of complex trees of arbitrarily changing content quickly and efficiently.

Expand All @@ -10,7 +12,9 @@ h3. References

In addition to the Git objects, which are immutable - that is, they cannot ever be changed, there are references also stored in Git. Unlike the objects, references can constantly change. They are simple pointers to a particular commit, something like a tag, but easily moveable.

Examples of references are branches and remotes. A branch in Git is nothing more than a file in the _.git/refs/heads/_ directory that contains the SHA-1 of the most recent commit of that branch. To branch that line of development, all Git does is create a new file in that directory that points to the same sha. Then, as you continue to commit, one of the branches will keep changing to point to the new commit shas, while the other one can stay where it was. _(Don't worry, we'll go over this again a bit later...)_
Examples of references are branches and remotes. A branch in Git is nothing more than a file in the @.git/refs/heads/@ directory that contains the SHA-1 of the most recent commit of that branch. To branch that line of development, all Git does is create a new file in that directory that points to the same SHA-1. As you continue to commit, one of the branches will keep changing to point to the new commit SHA-1s, while the other one can stay where it was. If this is confusing, don't worry. We'll go over it again later.

break. x

h3. The Model

Expand All @@ -30,19 +34,19 @@ code. model-tree-example.txt

When we first commit this tree, our Git model may look something like this:

!vector/Object_DAG_Tree1.eps!
!<vector/Object_DAG_Tree1.eps! We have three trees, three blobs and a single commit that points to the top of the tree. The current branch points to our last commit and the HEAD file points to the branch we're currently on. This lets Git know which commit will be the parent for the next commit.

We have 3 trees, 3 blobs, 1 commit that points to the top of the tree, the current branch pointing to our last commit and the HEAD file pointing to the branch we're currently on to let Git know which commit will be the parent for the next commit.
Now let's assume that we change the @lib/base/base_include.rb@ file and commit again. At this point, a new blob is added, which changes the tree that points to it, which changes the tree that points to that tree and so on to the top of the entire directory. Then a new commit object is added which points to its parent and the new tree, then the branch reference is moved forward.

Now let's assume that we change the _lib/base/base_include.rb_ file and commit again. At this point, a new blob is added, which changes the tree that points to it, which changes the tree that points to that tree and so on to the top of the entire directory. Then a new commit object is added which points to its parent and the new tree, then the branch reference is moved forward.
Let's also say at this point we tag this commit as a release, which adds a new tag object.

Let's also say at this point we tag this commit as a release, which adds a new tag object. At this point, we'll have the following in Git:
At this point, we'll have the following in Git:

!vector/Object_DAG_Tree2.eps!

Notice how the other two blobs that were not changed were not added again. The new trees that were added point to the same blobs in the data store that the previous trees pointed to.

Now let's say we modify the _init.rb_ file at the base of the project. The new blob will have to be added, which will add a new top tree, but all the subtrees will not be modified, so Git will re-use those references. Again, the branch reference will move forward and the new commit will point to its parent.
Now let's say we modify the @init.rb@ file at the base of the project. The new blob will have to be added, which will add a new top tree, but all the subtrees will not be modified, so Git will reuse those references. Again, the branch reference will move forward and the new commit will point to its parent.

!vector/Object_DAG_Tree3.eps!

Expand All @@ -56,7 +60,7 @@ So, to keep all the information and history on the three versions of this tree,

h3. Traversal

So, what do all the arrows in these illustrations really mean? How does Git actually retrieve these objects in practice? Well, it gets the initial SHA-1 of the starting commit object by looking in the _.git/refs_ directory for the branch, tag or remote you specify. Then it traverses the objects by walking the trees one by one, checking out the blobs under the names listed.
So, what do all the arrows in these illustrations really mean? How does Git actually retrieve these objects in practice? Well, it gets the initial SHA-1 of the starting commit object by looking in the @.git/refs@ directory for the branch, tag or remote you specify. Then it traverses the objects by walking the trees one by one, checking out the blobs under the names listed.

!vector/Traversing_Git_Objects.eps!

18 changes: 9 additions & 9 deletions text/s1-c06-branching-and-merging.textile
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ note. Creating a branch is nothing more than just writing 40 characters to a fil

Switching to that branch simply means having Git make your working directory look like the tree that SHA-1 points to and updating the HEAD file so each commit from that point on moves that branch pointer forward (in other words, it changes the 40 characters in @.git/refs/heads/[current_branch_name]@ be the SHA-1 of your last commit).

Now, let's see how Git handles branching, fetching and merging operations abstractly. For the following illustrations, we will represent the entire tree and the commit it points to as a single object.

!vector/Branches1.eps!
break. x

h3. Simple Case

!<vector/Branches1.eps! Now, let's see how Git handles branching, fetching and merging operations abstractly. For the following illustrations, we will represent the entire tree and the commit it points to as a single object.

Suppose that we work on a project for a while, then we get an idea for something that may not work out, but we want to do a quick proof-of-concept. We create a new branch called @experiment@ off of our main branch, which is by convention called @master@. We then switch to the new branch and create a few commits.

!vector/Branch_Story1.eps!
Expand All @@ -22,7 +22,9 @@ Then, our boss comes in and says we need a hot fix to production. So we switch

!vector/Branch_Story2.eps!

At this point, we show the new branch code to our co-workers and everyone likes the new changes. We decide we want to merge them back into our main branch, so we merge the changes and delete our @experiment@ branch. Our history of commit objects now looks like this:
At this point, we show the new branch code to our co-workers and everyone likes the new changes. We decide we want to merge them back into our main branch, so we merge the changes and delete our @experiment@ branch.

Our history of commit objects now looks like this:

!vector/Branch_Story3.eps!

Expand All @@ -32,9 +34,9 @@ Now lets take a look at remotes. Remotes are basically pointers to branches in

Lets say you clone someone's repository and make a few changes. You would have two references, one to @origin/master@ which points to where the master branch was on the person's repository you cloned from when you did so, and a @master@ branch that points the most recent local commit.

!vector/Remote_Story1.eps!
!vector/Remote_Story1.eps!

Now lets say you run a @fetch@. A fetch pulls all the refs and objects that you don't already have from the remote repository you specify. By default, it is origin, but you can name your remotes anything, and you can have more than one. Suppose we fetch from the repository that we originally cloned from and they had been doing some work. They have now committed a few times on their master branch, but they also branched off at one point to try an idea, and they named the branch @idea@ locally, then pushed that branch. We now have access to those changes as @origin/idea@.
Now let's say you run a @fetch@. A fetch pulls all the refs and objects that you don't already have from the remote repository you specify. By default, it is origin, but you can name your remotes anything, and you can have more than one. Suppose we fetch from the repository that we originally cloned from and they had been doing some work. They have now committed a few times on their master branch, but they also branched off at one point to try an idea, and they named the branch @idea@ locally, then pushed that branch. We now have access to those changes as @origin/idea@.

!vector/Remote_Story2.eps!

Expand All @@ -60,9 +62,7 @@ This is where the rebasing command comes in. With rebase, Git will checkout the

Rebase will literally produce a series of patch files of your work and start applying them to the upstream branch, automatically making new commits with the same messages as before and orphaning your older ones. These objects can then be removed, since nothing points to them, when you run the garbage collection tools (see "The Care and Feeding of Git" section).

So let's see what happens if we rebase rather than merge in the same scenario. Here we have our first merge and we can see that it orphans _Commit 1_ and applies the changes between _Commit 0_ and _Commit 1_ to the files in _Remote Commit 1_, creating a new _Commit 2_.

!vector/Rebase3.eps!
!<vector/Rebase3.eps! So let's see what happens if we rebase rather than merge in the same scenario. Here we have our first merge and we can see that it orphans _Commit 1_ and applies the changes between _Commit 0_ and _Commit 1_ to the files in _Remote Commit 1_, creating a new _Commit 2_.

Then, as you'll remember, you and Jen both commit again. You'll notice that now it looks like she cloned you and committed and then you changed that code, rather than you both working at the same time and merging.

Expand Down
2 changes: 2 additions & 0 deletions text/s2-c04-log-commit-history.textile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ shell. git-log-oneline.txt

With @--pretty@, you can choose between _oneline_, _short_, _medium_, _full_, _fuller_, _email_, _raw_ and _format:(string)_, where (string) is a format you specify with variables (ex: @--format:"%an added %h on %ar"@ will give you a bunch of lines like "Scott Chacon added @f1cc9df@ 4 days ago").

break. x

h3. Filtering Log Output

There are also a number of options for filtering the log output. You can specify the maximum number of commits you want to see with @-n@, you can limit the range of dates you want to see commits for with @--since@ and @--until@, you can filter it on the author or committer, text in the commit message and more. Here is an example showing at most 30 commits between yesterday and a month ago by me :
Expand Down
2 changes: 2 additions & 0 deletions text/s2-c05-browsing-git.textile
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ shell. git-catfile.txt

With those basic commands, you should be able to explore and inspect any object in any git repository relatively easily.

break. x

h3. Graphical Interfaces

There are two major graphical interfaces that come with Git as tools to browse the repository.
Expand Down
2 changes: 2 additions & 0 deletions text/s2-c13-sharing-repositories.textile
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
break. x

h2. Sharing Repositories

h3. Over Git
Expand Down
19 changes: 19 additions & 0 deletions website/website.textile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
!http://peepcode.com/system/previews/git-pdf/gitbook-cover.png!

Many have learned the basics of using Git from the PeepCode "Git screencast":http://peepcode.com/products/git. In this PDF, Scott Chacon goes even further to explain the distributed filesystem behind the popular source code management system.

If you're tired of terse man pages or academic white papers, you'll enjoy more than four dozen colorful diagrams that clearly explain the complicated inner workings of Git.

The first 50 pages explain the storage system that powers Git, and an additional 60 pages go into detail about using Git on a day to day basis. You'll learn not only how to use the basic commands, but will also learn different strategies for working via either a centralized or distributed collaboration model. This is a great companion to the existing PeepCode screencast or a useful book in its own right.

As a bonus, several short screencasts are included which show how to use the basic Git commands.

The Git source code control system continues to win over developers who are impressed with the speed and flexibility of the distributed workflow. Go beyond the basics with this PDF from PeepCode.

Available as part of the "PeepCode Unlimited":http://peepcode.com/products/unlimited package or as a single purchase for only US$9!

!http://peepcode.com/system/previews/git-pdf/gitbook-commits.png!

!http://peepcode.com/system/previews/git-pdf/gitbook-files.png!

!http://peepcode.com/system/previews/git-pdf/gitbook-trees.png!

0 comments on commit a85336a

Please sign in to comment.