OSDN Git Service

Add Git official document to help
[tortoisegit/TortoiseGitJp.git] / doc / source / en / TortoiseGit / git_doc / gitcore-tutorial.html.xml
diff --git a/doc/source/en/TortoiseGit/git_doc/gitcore-tutorial.html.xml b/doc/source/en/TortoiseGit/git_doc/gitcore-tutorial.html.xml
new file mode 100644 (file)
index 0000000..fb9a434
--- /dev/null
@@ -0,0 +1,1377 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">\r
+\r
+<article lang="en" id="gitcore-tutorial(7)">\r
+<articleinfo>\r
+    <title>gitcore-tutorial(7)</title>\r
+        <indexterm>\r
+                <primary>gitcore-tutorial(7)</primary>\r
+        </indexterm>\r
+</articleinfo>\r
+<simplesect id="_name">\r
+<title>NAME</title>\r
+<simpara>gitcore-tutorial - A git core tutorial for developers</simpara>\r
+</simplesect>\r
+<simplesect id="_synopsis">\r
+<title>SYNOPSIS</title>\r
+<simpara>git *</simpara>\r
+</simplesect>\r
+<simplesect id="_description">\r
+<title>DESCRIPTION</title>\r
+<simpara>This tutorial explains how to use the "core" git programs to set up and\r
+work with a git repository.</simpara>\r
+<simpara>If you just need to use git as a revision control system you may prefer\r
+to start with "A Tutorial Introduction to GIT" (<xref linkend="gittutorial(7)"/>) or\r
+<ulink url="user-manual.html">the GIT User Manual</ulink>.</simpara>\r
+<simpara>However, an understanding of these low-level tools can be helpful if\r
+you want to understand git&#8217;s internals.</simpara>\r
+<simpara>The core git is often called "plumbing", with the prettier user\r
+interfaces on top of it called "porcelain". You may not want to use the\r
+plumbing directly very often, but it can be good to know what the\r
+plumbing does for when the porcelain isn&#8217;t flushing.</simpara>\r
+<note><simpara>Deeper technical details are often marked as Notes, which you can\r
+skip on your first reading.</simpara></note>\r
+</simplesect>\r
+<simplesect id="_creating_a_git_repository">\r
+<title>Creating a git repository</title>\r
+<simpara>Creating a new git repository couldn&#8217;t be easier: all git repositories start\r
+out empty, and the only thing you need to do is find yourself a\r
+subdirectory that you want to use as a working tree - either an empty\r
+one for a totally new project, or an existing working tree that you want\r
+to import into git.</simpara>\r
+<simpara>For our first example, we&#8217;re going to start a totally new repository from\r
+scratch, with no pre-existing files, and we&#8217;ll call it <emphasis>git-tutorial</emphasis>.\r
+To start up, create a subdirectory for it, change into that\r
+subdirectory, and initialize the git infrastructure with <emphasis>git-init</emphasis>:</simpara>\r
+<literallayout>$ mkdir git-tutorial\r
+$ cd git-tutorial\r
+$ git init</literallayout>\r
+<simpara>to which git will reply</simpara>\r
+<literallayout>Initialized empty Git repository in .git/</literallayout>\r
+<simpara>which is just git&#8217;s way of saying that you haven&#8217;t been doing anything\r
+strange, and that it will have created a local <literal>.git</literal> directory setup for\r
+your new project. You will now have a <literal>.git</literal> directory, and you can\r
+inspect that with <emphasis>ls</emphasis>. For your new empty project, it should show you\r
+three entries, among other things:</simpara>\r
+<itemizedlist>\r
+<listitem>\r
+<simpara>\r
+a file called <literal>HEAD</literal>, that has <literal>ref: refs/heads/master</literal> in it.\r
+   This is similar to a symbolic link and points at\r
+   <literal>refs/heads/master</literal> relative to the <literal>HEAD</literal> file.\r
+</simpara>\r
+<simpara>Don&#8217;t worry about the fact that the file that the <literal>HEAD</literal> link points to\r
+doesn&#8217;t even exist yet&#8201;&#8212;&#8201;you haven&#8217;t created the commit that will\r
+start your <literal>HEAD</literal> development branch yet.</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+a subdirectory called <literal>objects</literal>, which will contain all the\r
+   objects of your project. You should never have any real reason to\r
+   look at the objects directly, but you might want to know that these\r
+   objects are what contains all the real <emphasis>data</emphasis> in your repository.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+a subdirectory called <literal>refs</literal>, which contains references to objects.\r
+</simpara>\r
+</listitem>\r
+</itemizedlist>\r
+<simpara>In particular, the <literal>refs</literal> subdirectory will contain two other\r
+subdirectories, named <literal>heads</literal> and <literal>tags</literal> respectively. They do\r
+exactly what their names imply: they contain references to any number\r
+of different <emphasis>heads</emphasis> of development (aka <emphasis>branches</emphasis>), and to any\r
+<emphasis>tags</emphasis> that you have created to name specific versions in your\r
+repository.</simpara>\r
+<simpara>One note: the special <literal>master</literal> head is the default branch, which is\r
+why the <literal>.git/HEAD</literal> file was created points to it even if it\r
+doesn&#8217;t yet exist. Basically, the <literal>HEAD</literal> link is supposed to always\r
+point to the branch you are working on right now, and you always\r
+start out expecting to work on the <literal>master</literal> branch.</simpara>\r
+<simpara>However, this is only a convention, and you can name your branches\r
+anything you want, and don&#8217;t have to ever even <emphasis>have</emphasis> a <literal>master</literal>\r
+branch. A number of the git tools will assume that <literal>.git/HEAD</literal> is\r
+valid, though.</simpara>\r
+<note><simpara>An <emphasis>object</emphasis> is identified by its 160-bit SHA1 hash, aka <emphasis>object name</emphasis>,\r
+and a reference to an object is always the 40-byte hex\r
+representation of that SHA1 name. The files in the &#8216;refs`\r
+subdirectory are expected to contain these hex references\r
+(usually with a final <literal>&#8217;\n\'</literal> at the end), and you should thus\r
+expect to see a number of 41-byte files containing these\r
+references in these <literal>refs</literal> subdirectories when you actually start\r
+populating your tree.</simpara></note>\r
+<note><simpara>An advanced user may want to take a look at <xref linkend="gitrepository-layout(5)"/>\r
+after finishing this tutorial.</simpara></note>\r
+<simpara>You have now created your first git repository. Of course, since it&#8217;s\r
+empty, that&#8217;s not very useful, so let&#8217;s start populating it with data.</simpara>\r
+</simplesect>\r
+<simplesect id="_populating_a_git_repository">\r
+<title>Populating a git repository</title>\r
+<simpara>We&#8217;ll keep this simple and stupid, so we&#8217;ll start off with populating a\r
+few trivial files just to get a feel for it.</simpara>\r
+<simpara>Start off with just creating any random files that you want to maintain\r
+in your git repository. We&#8217;ll start off with a few bad examples, just to\r
+get a feel for how this works:</simpara>\r
+<literallayout>$ echo "Hello World" &gt;hello\r
+$ echo "Silly example" &gt;example</literallayout>\r
+<simpara>you have now created two files in your working tree (aka <emphasis>working directory</emphasis>),\r
+but to actually check in your hard work, you will have to go through two steps:</simpara>\r
+<itemizedlist>\r
+<listitem>\r
+<simpara>\r
+fill in the <emphasis>index</emphasis> file (aka <emphasis>cache</emphasis>) with the information about your\r
+   working tree state.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+commit that index file as an object.\r
+</simpara>\r
+</listitem>\r
+</itemizedlist>\r
+<simpara>The first step is trivial: when you want to tell git about any changes\r
+to your working tree, you use the <emphasis>git-update-index</emphasis> program. That\r
+program normally just takes a list of filenames you want to update, but\r
+to avoid trivial mistakes, it refuses to add new entries to the index\r
+(or remove existing ones) unless you explicitly tell it that you&#8217;re\r
+adding a new entry with the <literal>--add</literal> flag (or removing an entry with the\r
+<literal>--remove</literal>) flag.</simpara>\r
+<simpara>So to populate the index with the two files you just created, you can do</simpara>\r
+<literallayout>$ git update-index --add hello example</literallayout>\r
+<simpara>and you have now told git to track those two files.</simpara>\r
+<simpara>In fact, as you did that, if you now look into your object directory,\r
+you&#8217;ll notice that git will have added two new objects to the object\r
+database. If you did exactly the steps above, you should now be able to do</simpara>\r
+<literallayout>$ ls .git/objects/??/*</literallayout>\r
+<simpara>and see two files:</simpara>\r
+<literallayout>.git/objects/55/7db03de997c86a4a028e1ebd3a1ceb225be238\r
+.git/objects/f2/4c74a2e500f5ee1332c86b94199f52b1d1d962</literallayout>\r
+<simpara>which correspond with the objects with names of <literal>557db&#8230;</literal> and\r
+<literal>f24c7&#8230;</literal> respectively.</simpara>\r
+<simpara>If you want to, you can use <emphasis>git-cat-file</emphasis> to look at those objects, but\r
+you&#8217;ll have to use the object name, not the filename of the object:</simpara>\r
+<literallayout>$ git cat-file -t 557db03de997c86a4a028e1ebd3a1ceb225be238</literallayout>\r
+<simpara>where the <literal>-t</literal> tells <emphasis>git-cat-file</emphasis> to tell you what the "type" of the\r
+object is. git will tell you that you have a "blob" object (i.e., just a\r
+regular file), and you can see the contents with</simpara>\r
+<literallayout>$ git cat-file "blob" 557db03</literallayout>\r
+<simpara>which will print out "Hello World". The object <literal>557db03</literal> is nothing\r
+more than the contents of your file <literal>hello</literal>.</simpara>\r
+<note><simpara>Don&#8217;t confuse that object with the file <literal>hello</literal> itself. The\r
+object is literally just those specific <emphasis role="strong">contents</emphasis> of the file, and\r
+however much you later change the contents in file <literal>hello</literal>, the object\r
+we just looked at will never change. Objects are immutable.</simpara></note>\r
+<note><simpara>The second example demonstrates that you can\r
+abbreviate the object name to only the first several\r
+hexadecimal digits in most places.</simpara></note>\r
+<simpara>Anyway, as we mentioned previously, you normally never actually take a\r
+look at the objects themselves, and typing long 40-character hex\r
+names is not something you&#8217;d normally want to do. The above digression\r
+was just to show that <emphasis>git-update-index</emphasis> did something magical, and\r
+actually saved away the contents of your files into the git object\r
+database.</simpara>\r
+<simpara>Updating the index did something else too: it created a <literal>.git/index</literal>\r
+file. This is the index that describes your current working tree, and\r
+something you should be very aware of. Again, you normally never worry\r
+about the index file itself, but you should be aware of the fact that\r
+you have not actually really "checked in" your files into git so far,\r
+you&#8217;ve only <emphasis role="strong">told</emphasis> git about them.</simpara>\r
+<simpara>However, since git knows about them, you can now start using some of the\r
+most basic git commands to manipulate the files or look at their status.</simpara>\r
+<simpara>In particular, let&#8217;s not even check in the two files into git yet, we&#8217;ll\r
+start off by adding another line to <literal>hello</literal> first:</simpara>\r
+<literallayout>$ echo "It's a new day for git" &gt;&gt;hello</literallayout>\r
+<simpara>and you can now, since you told git about the previous state of <literal>hello</literal>, ask\r
+git what has changed in the tree compared to your old index, using the\r
+<emphasis>git-diff-files</emphasis> command:</simpara>\r
+<literallayout>$ git diff-files</literallayout>\r
+<simpara>Oops. That wasn&#8217;t very readable. It just spit out its own internal\r
+version of a <emphasis>diff</emphasis>, but that internal version really just tells you\r
+that it has noticed that "hello" has been modified, and that the old object\r
+contents it had have been replaced with something else.</simpara>\r
+<simpara>To make it readable, we can tell <emphasis>git-diff-files</emphasis> to output the\r
+differences as a patch, using the <literal>-p</literal> flag:</simpara>\r
+<literallayout>$ git diff-files -p\r
+diff --git a/hello b/hello\r
+index 557db03..263414f 100644\r
+--- a/hello\r
++++ b/hello\r
+@@ -1 +1,2 @@\r
+ Hello World\r
++It's a new day for git</literallayout>\r
+<simpara>i.e. the diff of the change we caused by adding another line to <literal>hello</literal>.</simpara>\r
+<simpara>In other words, <emphasis>git-diff-files</emphasis> always shows us the difference between\r
+what is recorded in the index, and what is currently in the working\r
+tree. That&#8217;s very useful.</simpara>\r
+<simpara>A common shorthand for <literal>git diff-files -p</literal> is to just write <literal>git\r
+diff</literal>, which will do the same thing.</simpara>\r
+<literallayout>$ git diff\r
+diff --git a/hello b/hello\r
+index 557db03..263414f 100644\r
+--- a/hello\r
++++ b/hello\r
+@@ -1 +1,2 @@\r
+ Hello World\r
++It's a new day for git</literallayout>\r
+</simplesect>\r
+<simplesect id="_committing_git_state">\r
+<title>Committing git state</title>\r
+<simpara>Now, we want to go to the next stage in git, which is to take the files\r
+that git knows about in the index, and commit them as a real tree. We do\r
+that in two phases: creating a <emphasis>tree</emphasis> object, and committing that <emphasis>tree</emphasis>\r
+object as a <emphasis>commit</emphasis> object together with an explanation of what the\r
+tree was all about, along with information of how we came to that state.</simpara>\r
+<simpara>Creating a tree object is trivial, and is done with <emphasis>git-write-tree</emphasis>.\r
+There are no options or other input: <literal>git write-tree</literal> will take the\r
+current index state, and write an object that describes that whole\r
+index. In other words, we&#8217;re now tying together all the different\r
+filenames with their contents (and their permissions), and we&#8217;re\r
+creating the equivalent of a git "directory" object:</simpara>\r
+<literallayout>$ git write-tree</literallayout>\r
+<simpara>and this will just output the name of the resulting tree, in this case\r
+(if you have done exactly as I&#8217;ve described) it should be</simpara>\r
+<literallayout>8988da15d077d4829fc51d8544c097def6644dbb</literallayout>\r
+<simpara>which is another incomprehensible object name. Again, if you want to,\r
+you can use <literal>git cat-file -t 8988d...</literal> to see that this time the object\r
+is not a "blob" object, but a "tree" object (you can also use\r
+<literal>git cat-file</literal> to actually output the raw object contents, but you&#8217;ll see\r
+mainly a binary mess, so that&#8217;s less interesting).</simpara>\r
+<simpara>However&#8201;&#8212;&#8201;normally you&#8217;d never use <emphasis>git-write-tree</emphasis> on its own, because\r
+normally you always commit a tree into a commit object using the\r
+<emphasis>git-commit-tree</emphasis> command. In fact, it&#8217;s easier to not actually use\r
+<emphasis>git-write-tree</emphasis> on its own at all, but to just pass its result in as an\r
+argument to <emphasis>git-commit-tree</emphasis>.</simpara>\r
+<simpara><emphasis>git-commit-tree</emphasis> normally takes several arguments&#8201;&#8212;&#8201;it wants to know\r
+what the <emphasis>parent</emphasis> of a commit was, but since this is the first commit\r
+ever in this new repository, and it has no parents, we only need to pass in\r
+the object name of the tree. However, <emphasis>git-commit-tree</emphasis> also wants to get a\r
+commit message on its standard input, and it will write out the resulting\r
+object name for the commit to its standard output.</simpara>\r
+<simpara>And this is where we create the <literal>.git/refs/heads/master</literal> file\r
+which is pointed at by <literal>HEAD</literal>. This file is supposed to contain\r
+the reference to the top-of-tree of the master branch, and since\r
+that&#8217;s exactly what <emphasis>git-commit-tree</emphasis> spits out, we can do this\r
+all with a sequence of simple shell commands:</simpara>\r
+<literallayout>$ tree=$(git write-tree)\r
+$ commit=$(echo 'Initial commit' | git commit-tree $tree)\r
+$ git update-ref HEAD $commit</literallayout>\r
+<simpara>In this case this creates a totally new commit that is not related to\r
+anything else. Normally you do this only <emphasis role="strong">once</emphasis> for a project ever, and\r
+all later commits will be parented on top of an earlier commit.</simpara>\r
+<simpara>Again, normally you&#8217;d never actually do this by hand. There is a\r
+helpful script called <literal>git commit</literal> that will do all of this for you. So\r
+you could have just written <literal>git commit</literal>\r
+instead, and it would have done the above magic scripting for you.</simpara>\r
+</simplesect>\r
+<simplesect id="_making_a_change">\r
+<title>Making a change</title>\r
+<simpara>Remember how we did the <emphasis>git-update-index</emphasis> on file <literal>hello</literal> and then we\r
+changed <literal>hello</literal> afterward, and could compare the new state of <literal>hello</literal> with the\r
+state we saved in the index file?</simpara>\r
+<simpara>Further, remember how I said that <emphasis>git-write-tree</emphasis> writes the contents\r
+of the <emphasis role="strong">index</emphasis> file to the tree, and thus what we just committed was in\r
+fact the <emphasis role="strong">original</emphasis> contents of the file <literal>hello</literal>, not the new ones. We did\r
+that on purpose, to show the difference between the index state, and the\r
+state in the working tree, and how they don&#8217;t have to match, even\r
+when we commit things.</simpara>\r
+<simpara>As before, if we do <literal>git diff-files -p</literal> in our git-tutorial project,\r
+we&#8217;ll still see the same difference we saw last time: the index file\r
+hasn&#8217;t changed by the act of committing anything. However, now that we\r
+have committed something, we can also learn to use a new command:\r
+<emphasis>git-diff-index</emphasis>.</simpara>\r
+<simpara>Unlike <emphasis>git-diff-files</emphasis>, which showed the difference between the index\r
+file and the working tree, <emphasis>git-diff-index</emphasis> shows the differences\r
+between a committed <emphasis role="strong">tree</emphasis> and either the index file or the working\r
+tree. In other words, <emphasis>git-diff-index</emphasis> wants a tree to be diffed\r
+against, and before we did the commit, we couldn&#8217;t do that, because we\r
+didn&#8217;t have anything to diff against.</simpara>\r
+<simpara>But now we can do</simpara>\r
+<literallayout>$ git diff-index -p HEAD</literallayout>\r
+<simpara>(where <literal>-p</literal> has the same meaning as it did in <emphasis>git-diff-files</emphasis>), and it\r
+will show us the same difference, but for a totally different reason.\r
+Now we&#8217;re comparing the working tree not against the index file,\r
+but against the tree we just wrote. It just so happens that those two\r
+are obviously the same, so we get the same result.</simpara>\r
+<simpara>Again, because this is a common operation, you can also just shorthand\r
+it with</simpara>\r
+<literallayout>$ git diff HEAD</literallayout>\r
+<simpara>which ends up doing the above for you.</simpara>\r
+<simpara>In other words, <emphasis>git-diff-index</emphasis> normally compares a tree against the\r
+working tree, but when given the <literal>--cached</literal> flag, it is told to\r
+instead compare against just the index cache contents, and ignore the\r
+current working tree state entirely. Since we just wrote the index\r
+file to HEAD, doing <literal>git diff-index --cached -p HEAD</literal> should thus return\r
+an empty set of differences, and that&#8217;s exactly what it does.</simpara>\r
+<note>\r
+<simpara><emphasis>git-diff-index</emphasis> really always uses the index for its\r
+comparisons, and saying that it compares a tree against the working\r
+tree is thus not strictly accurate. In particular, the list of\r
+files to compare (the "meta-data") <emphasis role="strong">always</emphasis> comes from the index file,\r
+regardless of whether the <literal>--cached</literal> flag is used or not. The <literal>--cached</literal>\r
+flag really only determines whether the file <emphasis role="strong">contents</emphasis> to be compared\r
+come from the working tree or not.</simpara>\r
+<simpara>This is not hard to understand, as soon as you realize that git simply\r
+never knows (or cares) about files that it is not told about\r
+explicitly. git will never go <emphasis role="strong">looking</emphasis> for files to compare, it\r
+expects you to tell it what the files are, and that&#8217;s what the index\r
+is there for.</simpara>\r
+</note>\r
+<simpara>However, our next step is to commit the <emphasis role="strong">change</emphasis> we did, and again, to\r
+understand what&#8217;s going on, keep in mind the difference between "working\r
+tree contents", "index file" and "committed tree". We have changes\r
+in the working tree that we want to commit, and we always have to\r
+work through the index file, so the first thing we need to do is to\r
+update the index cache:</simpara>\r
+<literallayout>$ git update-index hello</literallayout>\r
+<simpara>(note how we didn&#8217;t need the <literal>--add</literal> flag this time, since git knew\r
+about the file already).</simpara>\r
+<simpara>Note what happens to the different <emphasis>git-diff-*</emphasis> versions here. After\r
+we&#8217;ve updated <literal>hello</literal> in the index, <literal>git diff-files -p</literal> now shows no\r
+differences, but <literal>git diff-index -p HEAD</literal> still <emphasis role="strong">does</emphasis> show that the\r
+current state is different from the state we committed. In fact, now\r
+<emphasis>git-diff-index</emphasis> shows the same difference whether we use the <literal>--cached</literal>\r
+flag or not, since now the index is coherent with the working tree.</simpara>\r
+<simpara>Now, since we&#8217;ve updated <literal>hello</literal> in the index, we can commit the new\r
+version. We could do it by writing the tree by hand again, and\r
+committing the tree (this time we&#8217;d have to use the <literal>-p HEAD</literal> flag to\r
+tell commit that the HEAD was the <emphasis role="strong">parent</emphasis> of the new commit, and that\r
+this wasn&#8217;t an initial commit any more), but you&#8217;ve done that once\r
+already, so let&#8217;s just use the helpful script this time:</simpara>\r
+<literallayout>$ git commit</literallayout>\r
+<simpara>which starts an editor for you to write the commit message and tells you\r
+a bit about what you have done.</simpara>\r
+<simpara>Write whatever message you want, and all the lines that start with <emphasis>#</emphasis>\r
+will be pruned out, and the rest will be used as the commit message for\r
+the change. If you decide you don&#8217;t want to commit anything after all at\r
+this point (you can continue to edit things and update the index), you\r
+can just leave an empty message. Otherwise <literal>git commit</literal> will commit\r
+the change for you.</simpara>\r
+<simpara>You&#8217;ve now made your first real git commit. And if you&#8217;re interested in\r
+looking at what <literal>git commit</literal> really does, feel free to investigate:\r
+it&#8217;s a few very simple shell scripts to generate the helpful (?) commit\r
+message headers, and a few one-liners that actually do the\r
+commit itself (<emphasis>git-commit</emphasis>).</simpara>\r
+</simplesect>\r
+<simplesect id="_inspecting_changes">\r
+<title>Inspecting Changes</title>\r
+<simpara>While creating changes is useful, it&#8217;s even more useful if you can tell\r
+later what changed. The most useful command for this is another of the\r
+<emphasis>diff</emphasis> family, namely <emphasis>git-diff-tree</emphasis>.</simpara>\r
+<simpara><emphasis>git-diff-tree</emphasis> can be given two arbitrary trees, and it will tell you the\r
+differences between them. Perhaps even more commonly, though, you can\r
+give it just a single commit object, and it will figure out the parent\r
+of that commit itself, and show the difference directly. Thus, to get\r
+the same diff that we&#8217;ve already seen several times, we can now do</simpara>\r
+<literallayout>$ git diff-tree -p HEAD</literallayout>\r
+<simpara>(again, <literal>-p</literal> means to show the difference as a human-readable patch),\r
+and it will show what the last commit (in <literal>HEAD</literal>) actually changed.</simpara>\r
+<note>\r
+<simpara>Here is an ASCII art by Jon Loeliger that illustrates how\r
+various diff-\* commands compare things.</simpara>\r
+<literallayout class="monospaced">            diff-tree\r
+             +----+\r
+             |    |\r
+             |    |\r
+             V    V\r
+          +-----------+\r
+          | Object DB |\r
+          |  Backing  |\r
+          |   Store   |\r
+          +-----------+\r
+            ^    ^\r
+            |    |\r
+            |    |  diff-index --cached\r
+            |    |\r
+diff-index  |    V\r
+            |  +-----------+\r
+            |  |   Index   |\r
+            |  |  "cache"  |\r
+            |  +-----------+\r
+            |    ^\r
+            |    |\r
+            |    |  diff-files\r
+            |    |\r
+            V    V\r
+          +-----------+\r
+          |  Working  |\r
+          | Directory |\r
+          +-----------+</literallayout>\r
+</note>\r
+<simpara>More interestingly, you can also give <emphasis>git-diff-tree</emphasis> the <literal>--pretty</literal> flag,\r
+which tells it to also show the commit message and author and date of the\r
+commit, and you can tell it to show a whole series of diffs.\r
+Alternatively, you can tell it to be "silent", and not show the diffs at\r
+all, but just show the actual commit message.</simpara>\r
+<simpara>In fact, together with the <emphasis>git-rev-list</emphasis> program (which generates a\r
+list of revisions), <emphasis>git-diff-tree</emphasis> ends up being a veritable fount of\r
+changes. A trivial (but very useful) script called <emphasis>git-whatchanged</emphasis> is\r
+included with git which does exactly this, and shows a log of recent\r
+activities.</simpara>\r
+<simpara>To see the whole history of our pitiful little git-tutorial project, you\r
+can do</simpara>\r
+<literallayout>$ git log</literallayout>\r
+<simpara>which shows just the log messages, or if we want to see the log together\r
+with the associated patches use the more complex (and much more\r
+powerful)</simpara>\r
+<literallayout>$ git whatchanged -p</literallayout>\r
+<simpara>and you will see exactly what has changed in the repository over its\r
+short history.</simpara>\r
+<note><simpara>When using the above two commands, the initial commit will be shown.\r
+If this is a problem because it is huge, you can hide it by setting\r
+the log.showroot configuration variable to false. Having this, you\r
+can still show it for each command just adding the <literal>--root</literal> option,\r
+which is a flag for <emphasis>git-diff-tree</emphasis> accepted by both commands.</simpara></note>\r
+<simpara>With that, you should now be having some inkling of what git does, and\r
+can explore on your own.</simpara>\r
+<note><simpara>Most likely, you are not directly using the core\r
+git Plumbing commands, but using Porcelain such as <emphasis>git-add</emphasis>, &#8216;git-rm&#8217;\r
+and &#8216;git-commit&#8217;.</simpara></note>\r
+</simplesect>\r
+<simplesect id="_tagging_a_version">\r
+<title>Tagging a version</title>\r
+<simpara>In git, there are two kinds of tags, a "light" one, and an "annotated tag".</simpara>\r
+<simpara>A "light" tag is technically nothing more than a branch, except we put\r
+it in the <literal>.git/refs/tags/</literal> subdirectory instead of calling it a <literal>head</literal>.\r
+So the simplest form of tag involves nothing more than</simpara>\r
+<literallayout>$ git tag my-first-tag</literallayout>\r
+<simpara>which just writes the current <literal>HEAD</literal> into the <literal>.git/refs/tags/my-first-tag</literal>\r
+file, after which point you can then use this symbolic name for that\r
+particular state. You can, for example, do</simpara>\r
+<literallayout>$ git diff my-first-tag</literallayout>\r
+<simpara>to diff your current state against that tag which at this point will\r
+obviously be an empty diff, but if you continue to develop and commit\r
+stuff, you can use your tag as an "anchor-point" to see what has changed\r
+since you tagged it.</simpara>\r
+<simpara>An "annotated tag" is actually a real git object, and contains not only a\r
+pointer to the state you want to tag, but also a small tag name and\r
+message, along with optionally a PGP signature that says that yes,\r
+you really did\r
+that tag. You create these annotated tags with either the <literal>-a</literal> or\r
+<literal>-s</literal> flag to <emphasis>git-tag</emphasis>:</simpara>\r
+<literallayout>$ git tag -s &lt;tagname&gt;</literallayout>\r
+<simpara>which will sign the current <literal>HEAD</literal> (but you can also give it another\r
+argument that specifies the thing to tag, i.e., you could have tagged the\r
+current <literal>mybranch</literal> point by using <literal>git tag &lt;tagname&gt; mybranch</literal>).</simpara>\r
+<simpara>You normally only do signed tags for major releases or things\r
+like that, while the light-weight tags are useful for any marking you\r
+want to do&#8201;&#8212;&#8201;any time you decide that you want to remember a certain\r
+point, just create a private tag for it, and you have a nice symbolic\r
+name for the state at that point.</simpara>\r
+</simplesect>\r
+<simplesect id="_copying_repositories">\r
+<title>Copying repositories</title>\r
+<simpara>git repositories are normally totally self-sufficient and relocatable.\r
+Unlike CVS, for example, there is no separate notion of\r
+"repository" and "working tree". A git repository normally <emphasis role="strong">is</emphasis> the\r
+working tree, with the local git information hidden in the <literal>.git</literal>\r
+subdirectory. There is nothing else. What you see is what you got.</simpara>\r
+<note><simpara>You can tell git to split the git internal information from\r
+the directory that it tracks, but we&#8217;ll ignore that for now: it&#8217;s not\r
+how normal projects work, and it&#8217;s really only meant for special uses.\r
+So the mental model of "the git information is always tied directly to\r
+the working tree that it describes" may not be technically 100%\r
+accurate, but it&#8217;s a good model for all normal use.</simpara></note>\r
+<simpara>This has two implications:</simpara>\r
+<itemizedlist>\r
+<listitem>\r
+<simpara>\r
+if you grow bored with the tutorial repository you created (or you&#8217;ve\r
+   made a mistake and want to start all over), you can just do simple\r
+</simpara>\r
+<literallayout>$ rm -rf git-tutorial</literallayout>\r
+<simpara>and it will be gone. There&#8217;s no external repository, and there&#8217;s no\r
+history outside the project you created.</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+if you want to move or duplicate a git repository, you can do so. There\r
+   is <emphasis>git-clone</emphasis> command, but if all you want to do is just to\r
+   create a copy of your repository (with all the full history that\r
+   went along with it), you can do so with a regular\r
+   <literal>cp -a git-tutorial new-git-tutorial</literal>.\r
+</simpara>\r
+<simpara>Note that when you&#8217;ve moved or copied a git repository, your git index\r
+file (which caches various information, notably some of the "stat"\r
+information for the files involved) will likely need to be refreshed.\r
+So after you do a <literal>cp -a</literal> to create a new copy, you&#8217;ll want to do</simpara>\r
+<literallayout>$ git update-index --refresh</literallayout>\r
+<simpara>in the new repository to make sure that the index file is up-to-date.</simpara>\r
+</listitem>\r
+</itemizedlist>\r
+<simpara>Note that the second point is true even across machines. You can\r
+duplicate a remote git repository with <emphasis role="strong">any</emphasis> regular copy mechanism, be it\r
+<emphasis>scp</emphasis>, <emphasis>rsync</emphasis> or <emphasis>wget</emphasis>.</simpara>\r
+<simpara>When copying a remote repository, you&#8217;ll want to at a minimum update the\r
+index cache when you do this, and especially with other peoples'\r
+repositories you often want to make sure that the index cache is in some\r
+known state (you don&#8217;t know <emphasis role="strong">what</emphasis> they&#8217;ve done and not yet checked in),\r
+so usually you&#8217;ll precede the <emphasis>git-update-index</emphasis> with a</simpara>\r
+<literallayout>$ git read-tree --reset HEAD\r
+$ git update-index --refresh</literallayout>\r
+<simpara>which will force a total index re-build from the tree pointed to by <literal>HEAD</literal>.\r
+It resets the index contents to <literal>HEAD</literal>, and then the <emphasis>git-update-index</emphasis>\r
+makes sure to match up all index entries with the checked-out files.\r
+If the original repository had uncommitted changes in its\r
+working tree, <literal>git update-index --refresh</literal> notices them and\r
+tells you they need to be updated.</simpara>\r
+<simpara>The above can also be written as simply</simpara>\r
+<literallayout>$ git reset</literallayout>\r
+<simpara>and in fact a lot of the common git command combinations can be scripted\r
+with the <literal>git xyz</literal> interfaces.  You can learn things by just looking\r
+at what the various git scripts do.  For example, <literal>git reset</literal> used to be\r
+the above two lines implemented in <emphasis>git-reset</emphasis>, but some things like\r
+<emphasis>git-status</emphasis> and <emphasis>git-commit</emphasis> are slightly more complex scripts around\r
+the basic git commands.</simpara>\r
+<simpara>Many (most?) public remote repositories will not contain any of\r
+the checked out files or even an index file, and will <emphasis role="strong">only</emphasis> contain the\r
+actual core git files. Such a repository usually doesn&#8217;t even have the\r
+<literal>.git</literal> subdirectory, but has all the git files directly in the\r
+repository.</simpara>\r
+<simpara>To create your own local live copy of such a "raw" git repository, you&#8217;d\r
+first create your own subdirectory for the project, and then copy the\r
+raw repository contents into the <literal>.git</literal> directory. For example, to\r
+create your own copy of the git repository, you&#8217;d do the following</simpara>\r
+<literallayout>$ mkdir my-git\r
+$ cd my-git\r
+$ rsync -rL rsync://rsync.kernel.org/pub/scm/git/git.git/ .git</literallayout>\r
+<simpara>followed by</simpara>\r
+<literallayout>$ git read-tree HEAD</literallayout>\r
+<simpara>to populate the index. However, now you have populated the index, and\r
+you have all the git internal files, but you will notice that you don&#8217;t\r
+actually have any of the working tree files to work on. To get\r
+those, you&#8217;d check them out with</simpara>\r
+<literallayout>$ git checkout-index -u -a</literallayout>\r
+<simpara>where the <literal>-u</literal> flag means that you want the checkout to keep the index\r
+up-to-date (so that you don&#8217;t have to refresh it afterward), and the\r
+<literal>-a</literal> flag means "check out all files" (if you have a stale copy or an\r
+older version of a checked out tree you may also need to add the <literal>-f</literal>\r
+flag first, to tell <emphasis>git-checkout-index</emphasis> to <emphasis role="strong">force</emphasis> overwriting of any old\r
+files).</simpara>\r
+<simpara>Again, this can all be simplified with</simpara>\r
+<literallayout>$ git clone rsync://rsync.kernel.org/pub/scm/git/git.git/ my-git\r
+$ cd my-git\r
+$ git checkout</literallayout>\r
+<simpara>which will end up doing all of the above for you.</simpara>\r
+<simpara>You have now successfully copied somebody else&#8217;s (mine) remote\r
+repository, and checked it out.</simpara>\r
+</simplesect>\r
+<simplesect id="_creating_a_new_branch">\r
+<title>Creating a new branch</title>\r
+<simpara>Branches in git are really nothing more than pointers into the git\r
+object database from within the <literal>.git/refs/</literal> subdirectory, and as we\r
+already discussed, the <literal>HEAD</literal> branch is nothing but a symlink to one of\r
+these object pointers.</simpara>\r
+<simpara>You can at any time create a new branch by just picking an arbitrary\r
+point in the project history, and just writing the SHA1 name of that\r
+object into a file under <literal>.git/refs/heads/</literal>. You can use any filename you\r
+want (and indeed, subdirectories), but the convention is that the\r
+"normal" branch is called <literal>master</literal>. That&#8217;s just a convention, though,\r
+and nothing enforces it.</simpara>\r
+<simpara>To show that as an example, let&#8217;s go back to the git-tutorial repository we\r
+used earlier, and create a branch in it. You do that by simply just\r
+saying that you want to check out a new branch:</simpara>\r
+<literallayout>$ git checkout -b mybranch</literallayout>\r
+<simpara>will create a new branch based at the current <literal>HEAD</literal> position, and switch\r
+to it.</simpara>\r
+<note>\r
+<simpara>If you make the decision to start your new branch at some\r
+other point in the history than the current <literal>HEAD</literal>, you can do so by\r
+just telling <emphasis>git-checkout</emphasis> what the base of the checkout would be.\r
+In other words, if you have an earlier tag or branch, you&#8217;d just do</simpara>\r
+<literallayout>$ git checkout -b mybranch earlier-commit</literallayout>\r
+<simpara>and it would create the new branch <literal>mybranch</literal> at the earlier commit,\r
+and check out the state at that time.</simpara>\r
+</note>\r
+<simpara>You can always just jump back to your original <literal>master</literal> branch by doing</simpara>\r
+<literallayout>$ git checkout master</literallayout>\r
+<simpara>(or any other branch-name, for that matter) and if you forget which\r
+branch you happen to be on, a simple</simpara>\r
+<literallayout>$ cat .git/HEAD</literallayout>\r
+<simpara>will tell you where it&#8217;s pointing.  To get the list of branches\r
+you have, you can say</simpara>\r
+<literallayout>$ git branch</literallayout>\r
+<simpara>which used to be nothing more than a simple script around <literal>ls .git/refs/heads</literal>.\r
+There will be an asterisk in front of the branch you are currently on.</simpara>\r
+<simpara>Sometimes you may wish to create a new branch <emphasis>without</emphasis> actually\r
+checking it out and switching to it. If so, just use the command</simpara>\r
+<literallayout>$ git branch &lt;branchname&gt; [startingpoint]</literallayout>\r
+<simpara>which will simply <emphasis>create</emphasis> the branch, but will not do anything further.\r
+You can then later&#8201;&#8212;&#8201;once you decide that you want to actually develop\r
+on that branch&#8201;&#8212;&#8201;switch to that branch with a regular <emphasis>git-checkout</emphasis>\r
+with the branchname as the argument.</simpara>\r
+</simplesect>\r
+<simplesect id="_merging_two_branches">\r
+<title>Merging two branches</title>\r
+<simpara>One of the ideas of having a branch is that you do some (possibly\r
+experimental) work in it, and eventually merge it back to the main\r
+branch. So assuming you created the above <literal>mybranch</literal> that started out\r
+being the same as the original <literal>master</literal> branch, let&#8217;s make sure we&#8217;re in\r
+that branch, and do some work there.</simpara>\r
+<literallayout>$ git checkout mybranch\r
+$ echo "Work, work, work" &gt;&gt;hello\r
+$ git commit -m "Some work." -i hello</literallayout>\r
+<simpara>Here, we just added another line to <literal>hello</literal>, and we used a shorthand for\r
+doing both <literal>git update-index hello</literal> and <literal>git commit</literal> by just giving the\r
+filename directly to <literal>git commit</literal>, with an <literal>-i</literal> flag (it tells\r
+git to <emphasis>include</emphasis> that file in addition to what you have done to\r
+the index file so far when making the commit).  The <literal>-m</literal> flag is to give the\r
+commit log message from the command line.</simpara>\r
+<simpara>Now, to make it a bit more interesting, let&#8217;s assume that somebody else\r
+does some work in the original branch, and simulate that by going back\r
+to the master branch, and editing the same file differently there:</simpara>\r
+<literallayout>$ git checkout master</literallayout>\r
+<simpara>Here, take a moment to look at the contents of <literal>hello</literal>, and notice how they\r
+don&#8217;t contain the work we just did in <literal>mybranch</literal>&#8201;&#8212;&#8201;because that work\r
+hasn&#8217;t happened in the <literal>master</literal> branch at all. Then do</simpara>\r
+<literallayout>$ echo "Play, play, play" &gt;&gt;hello\r
+$ echo "Lots of fun" &gt;&gt;example\r
+$ git commit -m "Some fun." -i hello example</literallayout>\r
+<simpara>since the master branch is obviously in a much better mood.</simpara>\r
+<simpara>Now, you&#8217;ve got two branches, and you decide that you want to merge the\r
+work done. Before we do that, let&#8217;s introduce a cool graphical tool that\r
+helps you view what&#8217;s going on:</simpara>\r
+<literallayout>$ gitk --all</literallayout>\r
+<simpara>will show you graphically both of your branches (that&#8217;s what the <literal>--all</literal>\r
+means: normally it will just show you your current <literal>HEAD</literal>) and their\r
+histories. You can also see exactly how they came to be from a common\r
+source.</simpara>\r
+<simpara>Anyway, let&#8217;s exit <emphasis>gitk</emphasis> (<literal>^Q</literal> or the File menu), and decide that we want\r
+to merge the work we did on the <literal>mybranch</literal> branch into the <literal>master</literal>\r
+branch (which is currently our <literal>HEAD</literal> too). To do that, there&#8217;s a nice\r
+script called <emphasis>git-merge</emphasis>, which wants to know which branches you want\r
+to resolve and what the merge is all about:</simpara>\r
+<literallayout>$ git merge -m "Merge work in mybranch" mybranch</literallayout>\r
+<simpara>where the first argument is going to be used as the commit message if\r
+the merge can be resolved automatically.</simpara>\r
+<simpara>Now, in this case we&#8217;ve intentionally created a situation where the\r
+merge will need to be fixed up by hand, though, so git will do as much\r
+of it as it can automatically (which in this case is just merge the <literal>example</literal>\r
+file, which had no differences in the <literal>mybranch</literal> branch), and say:</simpara>\r
+<literallayout>        Auto-merging hello\r
+        CONFLICT (content): Merge conflict in hello\r
+        Automatic merge failed; fix conflicts and then commit the result.</literallayout>\r
+<simpara>It tells you that it did an "Automatic merge", which\r
+failed due to conflicts in <literal>hello</literal>.</simpara>\r
+<simpara>Not to worry. It left the (trivial) conflict in <literal>hello</literal> in the same form you\r
+should already be well used to if you&#8217;ve ever used CVS, so let&#8217;s just\r
+open <literal>hello</literal> in our editor (whatever that may be), and fix it up somehow.\r
+I&#8217;d suggest just making it so that <literal>hello</literal> contains all four lines:</simpara>\r
+<literallayout>Hello World\r
+It's a new day for git\r
+Play, play, play\r
+Work, work, work</literallayout>\r
+<simpara>and once you&#8217;re happy with your manual merge, just do a</simpara>\r
+<literallayout>$ git commit -i hello</literallayout>\r
+<simpara>which will very loudly warn you that you&#8217;re now committing a merge\r
+(which is correct, so never mind), and you can write a small merge\r
+message about your adventures in <emphasis>git-merge</emphasis>-land.</simpara>\r
+<simpara>After you&#8217;re done, start up <literal>gitk --all</literal> to see graphically what the\r
+history looks like. Notice that <literal>mybranch</literal> still exists, and you can\r
+switch to it, and continue to work with it if you want to. The\r
+<literal>mybranch</literal> branch will not contain the merge, but next time you merge it\r
+from the <literal>master</literal> branch, git will know how you merged it, so you&#8217;ll not\r
+have to do <emphasis>that</emphasis> merge again.</simpara>\r
+<simpara>Another useful tool, especially if you do not always work in X-Window\r
+environment, is <literal>git show-branch</literal>.</simpara>\r
+<literallayout>$ git show-branch --topo-order --more=1 master mybranch\r
+* [master] Merge work in mybranch\r
+ ! [mybranch] Some work.\r
+--\r
+-  [master] Merge work in mybranch\r
+*+ [mybranch] Some work.\r
+*  [master^] Some fun.</literallayout>\r
+<simpara>The first two lines indicate that it is showing the two branches\r
+and the first line of the commit log message from their\r
+top-of-the-tree commits, you are currently on <literal>master</literal> branch\r
+(notice the asterisk <literal>*</literal> character), and the first column for\r
+the later output lines is used to show commits contained in the\r
+<literal>master</literal> branch, and the second column for the <literal>mybranch</literal>\r
+branch. Three commits are shown along with their log messages.\r
+All of them have non blank characters in the first column (<literal>*</literal>\r
+shows an ordinary commit on the current branch, <literal>-</literal> is a merge commit), which\r
+means they are now part of the <literal>master</literal> branch. Only the "Some\r
+work" commit has the plus <literal>+</literal> character in the second column,\r
+because <literal>mybranch</literal> has not been merged to incorporate these\r
+commits from the master branch.  The string inside brackets\r
+before the commit log message is a short name you can use to\r
+name the commit.  In the above example, <emphasis>master</emphasis> and <emphasis>mybranch</emphasis>\r
+are branch heads.  <emphasis>master^</emphasis> is the first parent of <emphasis>master</emphasis>\r
+branch head.  Please see <xref linkend="git-rev-parse(1)"/> if you want to\r
+see more complex cases.</simpara>\r
+<note><simpara>Without the <emphasis>--more=1</emphasis> option, <emphasis>git-show-branch</emphasis> would not output the\r
+<emphasis>[master^]</emphasis> commit, as <emphasis>[mybranch]</emphasis> commit is a common ancestor of\r
+both <emphasis>master</emphasis> and <emphasis>mybranch</emphasis> tips.  Please see <xref linkend="git-show-branch(1)"/>\r
+for details.</simpara></note>\r
+<note><simpara>If there were more commits on the <emphasis>master</emphasis> branch after the merge, the\r
+merge commit itself would not be shown by <emphasis>git-show-branch</emphasis> by\r
+default.  You would need to provide <emphasis>--sparse</emphasis> option to make the\r
+merge commit visible in this case.</simpara></note>\r
+<simpara>Now, let&#8217;s pretend you are the one who did all the work in\r
+<literal>mybranch</literal>, and the fruit of your hard work has finally been merged\r
+to the <literal>master</literal> branch. Let&#8217;s go back to <literal>mybranch</literal>, and run\r
+<emphasis>git-merge</emphasis> to get the "upstream changes" back to your branch.</simpara>\r
+<literallayout>$ git checkout mybranch\r
+$ git merge -m "Merge upstream changes." master</literallayout>\r
+<simpara>This outputs something like this (the actual commit object names\r
+would be different)</simpara>\r
+<literallayout>Updating from ae3a2da... to a80b4aa....\r
+Fast forward (no commit created; -m option ignored)\r
+ example |    1 +\r
+ hello   |    1 +\r
+ 2 files changed, 2 insertions(+), 0 deletions(-)</literallayout>\r
+<simpara>Because your branch did not contain anything more than what had\r
+already been merged into the <literal>master</literal> branch, the merge operation did\r
+not actually do a merge. Instead, it just updated the top of\r
+the tree of your branch to that of the <literal>master</literal> branch. This is\r
+often called <emphasis>fast forward</emphasis> merge.</simpara>\r
+<simpara>You can run <literal>gitk --all</literal> again to see how the commit ancestry\r
+looks like, or run <emphasis>show-branch</emphasis>, which tells you this.</simpara>\r
+<literallayout>$ git show-branch master mybranch\r
+! [master] Merge work in mybranch\r
+ * [mybranch] Merge work in mybranch\r
+--\r
+-- [master] Merge work in mybranch</literallayout>\r
+</simplesect>\r
+<simplesect id="_merging_external_work">\r
+<title>Merging external work</title>\r
+<simpara>It&#8217;s usually much more common that you merge with somebody else than\r
+merging with your own branches, so it&#8217;s worth pointing out that git\r
+makes that very easy too, and in fact, it&#8217;s not that different from\r
+doing a <emphasis>git-merge</emphasis>. In fact, a remote merge ends up being nothing\r
+more than "fetch the work from a remote repository into a temporary tag"\r
+followed by a <emphasis>git-merge</emphasis>.</simpara>\r
+<simpara>Fetching from a remote repository is done by, unsurprisingly,\r
+<emphasis>git-fetch</emphasis>:</simpara>\r
+<literallayout>$ git fetch &lt;remote-repository&gt;</literallayout>\r
+<simpara>One of the following transports can be used to name the\r
+repository to download from:</simpara>\r
+<variablelist>\r
+<varlistentry>\r
+<term>\r
+Rsync\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        <literal>rsync://remote.machine/path/to/repo.git/</literal>\r
+</simpara>\r
+<simpara>Rsync transport is usable for both uploading and downloading,\r
+but is completely unaware of what git does, and can produce\r
+unexpected results when you download from the public repository\r
+while the repository owner is uploading into it via <literal>rsync</literal>\r
+transport.  Most notably, it could update the files under\r
+<literal>refs/</literal> which holds the object name of the topmost commits\r
+before uploading the files in <literal>objects/</literal>&#8201;&#8212;&#8201;the downloader would\r
+obtain head commit object name while that object itself is still\r
+not available in the repository.  For this reason, it is\r
+considered deprecated.</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+SSH\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        <literal>remote.machine:/path/to/repo.git/</literal> or\r
+</simpara>\r
+<simpara><literal>ssh://remote.machine/path/to/repo.git/</literal></simpara>\r
+<simpara>This transport can be used for both uploading and downloading,\r
+and requires you to have a log-in privilege over <literal>ssh</literal> to the\r
+remote machine.  It finds out the set of objects the other side\r
+lacks by exchanging the head commits both ends have and\r
+transfers (close to) minimum set of objects.  It is by far the\r
+most efficient way to exchange git objects between repositories.</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+Local directory\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        <literal>/path/to/repo.git/</literal>\r
+</simpara>\r
+<simpara>This transport is the same as SSH transport but uses <emphasis>sh</emphasis> to run\r
+both ends on the local machine instead of running other end on\r
+the remote machine via <emphasis>ssh</emphasis>.</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+git Native\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        <literal>git://remote.machine/path/to/repo.git/</literal>\r
+</simpara>\r
+<simpara>This transport was designed for anonymous downloading.  Like SSH\r
+transport, it finds out the set of objects the downstream side\r
+lacks and transfers (close to) minimum set of objects.</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+HTTP(S)\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        <literal>http://remote.machine/path/to/repo.git/</literal>\r
+</simpara>\r
+<simpara>Downloader from http and https URL\r
+first obtains the topmost commit object name from the remote site\r
+by looking at the specified refname under <literal>repo.git/refs/</literal> directory,\r
+and then tries to obtain the\r
+commit object by downloading from <literal>repo.git/objects/xx/xxx...</literal>\r
+using the object name of that commit object.  Then it reads the\r
+commit object to find out its parent commits and the associate\r
+tree object; it repeats this process until it gets all the\r
+necessary objects.  Because of this behavior, they are\r
+sometimes also called <emphasis>commit walkers</emphasis>.</simpara>\r
+<simpara>The <emphasis>commit walkers</emphasis> are sometimes also called <emphasis>dumb\r
+transports</emphasis>, because they do not require any git aware smart\r
+server like git Native transport does.  Any stock HTTP server\r
+that does not even support directory index would suffice.  But\r
+you must prepare your repository with <emphasis>git-update-server-info</emphasis>\r
+to help dumb transport downloaders.</simpara>\r
+</listitem>\r
+</varlistentry>\r
+</variablelist>\r
+<simpara>Once you fetch from the remote repository, you <literal>merge</literal> that\r
+with your current branch.</simpara>\r
+<simpara>However&#8201;&#8212;&#8201;it&#8217;s such a common thing to <literal>fetch</literal> and then\r
+immediately <literal>merge</literal>, that it&#8217;s called <literal>git pull</literal>, and you can\r
+simply do</simpara>\r
+<literallayout>$ git pull &lt;remote-repository&gt;</literallayout>\r
+<simpara>and optionally give a branch-name for the remote end as a second\r
+argument.</simpara>\r
+<note><simpara>You could do without using any branches at all, by\r
+keeping as many local repositories as you would like to have\r
+branches, and merging between them with <emphasis>git-pull</emphasis>, just like\r
+you merge between branches. The advantage of this approach is\r
+that it lets you keep a set of files for each <literal>branch</literal> checked\r
+out and you may find it easier to switch back and forth if you\r
+juggle multiple lines of development simultaneously. Of\r
+course, you will pay the price of more disk usage to hold\r
+multiple working trees, but disk space is cheap these days.</simpara></note>\r
+<simpara>It is likely that you will be pulling from the same remote\r
+repository from time to time. As a short hand, you can store\r
+the remote repository URL in the local repository&#8217;s config file\r
+like this:</simpara>\r
+<literallayout>$ git config remote.linus.url http://www.kernel.org/pub/scm/git/git.git/</literallayout>\r
+<simpara>and use the "linus" keyword with <emphasis>git-pull</emphasis> instead of the full URL.</simpara>\r
+<simpara>Examples.</simpara>\r
+<orderedlist numeration="arabic">\r
+<listitem>\r
+<simpara>\r
+<literal>git pull linus</literal>\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+<literal>git pull linus tag v0.99.1</literal>\r
+</simpara>\r
+</listitem>\r
+</orderedlist>\r
+<simpara>the above are equivalent to:</simpara>\r
+<orderedlist numeration="arabic">\r
+<listitem>\r
+<simpara>\r
+<literal>git pull <ulink url="http://www.kernel.org/pub/scm/git/git.git/">http://www.kernel.org/pub/scm/git/git.git/</ulink> HEAD</literal>\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+<literal>git pull <ulink url="http://www.kernel.org/pub/scm/git/git.git/">http://www.kernel.org/pub/scm/git/git.git/</ulink> tag v0.99.1</literal>\r
+</simpara>\r
+</listitem>\r
+</orderedlist>\r
+</simplesect>\r
+<simplesect id="_how_does_the_merge_work">\r
+<title>How does the merge work?</title>\r
+<simpara>We said this tutorial shows what plumbing does to help you cope\r
+with the porcelain that isn&#8217;t flushing, but we so far did not\r
+talk about how the merge really works.  If you are following\r
+this tutorial the first time, I&#8217;d suggest to skip to "Publishing\r
+your work" section and come back here later.</simpara>\r
+<simpara>OK, still with me?  To give us an example to look at, let&#8217;s go\r
+back to the earlier repository with "hello" and "example" file,\r
+and bring ourselves back to the pre-merge state:</simpara>\r
+<literallayout>$ git show-branch --more=2 master mybranch\r
+! [master] Merge work in mybranch\r
+ * [mybranch] Merge work in mybranch\r
+--\r
+-- [master] Merge work in mybranch\r
++* [master^2] Some work.\r
++* [master^] Some fun.</literallayout>\r
+<simpara>Remember, before running <emphasis>git-merge</emphasis>, our <literal>master</literal> head was at\r
+"Some fun." commit, while our <literal>mybranch</literal> head was at "Some\r
+work." commit.</simpara>\r
+<literallayout>$ git checkout mybranch\r
+$ git reset --hard master^2\r
+$ git checkout master\r
+$ git reset --hard master^</literallayout>\r
+<simpara>After rewinding, the commit structure should look like this:</simpara>\r
+<literallayout>$ git show-branch\r
+* [master] Some fun.\r
+ ! [mybranch] Some work.\r
+--\r
+ + [mybranch] Some work.\r
+*  [master] Some fun.\r
+*+ [mybranch^] New day.</literallayout>\r
+<simpara>Now we are ready to experiment with the merge by hand.</simpara>\r
+<simpara><literal>git merge</literal> command, when merging two branches, uses 3-way merge\r
+algorithm.  First, it finds the common ancestor between them.\r
+The command it uses is <emphasis>git-merge-base</emphasis>:</simpara>\r
+<literallayout>$ mb=$(git merge-base HEAD mybranch)</literallayout>\r
+<simpara>The command writes the commit object name of the common ancestor\r
+to the standard output, so we captured its output to a variable,\r
+because we will be using it in the next step.  By the way, the common\r
+ancestor commit is the "New day." commit in this case.  You can\r
+tell it by:</simpara>\r
+<literallayout>$ git name-rev $mb\r
+my-first-tag</literallayout>\r
+<simpara>After finding out a common ancestor commit, the second step is\r
+this:</simpara>\r
+<literallayout>$ git read-tree -m -u $mb HEAD mybranch</literallayout>\r
+<simpara>This is the same <emphasis>git-read-tree</emphasis> command we have already seen,\r
+but it takes three trees, unlike previous examples.  This reads\r
+the contents of each tree into different <emphasis>stage</emphasis> in the index\r
+file (the first tree goes to stage 1, the second to stage 2,\r
+etc.).  After reading three trees into three stages, the paths\r
+that are the same in all three stages are <emphasis>collapsed</emphasis> into stage\r
+0.  Also paths that are the same in two of three stages are\r
+collapsed into stage 0, taking the SHA1 from either stage 2 or\r
+stage 3, whichever is different from stage 1 (i.e. only one side\r
+changed from the common ancestor).</simpara>\r
+<simpara>After <emphasis>collapsing</emphasis> operation, paths that are different in three\r
+trees are left in non-zero stages.  At this point, you can\r
+inspect the index file with this command:</simpara>\r
+<literallayout>$ git ls-files --stage\r
+100644 7f8b141b65fdcee47321e399a2598a235a032422 0       example\r
+100644 263414f423d0e4d70dae8fe53fa34614ff3e2860 1       hello\r
+100644 06fa6a24256dc7e560efa5687fa84b51f0263c3a 2       hello\r
+100644 cc44c73eb783565da5831b4d820c962954019b69 3       hello</literallayout>\r
+<simpara>In our example of only two files, we did not have unchanged\r
+files so only <emphasis>example</emphasis> resulted in collapsing.  But in real-life\r
+large projects, when only a small number of files change in one commit,\r
+this <emphasis>collapsing</emphasis> tends to trivially merge most of the paths\r
+fairly quickly, leaving only a handful of real changes in non-zero\r
+stages.</simpara>\r
+<simpara>To look at only non-zero stages, use <literal>--unmerged</literal> flag:</simpara>\r
+<literallayout>$ git ls-files --unmerged\r
+100644 263414f423d0e4d70dae8fe53fa34614ff3e2860 1       hello\r
+100644 06fa6a24256dc7e560efa5687fa84b51f0263c3a 2       hello\r
+100644 cc44c73eb783565da5831b4d820c962954019b69 3       hello</literallayout>\r
+<simpara>The next step of merging is to merge these three versions of the\r
+file, using 3-way merge.  This is done by giving\r
+<emphasis>git-merge-one-file</emphasis> command as one of the arguments to\r
+<emphasis>git-merge-index</emphasis> command:</simpara>\r
+<literallayout>$ git merge-index git-merge-one-file hello\r
+Auto-merging hello\r
+ERROR: Merge conflict in hello\r
+fatal: merge program failed</literallayout>\r
+<simpara><emphasis>git-merge-one-file</emphasis> script is called with parameters to\r
+describe those three versions, and is responsible to leave the\r
+merge results in the working tree.\r
+It is a fairly straightforward shell script, and\r
+eventually calls <emphasis>merge</emphasis> program from RCS suite to perform a\r
+file-level 3-way merge.  In this case, <emphasis>merge</emphasis> detects\r
+conflicts, and the merge result with conflict marks is left in\r
+the working tree..  This can be seen if you run <literal>ls-files\r
+--stage</literal> again at this point:</simpara>\r
+<literallayout>$ git ls-files --stage\r
+100644 7f8b141b65fdcee47321e399a2598a235a032422 0       example\r
+100644 263414f423d0e4d70dae8fe53fa34614ff3e2860 1       hello\r
+100644 06fa6a24256dc7e560efa5687fa84b51f0263c3a 2       hello\r
+100644 cc44c73eb783565da5831b4d820c962954019b69 3       hello</literallayout>\r
+<simpara>This is the state of the index file and the working file after\r
+<emphasis>git-merge</emphasis> returns control back to you, leaving the conflicting\r
+merge for you to resolve.  Notice that the path <literal>hello</literal> is still\r
+unmerged, and what you see with <emphasis>git-diff</emphasis> at this point is\r
+differences since stage 2 (i.e. your version).</simpara>\r
+</simplesect>\r
+<simplesect id="_publishing_your_work">\r
+<title>Publishing your work</title>\r
+<simpara>So, we can use somebody else&#8217;s work from a remote repository, but\r
+how can <emphasis role="strong">you</emphasis> prepare a repository to let other people pull from\r
+it?</simpara>\r
+<simpara>You do your real work in your working tree that has your\r
+primary repository hanging under it as its <literal>.git</literal> subdirectory.\r
+You <emphasis role="strong">could</emphasis> make that repository accessible remotely and ask\r
+people to pull from it, but in practice that is not the way\r
+things are usually done. A recommended way is to have a public\r
+repository, make it reachable by other people, and when the\r
+changes you made in your primary working tree are in good shape,\r
+update the public repository from it. This is often called\r
+<emphasis>pushing</emphasis>.</simpara>\r
+<note><simpara>This public repository could further be mirrored, and that is\r
+how git repositories at <literal>kernel.org</literal> are managed.</simpara></note>\r
+<simpara>Publishing the changes from your local (private) repository to\r
+your remote (public) repository requires a write privilege on\r
+the remote machine. You need to have an SSH account there to\r
+run a single command, <emphasis>git-receive-pack</emphasis>.</simpara>\r
+<simpara>First, you need to create an empty repository on the remote\r
+machine that will house your public repository. This empty\r
+repository will be populated and be kept up-to-date by pushing\r
+into it later. Obviously, this repository creation needs to be\r
+done only once.</simpara>\r
+<note><simpara><emphasis>git-push</emphasis> uses a pair of programs,\r
+<emphasis>git-send-pack</emphasis> on your local machine, and <emphasis>git-receive-pack</emphasis>\r
+on the remote machine. The communication between the two over\r
+the network internally uses an SSH connection.</simpara></note>\r
+<simpara>Your private repository&#8217;s git directory is usually <literal>.git</literal>, but\r
+your public repository is often named after the project name,\r
+i.e. <literal>&lt;project&gt;.git</literal>. Let&#8217;s create such a public repository for\r
+project <literal>my-git</literal>. After logging into the remote machine, create\r
+an empty directory:</simpara>\r
+<literallayout>$ mkdir my-git.git</literallayout>\r
+<simpara>Then, make that directory into a git repository by running\r
+<emphasis>git-init</emphasis>, but this time, since its name is not the usual\r
+<literal>.git</literal>, we do things slightly differently:</simpara>\r
+<literallayout>$ GIT_DIR=my-git.git git init</literallayout>\r
+<simpara>Make sure this directory is available for others you want your\r
+changes to be pulled via the transport of your choice. Also\r
+you need to make sure that you have the <emphasis>git-receive-pack</emphasis>\r
+program on the <literal>$PATH</literal>.</simpara>\r
+<note><simpara>Many installations of sshd do not invoke your shell as the login\r
+shell when you directly run programs; what this means is that if\r
+your login shell is <emphasis>bash</emphasis>, only <literal>.bashrc</literal> is read and not\r
+<literal>.bash_profile</literal>. As a workaround, make sure <literal>.bashrc</literal> sets up\r
+<literal>$PATH</literal> so that you can run <emphasis>git-receive-pack</emphasis> program.</simpara></note>\r
+<note><simpara>If you plan to publish this repository to be accessed over http,\r
+you should do <literal>mv my-git.git/hooks/post-update.sample\r
+my-git.git/hooks/post-update</literal> at this point.\r
+This makes sure that every time you push into this\r
+repository, <literal>git update-server-info</literal> is run.</simpara></note>\r
+<simpara>Your "public repository" is now ready to accept your changes.\r
+Come back to the machine you have your private repository. From\r
+there, run this command:</simpara>\r
+<literallayout>$ git push &lt;public-host&gt;:/path/to/my-git.git master</literallayout>\r
+<simpara>This synchronizes your public repository to match the named\r
+branch head (i.e. <literal>master</literal> in this case) and objects reachable\r
+from them in your current repository.</simpara>\r
+<simpara>As a real example, this is how I update my public git\r
+repository. Kernel.org mirror network takes care of the\r
+propagation to other publicly visible machines:</simpara>\r
+<literallayout>$ git push master.kernel.org:/pub/scm/git/git.git/</literallayout>\r
+</simplesect>\r
+<simplesect id="_packing_your_repository">\r
+<title>Packing your repository</title>\r
+<simpara>Earlier, we saw that one file under <literal>.git/objects/??/</literal> directory\r
+is stored for each git object you create. This representation\r
+is efficient to create atomically and safely, but\r
+not so convenient to transport over the network. Since git objects are\r
+immutable once they are created, there is a way to optimize the\r
+storage by "packing them together". The command</simpara>\r
+<literallayout>$ git repack</literallayout>\r
+<simpara>will do it for you. If you followed the tutorial examples, you\r
+would have accumulated about 17 objects in <literal>.git/objects/??/</literal>\r
+directories by now. <emphasis>git-repack</emphasis> tells you how many objects it\r
+packed, and stores the packed file in <literal>.git/objects/pack</literal>\r
+directory.</simpara>\r
+<note><simpara>You will see two files, <literal>pack-*.pack</literal> and <literal>pack-\*.idx</literal>,\r
+in <literal>.git/objects/pack</literal> directory. They are closely related to\r
+each other, and if you ever copy them by hand to a different\r
+repository for whatever reason, you should make sure you copy\r
+them together. The former holds all the data from the objects\r
+in the pack, and the latter holds the index for random\r
+access.</simpara></note>\r
+<simpara>If you are paranoid, running <emphasis>git-verify-pack</emphasis> command would\r
+detect if you have a corrupt pack, but do not worry too much.\r
+Our programs are always perfect ;-).</simpara>\r
+<simpara>Once you have packed objects, you do not need to leave the\r
+unpacked objects that are contained in the pack file anymore.</simpara>\r
+<literallayout>$ git prune-packed</literallayout>\r
+<simpara>would remove them for you.</simpara>\r
+<simpara>You can try running <literal>find .git/objects -type f</literal> before and after\r
+you run <literal>git prune-packed</literal> if you are curious.  Also <literal>git\r
+count-objects</literal> would tell you how many unpacked objects are in\r
+your repository and how much space they are consuming.</simpara>\r
+<note><simpara><literal>git pull</literal> is slightly cumbersome for HTTP transport, as a\r
+packed repository may contain relatively few objects in a\r
+relatively large pack. If you expect many HTTP pulls from your\r
+public repository you might want to repack &amp; prune often, or\r
+never.</simpara></note>\r
+<simpara>If you run <literal>git repack</literal> again at this point, it will say\r
+"Nothing new to pack.". Once you continue your development and\r
+accumulate the changes, running <literal>git repack</literal> again will create a\r
+new pack, that contains objects created since you packed your\r
+repository the last time. We recommend that you pack your project\r
+soon after the initial import (unless you are starting your\r
+project from scratch), and then run <literal>git repack</literal> every once in a\r
+while, depending on how active your project is.</simpara>\r
+<simpara>When a repository is synchronized via <literal>git push</literal> and <literal>git pull</literal>\r
+objects packed in the source repository are usually stored\r
+unpacked in the destination, unless rsync transport is used.\r
+While this allows you to use different packing strategies on\r
+both ends, it also means you may need to repack both\r
+repositories every once in a while.</simpara>\r
+</simplesect>\r
+<simplesect id="_working_with_others">\r
+<title>Working with Others</title>\r
+<simpara>Although git is a truly distributed system, it is often\r
+convenient to organize your project with an informal hierarchy\r
+of developers. Linux kernel development is run this way. There\r
+is a nice illustration (page 17, "Merges to Mainline") in\r
+<ulink url="http://www.xenotime.net/linux/mentor/linux-mentoring-2006.pdf">Randy Dunlap&#8217;s presentation</ulink>.</simpara>\r
+<simpara>It should be stressed that this hierarchy is purely <emphasis role="strong">informal</emphasis>.\r
+There is nothing fundamental in git that enforces the "chain of\r
+patch flow" this hierarchy implies. You do not have to pull\r
+from only one remote repository.</simpara>\r
+<simpara>A recommended workflow for a "project lead" goes like this:</simpara>\r
+<orderedlist numeration="arabic">\r
+<listitem>\r
+<simpara>\r
+Prepare your primary repository on your local machine. Your\r
+   work is done there.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Prepare a public repository accessible to others.\r
+</simpara>\r
+<simpara>If other people are pulling from your repository over dumb\r
+transport protocols (HTTP), you need to keep this repository\r
+<emphasis>dumb transport friendly</emphasis>.  After <literal>git init</literal>,\r
+<literal>$GIT_DIR/hooks/post-update.sample</literal> copied from the standard templates\r
+would contain a call to <emphasis>git-update-server-info</emphasis>\r
+but you need to manually enable the hook with\r
+<literal>mv post-update.sample post-update</literal>.  This makes sure\r
+<emphasis>git-update-server-info</emphasis> keeps the necessary files up-to-date.</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Push into the public repository from your primary\r
+   repository.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+<emphasis>git-repack</emphasis> the public repository. This establishes a big\r
+   pack that contains the initial set of objects as the\r
+   baseline, and possibly <emphasis>git-prune</emphasis> if the transport\r
+   used for pulling from your repository supports packed\r
+   repositories.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Keep working in your primary repository. Your changes\r
+   include modifications of your own, patches you receive via\r
+   e-mails, and merges resulting from pulling the "public"\r
+   repositories of your "subsystem maintainers".\r
+</simpara>\r
+<simpara>You can repack this private repository whenever you feel like.</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Push your changes to the public repository, and announce it\r
+   to the public.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Every once in a while, <emphasis>git-repack</emphasis> the public repository.\r
+   Go back to step 5. and continue working.\r
+</simpara>\r
+</listitem>\r
+</orderedlist>\r
+<simpara>A recommended work cycle for a "subsystem maintainer" who works\r
+on that project and has an own "public repository" goes like this:</simpara>\r
+<orderedlist numeration="arabic">\r
+<listitem>\r
+<simpara>\r
+Prepare your work repository, by <emphasis>git-clone</emphasis> the public\r
+   repository of the "project lead". The URL used for the\r
+   initial cloning is stored in the remote.origin.url\r
+   configuration variable.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Prepare a public repository accessible to others, just like\r
+   the "project lead" person does.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Copy over the packed files from "project lead" public\r
+   repository to your public repository, unless the "project\r
+   lead" repository lives on the same machine as yours.  In the\r
+   latter case, you can use <literal>objects/info/alternates</literal> file to\r
+   point at the repository you are borrowing from.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Push into the public repository from your primary\r
+   repository. Run <emphasis>git-repack</emphasis>, and possibly <emphasis>git-prune</emphasis> if the\r
+   transport used for pulling from your repository supports\r
+   packed repositories.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Keep working in your primary repository. Your changes\r
+   include modifications of your own, patches you receive via\r
+   e-mails, and merges resulting from pulling the "public"\r
+   repositories of your "project lead" and possibly your\r
+   "sub-subsystem maintainers".\r
+</simpara>\r
+<simpara>You can repack this private repository whenever you feel\r
+like.</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Push your changes to your public repository, and ask your\r
+   "project lead" and possibly your "sub-subsystem\r
+   maintainers" to pull from it.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Every once in a while, <emphasis>git-repack</emphasis> the public repository.\r
+   Go back to step 5. and continue working.\r
+</simpara>\r
+</listitem>\r
+</orderedlist>\r
+<simpara>A recommended work cycle for an "individual developer" who does\r
+not have a "public" repository is somewhat different. It goes\r
+like this:</simpara>\r
+<orderedlist numeration="arabic">\r
+<listitem>\r
+<simpara>\r
+Prepare your work repository, by <emphasis>git-clone</emphasis> the public\r
+   repository of the "project lead" (or a "subsystem\r
+   maintainer", if you work on a subsystem). The URL used for\r
+   the initial cloning is stored in the remote.origin.url\r
+   configuration variable.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Do your work in your repository on <emphasis>master</emphasis> branch.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Run <literal>git fetch origin</literal> from the public repository of your\r
+   upstream every once in a while. This does only the first\r
+   half of <literal>git pull</literal> but does not merge. The head of the\r
+   public repository is stored in <literal>.git/refs/remotes/origin/master</literal>.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Use <literal>git cherry origin</literal> to see which ones of your patches\r
+   were accepted, and/or use <literal>git rebase origin</literal> to port your\r
+   unmerged changes forward to the updated upstream.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Use <literal>git format-patch origin</literal> to prepare patches for e-mail\r
+   submission to your upstream and send it out. Go back to\r
+   step 2. and continue.\r
+</simpara>\r
+</listitem>\r
+</orderedlist>\r
+</simplesect>\r
+<simplesect id="_working_with_others_shared_repository_style">\r
+<title>Working with Others, Shared Repository Style</title>\r
+<simpara>If you are coming from CVS background, the style of cooperation\r
+suggested in the previous section may be new to you. You do not\r
+have to worry. git supports "shared public repository" style of\r
+cooperation you are probably more familiar with as well.</simpara>\r
+<simpara>See <xref linkend="gitcvs-migration(7)"/> for the details.</simpara>\r
+</simplesect>\r
+<simplesect id="_bundling_your_work_together">\r
+<title>Bundling your work together</title>\r
+<simpara>It is likely that you will be working on more than one thing at\r
+a time.  It is easy to manage those more-or-less independent tasks\r
+using branches with git.</simpara>\r
+<simpara>We have already seen how branches work previously,\r
+with "fun and work" example using two branches.  The idea is the\r
+same if there are more than two branches.  Let&#8217;s say you started\r
+out from "master" head, and have some new code in the "master"\r
+branch, and two independent fixes in the "commit-fix" and\r
+"diff-fix" branches:</simpara>\r
+<literallayout>$ git show-branch\r
+! [commit-fix] Fix commit message normalization.\r
+ ! [diff-fix] Fix rename detection.\r
+  * [master] Release candidate #1\r
+---\r
+ +  [diff-fix] Fix rename detection.\r
+ +  [diff-fix~1] Better common substring algorithm.\r
++   [commit-fix] Fix commit message normalization.\r
+  * [master] Release candidate #1\r
+++* [diff-fix~2] Pretty-print messages.</literallayout>\r
+<simpara>Both fixes are tested well, and at this point, you want to merge\r
+in both of them.  You could merge in <emphasis>diff-fix</emphasis> first and then\r
+<emphasis>commit-fix</emphasis> next, like this:</simpara>\r
+<literallayout>$ git merge -m "Merge fix in diff-fix" diff-fix\r
+$ git merge -m "Merge fix in commit-fix" commit-fix</literallayout>\r
+<simpara>Which would result in:</simpara>\r
+<literallayout>$ git show-branch\r
+! [commit-fix] Fix commit message normalization.\r
+ ! [diff-fix] Fix rename detection.\r
+  * [master] Merge fix in commit-fix\r
+---\r
+  - [master] Merge fix in commit-fix\r
++ * [commit-fix] Fix commit message normalization.\r
+  - [master~1] Merge fix in diff-fix\r
+ +* [diff-fix] Fix rename detection.\r
+ +* [diff-fix~1] Better common substring algorithm.\r
+  * [master~2] Release candidate #1\r
+++* [master~3] Pretty-print messages.</literallayout>\r
+<simpara>However, there is no particular reason to merge in one branch\r
+first and the other next, when what you have are a set of truly\r
+independent changes (if the order mattered, then they are not\r
+independent by definition).  You could instead merge those two\r
+branches into the current branch at once.  First let&#8217;s undo what\r
+we just did and start over.  We would want to get the master\r
+branch before these two merges by resetting it to <emphasis>master~2</emphasis>:</simpara>\r
+<literallayout>$ git reset --hard master~2</literallayout>\r
+<simpara>You can make sure <literal>git show-branch</literal> matches the state before\r
+those two <emphasis>git-merge</emphasis> you just did.  Then, instead of running\r
+two <emphasis>git-merge</emphasis> commands in a row, you would merge these two\r
+branch heads (this is known as <emphasis>making an Octopus</emphasis>):</simpara>\r
+<literallayout>$ git merge commit-fix diff-fix\r
+$ git show-branch\r
+! [commit-fix] Fix commit message normalization.\r
+ ! [diff-fix] Fix rename detection.\r
+  * [master] Octopus merge of branches 'diff-fix' and 'commit-fix'\r
+---\r
+  - [master] Octopus merge of branches 'diff-fix' and 'commit-fix'\r
++ * [commit-fix] Fix commit message normalization.\r
+ +* [diff-fix] Fix rename detection.\r
+ +* [diff-fix~1] Better common substring algorithm.\r
+  * [master~1] Release candidate #1\r
+++* [master~2] Pretty-print messages.</literallayout>\r
+<simpara>Note that you should not do Octopus because you can.  An octopus\r
+is a valid thing to do and often makes it easier to view the\r
+commit history if you are merging more than two independent\r
+changes at the same time.  However, if you have merge conflicts\r
+with any of the branches you are merging in and need to hand\r
+resolve, that is an indication that the development happened in\r
+those branches were not independent after all, and you should\r
+merge two at a time, documenting how you resolved the conflicts,\r
+and the reason why you preferred changes made in one side over\r
+the other.  Otherwise it would make the project history harder\r
+to follow, not easier.</simpara>\r
+</simplesect>\r
+<simplesect id="_see_also">\r
+<title>SEE ALSO</title>\r
+<simpara><xref linkend="gittutorial(7)"/>,\r
+<xref linkend="gittutorial-2(7)"/>,\r
+<xref linkend="gitcvs-migration(7)"/>,\r
+<xref linkend="git-help(1)"/>,\r
+<ulink url="everyday.html">Everyday git</ulink>,\r
+<ulink url="user-manual.html">The Git User&#8217;s Manual</ulink></simpara>\r
+</simplesect>\r
+<simplesect id="_git">\r
+<title>GIT</title>\r
+<simpara>Part of the <xref linkend="git(1)"/> suite.</simpara>\r
+</simplesect>\r
+</article>\r