Autogenerated HTML docs for v1.3.3-gd5e3d
[git.git] / tutorial-2.html
diff --git a/tutorial-2.html b/tutorial-2.html
new file mode 100644 (file)
index 0000000..3dd6805
--- /dev/null
@@ -0,0 +1,641 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\r
+    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\r
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">\r
+<head>\r
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />\r
+<meta name="generator" content="AsciiDoc 7.0.2" />\r
+<style type="text/css">\r
+/* Debug borders */\r
+p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {\r
+/*\r
+  border: 1px solid red;\r
+*/\r
+}\r
+\r
+body {\r
+  margin: 1em 5% 1em 5%;\r
+}\r
+\r
+a { color: blue; }\r
+a:visited { color: fuchsia; }\r
+\r
+em {\r
+  font-style: italic;\r
+}\r
+\r
+strong {\r
+  font-weight: bold;\r
+}\r
+\r
+tt {\r
+  color: navy;\r
+}\r
+\r
+h1, h2, h3, h4, h5, h6 {\r
+  color: #527bbd;\r
+  font-family: sans-serif;\r
+  margin-top: 1.2em;\r
+  margin-bottom: 0.5em;\r
+  line-height: 1.3;\r
+}\r
+\r
+h1 {\r
+  border-bottom: 2px solid silver;\r
+}\r
+h2 {\r
+  border-bottom: 2px solid silver;\r
+  padding-top: 0.5em;\r
+}\r
+\r
+div.sectionbody {\r
+  font-family: serif;\r
+  margin-left: 0;\r
+}\r
+\r
+hr {\r
+  border: 1px solid silver;\r
+}\r
+\r
+p {\r
+  margin-top: 0.5em;\r
+  margin-bottom: 0.5em;\r
+}\r
+\r
+pre {\r
+  padding: 0;\r
+  margin: 0;\r
+}\r
+\r
+span#author {\r
+  color: #527bbd;\r
+  font-family: sans-serif;\r
+  font-weight: bold;\r
+  font-size: 1.2em;\r
+}\r
+span#email {\r
+}\r
+span#revision {\r
+  font-family: sans-serif;\r
+}\r
+\r
+div#footer {\r
+  font-family: sans-serif;\r
+  font-size: small;\r
+  border-top: 2px solid silver;\r
+  padding-top: 0.5em;\r
+  margin-top: 4.0em;\r
+}\r
+div#footer-text {\r
+  float: left;\r
+  padding-bottom: 0.5em;\r
+}\r
+div#footer-badges {\r
+  float: right;\r
+  padding-bottom: 0.5em;\r
+}\r
+\r
+div#preamble,\r
+div.tableblock, div.imageblock, div.exampleblock, div.verseblock,\r
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,\r
+div.admonitionblock {\r
+  margin-right: 10%;\r
+  margin-top: 1.5em;\r
+  margin-bottom: 1.5em;\r
+}\r
+div.admonitionblock {\r
+  margin-top: 2.5em;\r
+  margin-bottom: 2.5em;\r
+}\r
+\r
+div.content { /* Block element content. */\r
+  padding: 0;\r
+}\r
+\r
+/* Block element titles. */\r
+div.title, caption.title {\r
+  font-family: sans-serif;\r
+  font-weight: bold;\r
+  text-align: left;\r
+  margin-top: 1.0em;\r
+  margin-bottom: 0.5em;\r
+}\r
+div.title + * {\r
+  margin-top: 0;\r
+}\r
+\r
+td div.title:first-child {\r
+  margin-top: 0.0em;\r
+}\r
+div.content div.title:first-child {\r
+  margin-top: 0.0em;\r
+}\r
+div.content + div.title {\r
+  margin-top: 0.0em;\r
+}\r
+\r
+div.sidebarblock > div.content {\r
+  background: #ffffee;\r
+  border: 1px solid silver;\r
+  padding: 0.5em;\r
+}\r
+\r
+div.listingblock > div.content {\r
+  border: 1px solid silver;\r
+  background: #f4f4f4;\r
+  padding: 0.5em;\r
+}\r
+\r
+div.quoteblock > div.content {\r
+  padding-left: 2.0em;\r
+}\r
+div.quoteblock .attribution {\r
+  text-align: right;\r
+}\r
+\r
+div.admonitionblock .icon {\r
+  vertical-align: top;\r
+  font-size: 1.1em;\r
+  font-weight: bold;\r
+  text-decoration: underline;\r
+  color: #527bbd;\r
+  padding-right: 0.5em;\r
+}\r
+div.admonitionblock td.content {\r
+  padding-left: 0.5em;\r
+  border-left: 2px solid silver;\r
+}\r
+\r
+div.exampleblock > div.content {\r
+  border-left: 2px solid silver;\r
+  padding: 0.5em;\r
+}\r
+\r
+div.verseblock div.content {\r
+  white-space: pre;\r
+}\r
+\r
+div.imageblock div.content { padding-left: 0; }\r
+div.imageblock img { border: 1px solid silver; }\r
+span.image img { border-style: none; }\r
+\r
+dl {\r
+  margin-top: 0.8em;\r
+  margin-bottom: 0.8em;\r
+}\r
+dt {\r
+  margin-top: 0.5em;\r
+  margin-bottom: 0;\r
+  font-style: italic;\r
+}\r
+dd > *:first-child {\r
+  margin-top: 0;\r
+}\r
+\r
+ul, ol {\r
+    list-style-position: outside;\r
+}\r
+ol.olist2 {\r
+  list-style-type: lower-alpha;\r
+}\r
+\r
+div.tableblock > table {\r
+  border-color: #527bbd;\r
+  border-width: 3px;\r
+}\r
+thead {\r
+  font-family: sans-serif;\r
+  font-weight: bold;\r
+}\r
+tfoot {\r
+  font-weight: bold;\r
+}\r
+\r
+div.hlist {\r
+  margin-top: 0.8em;\r
+  margin-bottom: 0.8em;\r
+}\r
+td.hlist1 {\r
+  vertical-align: top;\r
+  font-style: italic;\r
+  padding-right: 0.8em;\r
+}\r
+td.hlist2 {\r
+  vertical-align: top;\r
+}\r
+\r
+@media print {\r
+  div#footer-badges { display: none; }\r
+}\r
+/* Workarounds for IE6's broken and incomplete CSS2. */\r
+\r
+div.sidebar-content {\r
+  background: #ffffee;\r
+  border: 1px solid silver;\r
+  padding: 0.5em;\r
+}\r
+div.sidebar-title, div.image-title {\r
+  font-family: sans-serif;\r
+  font-weight: bold;\r
+  margin-top: 0.0em;\r
+  margin-bottom: 0.5em;\r
+}\r
+\r
+div.listingblock div.content {\r
+  border: 1px solid silver;\r
+  background: #f4f4f4;\r
+  padding: 0.5em;\r
+}\r
+\r
+div.quoteblock-content {\r
+  padding-left: 2.0em;\r
+}\r
+\r
+div.exampleblock-content {\r
+  border-left: 2px solid silver;\r
+  padding-left: 0.5em;\r
+}\r
+</style>\r
+<title>A tutorial introduction to git: part two</title>\r
+</head>\r
+<body>\r
+<div id="header">\r
+<h1>A tutorial introduction to git: part two</h1>\r
+</div>\r
+<div id="preamble">\r
+<div class="sectionbody">\r
+<p>You should work through <a href="tutorial.html">A tutorial introduction to\r
+git</a> before reading this tutorial.</p>\r
+<p>The goal of this tutorial is to introduce two fundamental pieces of\r
+git's architecture&#8212;the object database and the index file&#8212;and to\r
+provide the reader with everything necessary to understand the rest\r
+of the git documentation.</p>\r
+</div>\r
+</div>\r
+<h2>The git object database</h2>\r
+<div class="sectionbody">\r
+<p>Let's start a new project and create a small amount of history:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ mkdir test-project\r
+$ cd test-project\r
+$ git init-db\r
+defaulting to local storage area\r
+$ echo 'hello world' &gt; file.txt\r
+$ git add .\r
+$ git commit -a -m "initial commit"\r
+Committing initial tree 92b8b694ffb1675e5975148e1121810081dbdffe\r
+$ echo 'hello world!' &gt;file.txt\r
+$ git commit -a -m "add emphasis"</tt></pre>\r
+</div></div>\r
+<p>What are the 40 digits of hex that git responded to the first commit\r
+with?</p>\r
+<p>We saw in part one of the tutorial that commits have names like this.\r
+It turns out that every object in the git history is stored under\r
+such a 40-digit hex name.  That name is the SHA1 hash of the object's\r
+contents; among other things, this ensures that git will never store\r
+the same data twice (since identical data is given an identical SHA1\r
+name), and that the contents of a git object will never change (since\r
+that would change the object's name as well).</p>\r
+<p>We can ask git about this particular object with the cat-file\r
+command&#8212;just cut-and-paste from the reply to the initial commit, to\r
+save yourself typing all 40 hex digits:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ git cat-file -t 92b8b694ffb1675e5975148e1121810081dbdffe\r
+tree</tt></pre>\r
+</div></div>\r
+<p>A tree can refer to one or more "blob" objects, each corresponding to\r
+a file.  In addition, a tree can also refer to other tree objects,\r
+thus creating a directory heirarchy.  You can examine the contents of\r
+any tree using ls-tree (remember that a long enough initial portion\r
+of the SHA1 will also work):</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ git ls-tree 92b8b694\r
+100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad    file.txt</tt></pre>\r
+</div></div>\r
+<p>Thus we see that this tree has one file in it.  The SHA1 hash is a\r
+reference to that file's data:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ git cat-file -t 3b18e512\r
+blob</tt></pre>\r
+</div></div>\r
+<p>A "blob" is just file data, which we can also examine with cat-file:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ git cat-file blob 3b18e512\r
+hello world</tt></pre>\r
+</div></div>\r
+<p>Note that this is the old file data; so the object that git named in\r
+its response to the initial tree was a tree with a snapshot of the\r
+directory state that was recorded by the first commit.</p>\r
+<p>All of these objects are stored under their SHA1 names inside the git\r
+directory:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ find .git/objects/\r
+.git/objects/\r
+.git/objects/pack\r
+.git/objects/info\r
+.git/objects/3b\r
+.git/objects/3b/18e512dba79e4c8300dd08aeb37f8e728b8dad\r
+.git/objects/92\r
+.git/objects/92/b8b694ffb1675e5975148e1121810081dbdffe\r
+.git/objects/54\r
+.git/objects/54/196cc2703dc165cbd373a65a4dcf22d50ae7f7\r
+.git/objects/a0\r
+.git/objects/a0/423896973644771497bdc03eb99d5281615b51\r
+.git/objects/d0\r
+.git/objects/d0/492b368b66bdabf2ac1fd8c92b39d3db916e59\r
+.git/objects/c4\r
+.git/objects/c4/d59f390b9cfd4318117afde11d601c1085f241</tt></pre>\r
+</div></div>\r
+<p>and the contents of these files is just the compressed data plus a\r
+header identifying their length and their type.  The type is either a\r
+blob, a tree, a commit, or a tag.  We've seen a blob and a tree now,\r
+so next we should look at a commit.</p>\r
+<p>The simplest commit to find is the HEAD commit, which we can find\r
+from .git/HEAD:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ cat .git/HEAD\r
+ref: refs/heads/master</tt></pre>\r
+</div></div>\r
+<p>As you can see, this tells us which branch we're currently on, and it\r
+tells us this by naming a file under the .git directory, which itself\r
+contains a SHA1 name referring to a commit object, which we can\r
+examine with cat-file:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ cat .git/refs/heads/master\r
+c4d59f390b9cfd4318117afde11d601c1085f241\r
+$ git cat-file -t c4d59f39\r
+commit\r
+$ git cat-file commit c4d59f39\r
+tree d0492b368b66bdabf2ac1fd8c92b39d3db916e59\r
+parent 54196cc2703dc165cbd373a65a4dcf22d50ae7f7\r
+author J. Bruce Fields &lt;bfields@puzzle.fieldses.org&gt; 1143418702 -0500\r
+committer J. Bruce Fields &lt;bfields@puzzle.fieldses.org&gt; 1143418702 -0500\r
+\r
+add emphasis</tt></pre>\r
+</div></div>\r
+<p>The "tree" object here refers to the new state of the tree:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ git ls-tree d0492b36\r
+100644 blob a0423896973644771497bdc03eb99d5281615b51    file.txt\r
+$ git cat-file commit a0423896\r
+hello world!</tt></pre>\r
+</div></div>\r
+<p>and the "parent" object refers to the previous commit:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ git-cat-file commit 54196cc2\r
+tree 92b8b694ffb1675e5975148e1121810081dbdffe\r
+author J. Bruce Fields &lt;bfields@puzzle.fieldses.org&gt; 1143414668 -0500\r
+committer J. Bruce Fields &lt;bfields@puzzle.fieldses.org&gt; 1143414668 -0500\r
+\r
+initial commit</tt></pre>\r
+</div></div>\r
+<p>The tree object is the tree we examined first, and this commit is\r
+unusual in that it lacks any parent.</p>\r
+<p>Most commits have only one parent, but it is also common for a commit\r
+to have multiple parents.   In that case the commit represents a\r
+merge, with the parent references pointing to the heads of the merged\r
+branches.</p>\r
+<p>Besides blobs, trees, and commits, the only remaining type of object\r
+is a "tag", which we won't discuss here; refer to <a href="git-tag.html">git-tag(1)</a>\r
+for details.</p>\r
+<p>So now we know how git uses the object database to represent a\r
+project's history:</p>\r
+<ul>\r
+<li>\r
+<p>\r
+"commit" objects refer to "tree" objects representing the\r
+    snapshot of a directory tree at a particular point in the\r
+    history, and refer to "parent" commits to show how they're\r
+    connected into the project history.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+"tree" objects represent the state of a single directory,\r
+    associating directory names to "blob" objects containing file\r
+    data and "tree" objects containing subdirectory information.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+"blob" objects contain file data without any other structure.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+References to commit objects at the head of each branch are\r
+    stored in files under .git/refs/heads/.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+The name of the current branch is stored in .git/HEAD.\r
+</p>\r
+</li>\r
+</ul>\r
+<p>Note, by the way, that lots of commands take a tree as an argument.\r
+But as we can see above, a tree can be referred to in many different\r
+ways&#8212;by the SHA1 name for that tree, by the name of a commit that\r
+refers to the tree, by the name of a branch whose head refers to that\r
+tree, etc.&#8212;and most such commands can accept any of these names.</p>\r
+<p>In command synopses, the word "tree-ish" is sometimes used to\r
+designate such an argument.</p>\r
+</div>\r
+<h2>The index file</h2>\r
+<div class="sectionbody">\r
+<p>The primary tool we've been using to create commits is "git commit\r
+-a", which creates a commit including every change you've made to\r
+your working tree.  But what if you want to commit changes only to\r
+certain files?  Or only certain changes to certain files?</p>\r
+<p>If we look at the way commits are created under the cover, we'll see\r
+that there are more flexible ways creating commits.</p>\r
+<p>Continuing with our test-project, let's modify file.txt again:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ echo "hello world, again" &gt;&gt;file.txt</tt></pre>\r
+</div></div>\r
+<p>but this time instead of immediately making the commit, let's take an\r
+intermediate step, and ask for diffs along the way to keep track of\r
+what's happening:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ git diff\r
+--- a/file.txt\r
++++ b/file.txt\r
+@@ -1 +1,2 @@\r
+ hello world!\r
++hello world, again\r
+$ git update-index file.txt\r
+$ git diff</tt></pre>\r
+</div></div>\r
+<p>The last diff is empty, but no new commits have been made, and the\r
+head still doesn't contain the new line:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ git-diff HEAD\r
+diff --git a/file.txt b/file.txt\r
+index a042389..513feba 100644\r
+--- a/file.txt\r
++++ b/file.txt\r
+@@ -1 +1,2 @@\r
+ hello world!\r
++hello world, again</tt></pre>\r
+</div></div>\r
+<p>So "git diff" is comparing against something other than the head.\r
+The thing that it's comparing against is actually the index file,\r
+which is stored in .git/index in a binary format, but whose contents\r
+we can examine with ls-files:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ git ls-files --stage\r
+100644 513feba2e53ebbd2532419ded848ba19de88ba00 0       file.txt\r
+$ git cat-file -t 513feba2\r
+blob\r
+$ git cat-file blob 513feba2\r
+hello world, again</tt></pre>\r
+</div></div>\r
+<p>So what our "git update-index" did was store a new blob and then put\r
+a reference to it in the index file.  If we modify the file again,\r
+we'll see that the new modifications are reflected in the "git-diff"\r
+output:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ echo 'again?' &gt;&gt;file.txt\r
+$ git diff\r
+index 513feba..ba3da7b 100644\r
+--- a/file.txt\r
++++ b/file.txt\r
+@@ -1,2 +1,3 @@\r
+ hello world!\r
+ hello world, again\r
++again?</tt></pre>\r
+</div></div>\r
+<p>With the right arguments, git diff can also show us the difference\r
+between the working directory and the last commit, or between the\r
+index and the last commit:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ git diff HEAD\r
+diff --git a/file.txt b/file.txt\r
+index a042389..ba3da7b 100644\r
+--- a/file.txt\r
++++ b/file.txt\r
+@@ -1 +1,3 @@\r
+ hello world!\r
++hello world, again\r
++again?\r
+$ git diff --cached\r
+diff --git a/file.txt b/file.txt\r
+index a042389..513feba 100644\r
+--- a/file.txt\r
++++ b/file.txt\r
+@@ -1 +1,2 @@\r
+ hello world!\r
++hello world, again</tt></pre>\r
+</div></div>\r
+<p>At any time, we can create a new commit using "git commit" (without\r
+the -a option), and verify that the state committed only includes the\r
+changes stored in the index file, not the additional change that is\r
+still only in our working tree:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ git commit -m "repeat"\r
+$ git diff HEAD\r
+diff --git a/file.txt b/file.txt\r
+index 513feba..ba3da7b 100644\r
+--- a/file.txt\r
++++ b/file.txt\r
+@@ -1,2 +1,3 @@\r
+ hello world!\r
+ hello world, again\r
++again?</tt></pre>\r
+</div></div>\r
+<p>So by default "git commit" uses the index to create the commit, not\r
+the working tree; the -a option to commit tells it to first update\r
+the index with all changes in the working tree.</p>\r
+<p>Finally, it's worth looking at the effect of "git add" on the index\r
+file:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ echo "goodbye, world" &gt;closing.txt\r
+$ git add closing.txt</tt></pre>\r
+</div></div>\r
+<p>The effect of the "git add" was to add one entry to the index file:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ git ls-files --stage\r
+100644 8b9743b20d4b15be3955fc8d5cd2b09cd2336138 0       closing.txt\r
+100644 513feba2e53ebbd2532419ded848ba19de88ba00 0       file.txt</tt></pre>\r
+</div></div>\r
+<p>And, as you can see with cat-file, this new entry refers to the\r
+current contents of the file:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ git cat-file blob a6b11f7a\r
+goodbye, word</tt></pre>\r
+</div></div>\r
+<p>The "status" command is a useful way to get a quick summary of the\r
+situation:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ git status\r
+#\r
+# Updated but not checked in:\r
+#   (will commit)\r
+#\r
+#       new file: closing.txt\r
+#\r
+#\r
+# Changed but not updated:\r
+#   (use git-update-index to mark for commit)\r
+#\r
+#       modified: file.txt\r
+#</tt></pre>\r
+</div></div>\r
+<p>Since the current state of closing.txt is cached in the index file,\r
+it is listed as "updated but not checked in".  Since file.txt has\r
+changes in the working directory that aren't reflected in the index,\r
+it is marked "changed but not updated".  At this point, running "git\r
+commit" would create a commit that added closing.txt (with its new\r
+contents), but that didn't modify file.txt.</p>\r
+<p>Also, note that a bare "git diff" shows the changes to file.txt, but\r
+not the addition of closing.txt, because the version of closing.txt\r
+in the index file is identical to the one in the working directory.</p>\r
+<p>In addition to being the staging area for new commits, the index file\r
+is also populated from the object database when checking out a\r
+branch, and is used to hold the trees involved in a merge operation.\r
+See the <a href="core-tutorial.txt">core tutorial</a> and the relevant man\r
+pages for details.</p>\r
+</div>\r
+<h2>What next?</h2>\r
+<div class="sectionbody">\r
+<p>At this point you should know everything necessary to read the man\r
+pages for any of the git commands; one good place to start would be\r
+with the commands mentioned in <a href="everday.html">Everyday git</a>.  You\r
+should be able to find any unknown jargon in the\r
+<a href="glossary.html">Glosssay</a>.</p>\r
+<p>The <a href="cvs-migration.html">CVS migration</a> document explains how to\r
+import a CVS repository into git, and shows how to use git in a\r
+CVS-like way.</p>\r
+<p>For some interesting examples of git use, see the\r
+<a href="howto-index.html">howtos</a>.</p>\r
+<p>For git developers, the <a href="core-tutorial.html">Core tutorial</a> goes\r
+into detail on the lower-level git mechanisms involved in, for\r
+example, creating a new commit.</p>\r
+</div>\r
+<div id="footer">\r
+<div id="footer-text">\r
+Last updated 22-May-2006 01:09:53 UTC\r
+</div>\r
+</div>\r
+</body>\r
+</html>\r