OSDN Git Service

Add Git User manual to Help Document
authorFrank Li <lznuaa@gmail.com>
Tue, 3 Mar 2009 06:14:14 +0000 (14:14 +0800)
committerFrank Li <lznuaa@gmail.com>
Wed, 4 Mar 2009 13:11:18 +0000 (21:11 +0800)
Signed-off-by: Frank Li <lznuaa@gmail.com>
doc/source/en/TortoiseGit/tortoisegit.xml
doc/source/en/TortoiseGit/user-manual.xml [new file with mode: 0644]

index 58447eb..8f4a363 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
+<?xml version="1.0" encoding="UTF-8"?>\r
 <!DOCTYPE book SYSTEM "../../dtd/dblite.dtd">\r
 <book id="tsvn" lang="en" xmlns:xi="http://www.w3.org/2001/XInclude">\r
        <title>TortoiseGit</title>\r
        <xi:include href="./tsvn_app_automation.xml"/>  \r
        <xi:include href="./tsvn_app_cli.xml"/>\r
        <xi:include href="./tsvn_app_internals.xml"/>\r
+       \r
        <xi:include href="./tsvn_app_ssh.xml"/>\r
+       \r
+       <xi:include href="./user-manual.xml"/>  \r
+       \r
+       \r
        <xi:include href="../glossary.xml"/>\r
-       <appendix id="git-user manual" xmlns:xi="http://www.w3.org/2001/XInclude">\r
-       <!--\r
-       <xi:include href="./user-manual.xml" xpointer="xpointer(//book)"/>\r
-       -->\r
+       <appendix id="appendix" xmlns:xi="http://www.w3.org/2001/XInclude">\r
        </appendix>\r
        <index id="tsvn-index"/>\r
 </book>\r
diff --git a/doc/source/en/TortoiseGit/user-manual.xml b/doc/source/en/TortoiseGit/user-manual.xml
new file mode 100644 (file)
index 0000000..d42d0c5
--- /dev/null
@@ -0,0 +1,4348 @@
+<?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">\r
+<articleinfo>\r
+    <title>Git User&#8217;s Manual (for version 1.5.3 or newer)</title>\r
+</articleinfo>\r
+<simpara>Git is a fast distributed revision control system.</simpara>\r
+<simpara>This manual is designed to be readable by someone with basic UNIX\r
+command-line skills, but no previous knowledge of git.</simpara>\r
+<simpara><xref linkend="repositories-and-branches"/> and <xref linkend="exploring-git-history"/> explain how\r
+to fetch and study a project using git&#8212;read these chapters to learn how\r
+to build and test a particular version of a software project, search for\r
+regressions, and so on.</simpara>\r
+<simpara>People needing to do actual development will also want to read\r
+<xref linkend="Developing-With-git"/> and <xref linkend="sharing-development"/>.</simpara>\r
+<simpara>Further chapters cover more specialized topics.</simpara>\r
+<simpara>Comprehensive reference documentation is available through the man\r
+pages, or <ulink url="git-help.html">git-help(1)</ulink> command.  For example, for the command\r
+"git clone &lt;repo&gt;", you can either use:</simpara>\r
+<literallayout>$ man git-clone</literallayout>\r
+<simpara>or:</simpara>\r
+<literallayout>$ git help clone</literallayout>\r
+<simpara>With the latter, you can use the manual viewer of your choice; see\r
+<ulink url="git-help.html">git-help(1)</ulink> for more information.</simpara>\r
+<simpara>See also <xref linkend="git-quick-start"/> for a brief overview of git commands,\r
+without any explanation.</simpara>\r
+<simpara>Finally, see <xref linkend="todo"/> for ways that you can help make this manual more\r
+complete.</simpara>\r
+<section id="repositories-and-branches">\r
+<title>Repositories and Branches</title>\r
+<section id="how-to-get-a-git-repository">\r
+<title>How to get a git repository</title>\r
+<simpara>It will be useful to have a git repository to experiment with as you\r
+read this manual.</simpara>\r
+<simpara>The best way to get one is by using the <ulink url="git-clone.html">git-clone(1)</ulink> command to\r
+download a copy of an existing repository.  If you don&#8217;t already have a\r
+project in mind, here are some interesting examples:</simpara>\r
+<literallayout>        # git itself (approx. 10MB download):\r
+$ git clone git://git.kernel.org/pub/scm/git/git.git\r
+        # the Linux kernel (approx. 150MB download):\r
+$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git</literallayout>\r
+<simpara>The initial clone may be time-consuming for a large project, but you\r
+will only need to clone once.</simpara>\r
+<simpara>The clone command creates a new directory named after the project ("git"\r
+or "linux-2.6" in the examples above).  After you cd into this\r
+directory, you will see that it contains a copy of the project files,\r
+called the <link linkend="def_working_tree">working tree</link>, together with a special\r
+top-level directory named ".git", which contains all the information\r
+about the history of the project.</simpara>\r
+</section>\r
+<section id="how-to-check-out">\r
+<title>How to check out a different version of a project</title>\r
+<simpara>Git is best thought of as a tool for storing the history of a collection\r
+of files.  It stores the history as a compressed collection of\r
+interrelated snapshots of the project&#8217;s contents.  In git each such\r
+version is called a <link linkend="def_commit">commit</link>.</simpara>\r
+<simpara>Those snapshots aren&#8217;t necessarily all arranged in a single line from\r
+oldest to newest; instead, work may simultaneously proceed along\r
+parallel lines of development, called <link linkend="def_branch">branches</link>, which may\r
+merge and diverge.</simpara>\r
+<simpara>A single git repository can track development on multiple branches.  It\r
+does this by keeping a list of <link linkend="def_head">heads</link> which reference the\r
+latest commit on each branch; the <ulink url="git-branch.html">git-branch(1)</ulink> command shows\r
+you the list of branch heads:</simpara>\r
+<literallayout>$ git branch\r
+* master</literallayout>\r
+<simpara>A freshly cloned repository contains a single branch head, by default\r
+named "master", with the working directory initialized to the state of\r
+the project referred to by that branch head.</simpara>\r
+<simpara>Most projects also use <link linkend="def_tag">tags</link>.  Tags, like heads, are\r
+references into the project&#8217;s history, and can be listed using the\r
+<ulink url="git-tag.html">git-tag(1)</ulink> command:</simpara>\r
+<literallayout>$ git tag -l\r
+v2.6.11\r
+v2.6.11-tree\r
+v2.6.12\r
+v2.6.12-rc2\r
+v2.6.12-rc3\r
+v2.6.12-rc4\r
+v2.6.12-rc5\r
+v2.6.12-rc6\r
+v2.6.13\r
+...</literallayout>\r
+<simpara>Tags are expected to always point at the same version of a project,\r
+while heads are expected to advance as development progresses.</simpara>\r
+<simpara>Create a new branch head pointing to one of these versions and check it\r
+out using <ulink url="git-checkout.html">git-checkout(1)</ulink>:</simpara>\r
+<literallayout>$ git checkout -b new v2.6.13</literallayout>\r
+<simpara>The working directory then reflects the contents that the project had\r
+when it was tagged v2.6.13, and <ulink url="git-branch.html">git-branch(1)</ulink> shows two\r
+branches, with an asterisk marking the currently checked-out branch:</simpara>\r
+<literallayout>$ git branch\r
+  master\r
+* new</literallayout>\r
+<simpara>If you decide that you&#8217;d rather see version 2.6.17, you can modify\r
+the current branch to point at v2.6.17 instead, with</simpara>\r
+<literallayout>$ git reset --hard v2.6.17</literallayout>\r
+<simpara>Note that if the current branch head was your only reference to a\r
+particular point in history, then resetting that branch may leave you\r
+with no way to find the history it used to point to; so use this command\r
+carefully.</simpara>\r
+</section>\r
+<section id="understanding-commits">\r
+<title>Understanding History: Commits</title>\r
+<simpara>Every change in the history of a project is represented by a commit.\r
+The <ulink url="git-show.html">git-show(1)</ulink> command shows the most recent commit on the\r
+current branch:</simpara>\r
+<literallayout>$ git show\r
+commit 17cf781661e6d38f737f15f53ab552f1e95960d7\r
+Author: Linus Torvalds &lt;torvalds@ppc970.osdl.org.(none)&gt;\r
+Date:   Tue Apr 19 14:11:06 2005 -0700\r
+\r
+    Remove duplicate getenv(DB_ENVIRONMENT) call\r
+\r
+    Noted by Tony Luck.\r
+\r
+diff --git a/init-db.c b/init-db.c\r
+index 65898fa..b002dc6 100644\r
+--- a/init-db.c\r
++++ b/init-db.c\r
+@@ -7,7 +7,7 @@\r
+\r
+ int main(int argc, char **argv)\r
+ {\r
+-       char *sha1_dir = getenv(DB_ENVIRONMENT), *path;\r
++       char *sha1_dir, *path;\r
+        int len, i;\r
+\r
+        if (mkdir(".git", 0755) &lt; 0) {</literallayout>\r
+<simpara>As you can see, a commit shows who made the latest change, what they\r
+did, and why.</simpara>\r
+<simpara>Every commit has a 40-hexdigit id, sometimes called the "object name" or the\r
+"SHA1 id", shown on the first line of the "git-show" output.  You can usually\r
+refer to a commit by a shorter name, such as a tag or a branch name, but this\r
+longer name can also be useful.  Most importantly, it is a globally unique\r
+name for this commit: so if you tell somebody else the object name (for\r
+example in email), then you are guaranteed that name will refer to the same\r
+commit in their repository that it does in yours (assuming their repository\r
+has that commit at all).  Since the object name is computed as a hash over the\r
+contents of the commit, you are guaranteed that the commit can never change\r
+without its name also changing.</simpara>\r
+<simpara>In fact, in <xref linkend="git-concepts"/> we shall see that everything stored in git\r
+history, including file data and directory contents, is stored in an object\r
+with a name that is a hash of its contents.</simpara>\r
+<section id="understanding-reachability">\r
+<title>Understanding history: commits, parents, and reachability</title>\r
+<simpara>Every commit (except the very first commit in a project) also has a\r
+parent commit which shows what happened before this commit.\r
+Following the chain of parents will eventually take you back to the\r
+beginning of the project.</simpara>\r
+<simpara>However, the commits do not form a simple list; git allows lines of\r
+development to diverge and then reconverge, and the point where two\r
+lines of development reconverge is called a "merge".  The commit\r
+representing a merge can therefore have more than one parent, with\r
+each parent representing the most recent commit on one of the lines\r
+of development leading to that point.</simpara>\r
+<simpara>The best way to see how this works is using the <ulink url="gitk.html">gitk(1)</ulink>\r
+command; running gitk now on a git repository and looking for merge\r
+commits will help understand how the git organizes history.</simpara>\r
+<simpara>In the following, we say that commit X is "reachable" from commit Y\r
+if commit X is an ancestor of commit Y.  Equivalently, you could say\r
+that Y is a descendant of X, or that there is a chain of parents\r
+leading from commit Y to commit X.</simpara>\r
+</section>\r
+<section id="history-diagrams">\r
+<title>Understanding history: History diagrams</title>\r
+<simpara>We will sometimes represent git history using diagrams like the one\r
+below.  Commits are shown as "o", and the links between them with\r
+lines drawn with - / and \.  Time goes left to right:</simpara>\r
+<literallayout class="monospaced">         o--o--o &lt;-- Branch A\r
+        /\r
+ o--o--o &lt;-- master\r
+        \\r
+         o--o--o &lt;-- Branch B</literallayout>\r
+<simpara>If we need to talk about a particular commit, the character "o" may\r
+be replaced with another letter or number.</simpara>\r
+</section>\r
+<section id="what-is-a-branch">\r
+<title>Understanding history: What is a branch?</title>\r
+<simpara>When we need to be precise, we will use the word "branch" to mean a line\r
+of development, and "branch head" (or just "head") to mean a reference\r
+to the most recent commit on a branch.  In the example above, the branch\r
+head named "A" is a pointer to one particular commit, but we refer to\r
+the line of three commits leading up to that point as all being part of\r
+"branch A".</simpara>\r
+<simpara>However, when no confusion will result, we often just use the term\r
+"branch" both for branches and for branch heads.</simpara>\r
+</section>\r
+</section>\r
+<section id="manipulating-branches">\r
+<title>Manipulating branches</title>\r
+<simpara>Creating, deleting, and modifying branches is quick and easy; here&#8217;s\r
+a summary of the commands:</simpara>\r
+<variablelist>\r
+<varlistentry>\r
+<term>\r
+git branch\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        list all branches\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+git branch &lt;branch&gt;\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        create a new branch named &lt;branch&gt;, referencing the same\r
+        point in history as the current branch\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+git branch &lt;branch&gt; &lt;start-point&gt;\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        create a new branch named &lt;branch&gt;, referencing\r
+        &lt;start-point&gt;, which may be specified any way you like,\r
+        including using a branch name or a tag name\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+git branch -d &lt;branch&gt;\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        delete the branch &lt;branch&gt;; if the branch you are deleting\r
+        points to a commit which is not reachable from the current\r
+        branch, this command will fail with a warning.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+git branch -D &lt;branch&gt;\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        even if the branch points to a commit not reachable\r
+        from the current branch, you may know that that commit\r
+        is still reachable from some other branch or tag.  In that\r
+        case it is safe to use this command to force git to delete\r
+        the branch.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+git checkout &lt;branch&gt;\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        make the current branch &lt;branch&gt;, updating the working\r
+        directory to reflect the version referenced by &lt;branch&gt;\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+git checkout -b &lt;new&gt; &lt;start-point&gt;\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        create a new branch &lt;new&gt; referencing &lt;start-point&gt;, and\r
+        check it out.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+</variablelist>\r
+<simpara>The special symbol "HEAD" can always be used to refer to the current\r
+branch.  In fact, git uses a file named "HEAD" in the .git directory to\r
+remember which branch is current:</simpara>\r
+<literallayout>$ cat .git/HEAD\r
+ref: refs/heads/master</literallayout>\r
+</section>\r
+<section id="detached-head">\r
+<title>Examining an old version without creating a new branch</title>\r
+<simpara>The git-checkout command normally expects a branch head, but will also\r
+accept an arbitrary commit; for example, you can check out the commit\r
+referenced by a tag:</simpara>\r
+<literallayout>$ git checkout v2.6.17\r
+Note: moving to "v2.6.17" which isn't a local branch\r
+If you want to create a new branch from this checkout, you may do so\r
+(now or later) by using -b with the checkout command again. Example:\r
+  git checkout -b &lt;new_branch_name&gt;\r
+HEAD is now at 427abfa... Linux v2.6.17</literallayout>\r
+<simpara>The HEAD then refers to the SHA1 of the commit instead of to a branch,\r
+and git branch shows that you are no longer on a branch:</simpara>\r
+<literallayout>$ cat .git/HEAD\r
+427abfa28afedffadfca9dd8b067eb6d36bac53f\r
+$ git branch\r
+* (no branch)\r
+  master</literallayout>\r
+<simpara>In this case we say that the HEAD is "detached".</simpara>\r
+<simpara>This is an easy way to check out a particular version without having to\r
+make up a name for the new branch.   You can still create a new branch\r
+(or tag) for this version later if you decide to.</simpara>\r
+</section>\r
+<section id="examining-remote-branches">\r
+<title>Examining branches from a remote repository</title>\r
+<simpara>The "master" branch that was created at the time you cloned is a copy\r
+of the HEAD in the repository that you cloned from.  That repository\r
+may also have had other branches, though, and your local repository\r
+keeps branches which track each of those remote branches, which you\r
+can view using the "-r" option to <ulink url="git-branch.html">git-branch(1)</ulink>:</simpara>\r
+<literallayout>$ git branch -r\r
+  origin/HEAD\r
+  origin/html\r
+  origin/maint\r
+  origin/man\r
+  origin/master\r
+  origin/next\r
+  origin/pu\r
+  origin/todo</literallayout>\r
+<simpara>You cannot check out these remote-tracking branches, but you can\r
+examine them on a branch of your own, just as you would a tag:</simpara>\r
+<literallayout>$ git checkout -b my-todo-copy origin/todo</literallayout>\r
+<simpara>Note that the name "origin" is just the name that git uses by default\r
+to refer to the repository that you cloned from.</simpara>\r
+</section>\r
+<section id="how-git-stores-references">\r
+<title>Naming branches, tags, and other references</title>\r
+<simpara>Branches, remote-tracking branches, and tags are all references to\r
+commits.  All references are named with a slash-separated path name\r
+starting with "refs"; the names we&#8217;ve been using so far are actually\r
+shorthand:</simpara>\r
+<itemizedlist>\r
+<listitem>\r
+<simpara>\r
+The branch "test" is short for "refs/heads/test".\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+The tag "v2.6.18" is short for "refs/tags/v2.6.18".\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+"origin/master" is short for "refs/remotes/origin/master".\r
+</simpara>\r
+</listitem>\r
+</itemizedlist>\r
+<simpara>The full name is occasionally useful if, for example, there ever\r
+exists a tag and a branch with the same name.</simpara>\r
+<simpara>(Newly created refs are actually stored in the .git/refs directory,\r
+under the path given by their name.  However, for efficiency reasons\r
+they may also be packed together in a single file; see\r
+<ulink url="git-pack-refs.html">git-pack-refs(1)</ulink>).</simpara>\r
+<simpara>As another useful shortcut, the "HEAD" of a repository can be referred\r
+to just using the name of that repository.  So, for example, "origin"\r
+is usually a shortcut for the HEAD branch in the repository "origin".</simpara>\r
+<simpara>For the complete list of paths which git checks for references, and\r
+the order it uses to decide which to choose when there are multiple\r
+references with the same shorthand name, see the "SPECIFYING\r
+REVISIONS" section of <ulink url="git-rev-parse.html">git-rev-parse(1)</ulink>.</simpara>\r
+</section>\r
+<section id="Updating-a-repository-With-git-fetch">\r
+<title>Updating a repository with git-fetch</title>\r
+<simpara>Eventually the developer cloned from will do additional work in her\r
+repository, creating new commits and advancing the branches to point\r
+at the new commits.</simpara>\r
+<simpara>The command "git fetch", with no arguments, will update all of the\r
+remote-tracking branches to the latest version found in her\r
+repository.  It will not touch any of your own branches&#8212;not even the\r
+"master" branch that was created for you on clone.</simpara>\r
+</section>\r
+<section id="fetching-branches">\r
+<title>Fetching branches from other repositories</title>\r
+<simpara>You can also track branches from repositories other than the one you\r
+cloned from, using <ulink url="git-remote.html">git-remote(1)</ulink>:</simpara>\r
+<literallayout>$ git remote add linux-nfs git://linux-nfs.org/pub/nfs-2.6.git\r
+$ git fetch linux-nfs\r
+* refs/remotes/linux-nfs/master: storing branch 'master' ...\r
+  commit: bf81b46</literallayout>\r
+<simpara>New remote-tracking branches will be stored under the shorthand name\r
+that you gave "git-remote add", in this case linux-nfs:</simpara>\r
+<literallayout>$ git branch -r\r
+linux-nfs/master\r
+origin/master</literallayout>\r
+<simpara>If you run "git fetch &lt;remote&gt;" later, the tracking branches for the\r
+named &lt;remote&gt; will be updated.</simpara>\r
+<simpara>If you examine the file .git/config, you will see that git has added\r
+a new stanza:</simpara>\r
+<literallayout>$ cat .git/config\r
+...\r
+[remote "linux-nfs"]\r
+        url = git://linux-nfs.org/pub/nfs-2.6.git\r
+        fetch = +refs/heads/*:refs/remotes/linux-nfs/*\r
+...</literallayout>\r
+<simpara>This is what causes git to track the remote&#8217;s branches; you may modify\r
+or delete these configuration options by editing .git/config with a\r
+text editor.  (See the "CONFIGURATION FILE" section of\r
+<ulink url="git-config.html">git-config(1)</ulink> for details.)</simpara>\r
+</section>\r
+</section>\r
+<section id="exploring-git-history">\r
+<title>Exploring git history</title>\r
+<simpara>Git is best thought of as a tool for storing the history of a\r
+collection of files.  It does this by storing compressed snapshots of\r
+the contents of a file hierarchy, together with "commits" which show\r
+the relationships between these snapshots.</simpara>\r
+<simpara>Git provides extremely flexible and fast tools for exploring the\r
+history of a project.</simpara>\r
+<simpara>We start with one specialized tool that is useful for finding the\r
+commit that introduced a bug into a project.</simpara>\r
+<section id="using-bisect">\r
+<title>How to use bisect to find a regression</title>\r
+<simpara>Suppose version 2.6.18 of your project worked, but the version at\r
+"master" crashes.  Sometimes the best way to find the cause of such a\r
+regression is to perform a brute-force search through the project&#8217;s\r
+history to find the particular commit that caused the problem.  The\r
+<ulink url="git-bisect.html">git-bisect(1)</ulink> command can help you do this:</simpara>\r
+<literallayout>$ git bisect start\r
+$ git bisect good v2.6.18\r
+$ git bisect bad master\r
+Bisecting: 3537 revisions left to test after this\r
+[65934a9a028b88e83e2b0f8b36618fe503349f8e] BLOCK: Make USB storage depend on SCSI rather than selecting it [try #6]</literallayout>\r
+<simpara>If you run "git branch" at this point, you&#8217;ll see that git has\r
+temporarily moved you in "(no branch)". HEAD is now detached from any\r
+branch and points directly to a commit (with commit id 65934&#8230;) that\r
+is reachable from "master" but not from v2.6.18. Compile and test it,\r
+and see whether it crashes. Assume it does crash. Then:</simpara>\r
+<literallayout>$ git bisect bad\r
+Bisecting: 1769 revisions left to test after this\r
+[7eff82c8b1511017ae605f0c99ac275a7e21b867] i2c-core: Drop useless bitmaskings</literallayout>\r
+<simpara>checks out an older version.  Continue like this, telling git at each\r
+stage whether the version it gives you is good or bad, and notice\r
+that the number of revisions left to test is cut approximately in\r
+half each time.</simpara>\r
+<simpara>After about 13 tests (in this case), it will output the commit id of\r
+the guilty commit.  You can then examine the commit with\r
+<ulink url="git-show.html">git-show(1)</ulink>, find out who wrote it, and mail them your bug\r
+report with the commit id.  Finally, run</simpara>\r
+<literallayout>$ git bisect reset</literallayout>\r
+<simpara>to return you to the branch you were on before.</simpara>\r
+<simpara>Note that the version which git-bisect checks out for you at each\r
+point is just a suggestion, and you&#8217;re free to try a different\r
+version if you think it would be a good idea.  For example,\r
+occasionally you may land on a commit that broke something unrelated;\r
+run</simpara>\r
+<literallayout>$ git bisect visualize</literallayout>\r
+<simpara>which will run gitk and label the commit it chose with a marker that\r
+says "bisect".  Choose a safe-looking commit nearby, note its commit\r
+id, and check it out with:</simpara>\r
+<literallayout>$ git reset --hard fb47ddb2db...</literallayout>\r
+<simpara>then test, run "bisect good" or "bisect bad" as appropriate, and\r
+continue.</simpara>\r
+<simpara>Instead of "git bisect visualize" and then "git reset --hard\r
+fb47ddb2db&#8230;", you might just want to tell git that you want to skip\r
+the current commit:</simpara>\r
+<literallayout>$ git bisect skip</literallayout>\r
+<simpara>In this case, though, git may not eventually be able to tell the first\r
+bad one between some first skipped commits and a later bad commit.</simpara>\r
+<simpara>There are also ways to automate the bisecting process if you have a\r
+test script that can tell a good from a bad commit. See\r
+<ulink url="git-bisect.html">git-bisect(1)</ulink> for more information about this and other "git\r
+bisect" features.</simpara>\r
+</section>\r
+<section id="naming-commits">\r
+<title>Naming commits</title>\r
+<simpara>We have seen several ways of naming commits already:</simpara>\r
+<itemizedlist>\r
+<listitem>\r
+<simpara>\r
+40-hexdigit object name\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+branch name: refers to the commit at the head of the given\r
+          branch\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+tag name: refers to the commit pointed to by the given tag\r
+          (we&#8217;ve seen branches and tags are special cases of\r
+          <link linkend="how-git-stores-references">references</link>).\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+HEAD: refers to the head of the current branch\r
+</simpara>\r
+</listitem>\r
+</itemizedlist>\r
+<simpara>There are many more; see the "SPECIFYING REVISIONS" section of the\r
+<ulink url="git-rev-parse.html">git-rev-parse(1)</ulink> man page for the complete list of ways to\r
+name revisions.  Some examples:</simpara>\r
+<literallayout>$ git show fb47ddb2 # the first few characters of the object name\r
+                    # are usually enough to specify it uniquely\r
+$ git show HEAD^    # the parent of the HEAD commit\r
+$ git show HEAD^^   # the grandparent\r
+$ git show HEAD~4   # the great-great-grandparent</literallayout>\r
+<simpara>Recall that merge commits may have more than one parent; by default,\r
+^ and ~ follow the first parent listed in the commit, but you can\r
+also choose:</simpara>\r
+<literallayout>$ git show HEAD^1   # show the first parent of HEAD\r
+$ git show HEAD^2   # show the second parent of HEAD</literallayout>\r
+<simpara>In addition to HEAD, there are several other special names for\r
+commits:</simpara>\r
+<simpara>Merges (to be discussed later), as well as operations such as\r
+git-reset, which change the currently checked-out commit, generally\r
+set ORIG_HEAD to the value HEAD had before the current operation.</simpara>\r
+<simpara>The git-fetch operation always stores the head of the last fetched\r
+branch in FETCH_HEAD.  For example, if you run git fetch without\r
+specifying a local branch as the target of the operation</simpara>\r
+<literallayout>$ git fetch git://example.com/proj.git theirbranch</literallayout>\r
+<simpara>the fetched commits will still be available from FETCH_HEAD.</simpara>\r
+<simpara>When we discuss merges we&#8217;ll also see the special name MERGE_HEAD,\r
+which refers to the other branch that we&#8217;re merging in to the current\r
+branch.</simpara>\r
+<simpara>The <ulink url="git-rev-parse.html">git-rev-parse(1)</ulink> command is a low-level command that is\r
+occasionally useful for translating some name for a commit to the object\r
+name for that commit:</simpara>\r
+<literallayout>$ git rev-parse origin\r
+e05db0fd4f31dde7005f075a84f96b360d05984b</literallayout>\r
+</section>\r
+<section id="creating-tags">\r
+<title>Creating tags</title>\r
+<simpara>We can also create a tag to refer to a particular commit; after\r
+running</simpara>\r
+<literallayout>$ git tag stable-1 1b2e1d63ff</literallayout>\r
+<simpara>You can use stable-1 to refer to the commit 1b2e1d63ff.</simpara>\r
+<simpara>This creates a "lightweight" tag.  If you would also like to include a\r
+comment with the tag, and possibly sign it cryptographically, then you\r
+should create a tag object instead; see the <ulink url="git-tag.html">git-tag(1)</ulink> man page\r
+for details.</simpara>\r
+</section>\r
+<section id="browsing-revisions">\r
+<title>Browsing revisions</title>\r
+<simpara>The <ulink url="git-log.html">git-log(1)</ulink> command can show lists of commits.  On its\r
+own, it shows all commits reachable from the parent commit; but you\r
+can also make more specific requests:</simpara>\r
+<literallayout>$ git log v2.5..        # commits since (not reachable from) v2.5\r
+$ git log test..master  # commits reachable from master but not test\r
+$ git log master..test  # ...reachable from test but not master\r
+$ git log master...test # ...reachable from either test or master,\r
+                        #    but not both\r
+$ git log --since="2 weeks ago" # commits from the last 2 weeks\r
+$ git log Makefile      # commits which modify Makefile\r
+$ git log fs/           # ... which modify any file under fs/\r
+$ git log -S'foo()'     # commits which add or remove any file data\r
+                        # matching the string 'foo()'</literallayout>\r
+<simpara>And of course you can combine all of these; the following finds\r
+commits since v2.5 which touch the Makefile or any file under fs:</simpara>\r
+<literallayout>$ git log v2.5.. Makefile fs/</literallayout>\r
+<simpara>You can also ask git log to show patches:</simpara>\r
+<literallayout>$ git log -p</literallayout>\r
+<simpara>See the "--pretty" option in the <ulink url="git-log.html">git-log(1)</ulink> man page for more\r
+display options.</simpara>\r
+<simpara>Note that git log starts with the most recent commit and works\r
+backwards through the parents; however, since git history can contain\r
+multiple independent lines of development, the particular order that\r
+commits are listed in may be somewhat arbitrary.</simpara>\r
+</section>\r
+<section id="generating-diffs">\r
+<title>Generating diffs</title>\r
+<simpara>You can generate diffs between any two versions using\r
+<ulink url="git-diff.html">git-diff(1)</ulink>:</simpara>\r
+<literallayout>$ git diff master..test</literallayout>\r
+<simpara>That will produce the diff between the tips of the two branches.  If\r
+you&#8217;d prefer to find the diff from their common ancestor to test, you\r
+can use three dots instead of two:</simpara>\r
+<literallayout>$ git diff master...test</literallayout>\r
+<simpara>Sometimes what you want instead is a set of patches; for this you can\r
+use <ulink url="git-format-patch.html">git-format-patch(1)</ulink>:</simpara>\r
+<literallayout>$ git format-patch master..test</literallayout>\r
+<simpara>will generate a file with a patch for each commit reachable from test\r
+but not from master.</simpara>\r
+</section>\r
+<section id="viewing-old-file-versions">\r
+<title>Viewing old file versions</title>\r
+<simpara>You can always view an old version of a file by just checking out the\r
+correct revision first.  But sometimes it is more convenient to be\r
+able to view an old version of a single file without checking\r
+anything out; this command does that:</simpara>\r
+<literallayout>$ git show v2.5:fs/locks.c</literallayout>\r
+<simpara>Before the colon may be anything that names a commit, and after it\r
+may be any path to a file tracked by git.</simpara>\r
+</section>\r
+<section id="history-examples">\r
+<title>Examples</title>\r
+<section id="counting-commits-on-a-branch">\r
+<title>Counting the number of commits on a branch</title>\r
+<simpara>Suppose you want to know how many commits you&#8217;ve made on "mybranch"\r
+since it diverged from "origin":</simpara>\r
+<literallayout>$ git log --pretty=oneline origin..mybranch | wc -l</literallayout>\r
+<simpara>Alternatively, you may often see this sort of thing done with the\r
+lower-level command <ulink url="git-rev-list.html">git-rev-list(1)</ulink>, which just lists the SHA1&#8217;s\r
+of all the given commits:</simpara>\r
+<literallayout>$ git rev-list origin..mybranch | wc -l</literallayout>\r
+</section>\r
+<section id="checking-for-equal-branches">\r
+<title>Check whether two branches point at the same history</title>\r
+<simpara>Suppose you want to check whether two branches point at the same point\r
+in history.</simpara>\r
+<literallayout>$ git diff origin..master</literallayout>\r
+<simpara>will tell you whether the contents of the project are the same at the\r
+two branches; in theory, however, it&#8217;s possible that the same project\r
+contents could have been arrived at by two different historical\r
+routes.  You could compare the object names:</simpara>\r
+<literallayout>$ git rev-list origin\r
+e05db0fd4f31dde7005f075a84f96b360d05984b\r
+$ git rev-list master\r
+e05db0fd4f31dde7005f075a84f96b360d05984b</literallayout>\r
+<simpara>Or you could recall that the &#8230; operator selects all commits\r
+contained reachable from either one reference or the other but not\r
+both: so</simpara>\r
+<literallayout>$ git log origin...master</literallayout>\r
+<simpara>will return no commits when the two branches are equal.</simpara>\r
+</section>\r
+<section id="finding-tagged-descendants">\r
+<title>Find first tagged version including a given fix</title>\r
+<simpara>Suppose you know that the commit e05db0fd fixed a certain problem.\r
+You&#8217;d like to find the earliest tagged release that contains that\r
+fix.</simpara>\r
+<simpara>Of course, there may be more than one answer&#8212;if the history branched\r
+after commit e05db0fd, then there could be multiple "earliest" tagged\r
+releases.</simpara>\r
+<simpara>You could just visually inspect the commits since e05db0fd:</simpara>\r
+<literallayout>$ gitk e05db0fd..</literallayout>\r
+<simpara>Or you can use <ulink url="git-name-rev.html">git-name-rev(1)</ulink>, which will give the commit a\r
+name based on any tag it finds pointing to one of the commit&#8217;s\r
+descendants:</simpara>\r
+<literallayout>$ git name-rev --tags e05db0fd\r
+e05db0fd tags/v1.5.0-rc1^0~23</literallayout>\r
+<simpara>The <ulink url="git-describe.html">git-describe(1)</ulink> command does the opposite, naming the\r
+revision using a tag on which the given commit is based:</simpara>\r
+<literallayout>$ git describe e05db0fd\r
+v1.5.0-rc0-260-ge05db0f</literallayout>\r
+<simpara>but that may sometimes help you guess which tags might come after the\r
+given commit.</simpara>\r
+<simpara>If you just want to verify whether a given tagged version contains a\r
+given commit, you could use <ulink url="git-merge-base.html">git-merge-base(1)</ulink>:</simpara>\r
+<literallayout>$ git merge-base e05db0fd v1.5.0-rc1\r
+e05db0fd4f31dde7005f075a84f96b360d05984b</literallayout>\r
+<simpara>The merge-base command finds a common ancestor of the given commits,\r
+and always returns one or the other in the case where one is a\r
+descendant of the other; so the above output shows that e05db0fd\r
+actually is an ancestor of v1.5.0-rc1.</simpara>\r
+<simpara>Alternatively, note that</simpara>\r
+<literallayout>$ git log v1.5.0-rc1..e05db0fd</literallayout>\r
+<simpara>will produce empty output if and only if v1.5.0-rc1 includes e05db0fd,\r
+because it outputs only commits that are not reachable from v1.5.0-rc1.</simpara>\r
+<simpara>As yet another alternative, the <ulink url="git-show-branch.html">git-show-branch(1)</ulink> command lists\r
+the commits reachable from its arguments with a display on the left-hand\r
+side that indicates which arguments that commit is reachable from.  So,\r
+you can run something like</simpara>\r
+<literallayout>$ git show-branch e05db0fd v1.5.0-rc0 v1.5.0-rc1 v1.5.0-rc2\r
+! [e05db0fd] Fix warnings in sha1_file.c - use C99 printf format if\r
+available\r
+ ! [v1.5.0-rc0] GIT v1.5.0 preview\r
+  ! [v1.5.0-rc1] GIT v1.5.0-rc1\r
+   ! [v1.5.0-rc2] GIT v1.5.0-rc2\r
+...</literallayout>\r
+<simpara>then search for a line that looks like</simpara>\r
+<literallayout>+ ++ [e05db0fd] Fix warnings in sha1_file.c - use C99 printf format if\r
+available</literallayout>\r
+<simpara>Which shows that e05db0fd is reachable from itself, from v1.5.0-rc1, and\r
+from v1.5.0-rc2, but not from v1.5.0-rc0.</simpara>\r
+</section>\r
+<section id="showing-commits-unique-to-a-branch">\r
+<title>Showing commits unique to a given branch</title>\r
+<simpara>Suppose you would like to see all the commits reachable from the branch\r
+head named "master" but not from any other head in your repository.</simpara>\r
+<simpara>We can list all the heads in this repository with\r
+<ulink url="git-show-ref.html">git-show-ref(1)</ulink>:</simpara>\r
+<literallayout>$ git show-ref --heads\r
+bf62196b5e363d73353a9dcf094c59595f3153b7 refs/heads/core-tutorial\r
+db768d5504c1bb46f63ee9d6e1772bd047e05bf9 refs/heads/maint\r
+a07157ac624b2524a059a3414e99f6f44bebc1e7 refs/heads/master\r
+24dbc180ea14dc1aebe09f14c8ecf32010690627 refs/heads/tutorial-2\r
+1e87486ae06626c2f31eaa63d26fc0fd646c8af2 refs/heads/tutorial-fixes</literallayout>\r
+<simpara>We can get just the branch-head names, and remove "master", with\r
+the help of the standard utilities cut and grep:</simpara>\r
+<literallayout>$ git show-ref --heads | cut -d' ' -f2 | grep -v '^refs/heads/master'\r
+refs/heads/core-tutorial\r
+refs/heads/maint\r
+refs/heads/tutorial-2\r
+refs/heads/tutorial-fixes</literallayout>\r
+<simpara>And then we can ask to see all the commits reachable from master\r
+but not from these other heads:</simpara>\r
+<literallayout>$ gitk master --not $( git show-ref --heads | cut -d' ' -f2 |\r
+                                grep -v '^refs/heads/master' )</literallayout>\r
+<simpara>Obviously, endless variations are possible; for example, to see all\r
+commits reachable from some head but not from any tag in the repository:</simpara>\r
+<literallayout>$ gitk $( git show-ref --heads ) --not  $( git show-ref --tags )</literallayout>\r
+<simpara>(See <ulink url="git-rev-parse.html">git-rev-parse(1)</ulink> for explanations of commit-selecting\r
+syntax such as <literal>--not</literal>.)</simpara>\r
+</section>\r
+<section id="making-a-release">\r
+<title>Creating a changelog and tarball for a software release</title>\r
+<simpara>The <ulink url="git-archive.html">git-archive(1)</ulink> command can create a tar or zip archive from\r
+any version of a project; for example:</simpara>\r
+<literallayout>$ git archive --format=tar --prefix=project/ HEAD | gzip &gt;latest.tar.gz</literallayout>\r
+<simpara>will use HEAD to produce a tar archive in which each filename is\r
+preceded by "project/".</simpara>\r
+<simpara>If you&#8217;re releasing a new version of a software project, you may want\r
+to simultaneously make a changelog to include in the release\r
+announcement.</simpara>\r
+<simpara>Linus Torvalds, for example, makes new kernel releases by tagging them,\r
+then running:</simpara>\r
+<literallayout>$ release-script 2.6.12 2.6.13-rc6 2.6.13-rc7</literallayout>\r
+<simpara>where release-script is a shell script that looks like:</simpara>\r
+<literallayout>#!/bin/sh\r
+stable="$1"\r
+last="$2"\r
+new="$3"\r
+echo "# git tag v$new"\r
+echo "git archive --prefix=linux-$new/ v$new | gzip -9 &gt; ../linux-$new.tar.gz"\r
+echo "git diff v$stable v$new | gzip -9 &gt; ../patch-$new.gz"\r
+echo "git log --no-merges v$new ^v$last &gt; ../ChangeLog-$new"\r
+echo "git shortlog --no-merges v$new ^v$last &gt; ../ShortLog"\r
+echo "git diff --stat --summary -M v$last v$new &gt; ../diffstat-$new"</literallayout>\r
+<simpara>and then he just cut-and-pastes the output commands after verifying that\r
+they look OK.</simpara>\r
+</section>\r
+<section id="Finding-comments-With-given-Content">\r
+<title>Finding commits referencing a file with given content</title>\r
+<simpara>Somebody hands you a copy of a file, and asks which commits modified a\r
+file such that it contained the given content either before or after the\r
+commit.  You can find out with this:</simpara>\r
+<literallayout>$  git log --raw --abbrev=40 --pretty=oneline |\r
+        grep -B 1 `git hash-object filename`</literallayout>\r
+<simpara>Figuring out why this works is left as an exercise to the (advanced)\r
+student.  The <ulink url="git-log.html">git-log(1)</ulink>, <ulink url="git-diff-tree.html">git-diff-tree(1)</ulink>, and\r
+<ulink url="git-hash-object.html">git-hash-object(1)</ulink> man pages may prove helpful.</simpara>\r
+</section>\r
+</section>\r
+</section>\r
+<section id="Developing-With-git">\r
+<title>Developing with git</title>\r
+<section id="telling-git-your-name">\r
+<title>Telling git your name</title>\r
+<simpara>Before creating any commits, you should introduce yourself to git.  The\r
+easiest way to do so is to make sure the following lines appear in a\r
+file named .gitconfig in your home directory:</simpara>\r
+<literallayout>[user]\r
+        name = Your Name Comes Here\r
+        email = you@yourdomain.example.com</literallayout>\r
+<simpara>(See the "CONFIGURATION FILE" section of <ulink url="git-config.html">git-config(1)</ulink> for\r
+details on the configuration file.)</simpara>\r
+</section>\r
+<section id="creating-a-new-repository">\r
+<title>Creating a new repository</title>\r
+<simpara>Creating a new repository from scratch is very easy:</simpara>\r
+<literallayout>$ mkdir project\r
+$ cd project\r
+$ git init</literallayout>\r
+<simpara>If you have some initial content (say, a tarball):</simpara>\r
+<literallayout>$ tar xzvf project.tar.gz\r
+$ cd project\r
+$ git init\r
+$ git add . # include everything below ./ in the first commit:\r
+$ git commit</literallayout>\r
+</section>\r
+<section id="how-to-make-a-commit">\r
+<title>How to make a commit</title>\r
+<simpara>Creating a new commit takes three steps:</simpara>\r
+<orderedlist numeration="arabic">\r
+<listitem>\r
+<simpara>\r
+Making some changes to the working directory using your\r
+           favorite editor.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Telling git about your changes.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Creating the commit using the content you told git about\r
+           in step 2.\r
+</simpara>\r
+</listitem>\r
+</orderedlist>\r
+<simpara>In practice, you can interleave and repeat steps 1 and 2 as many\r
+times as you want: in order to keep track of what you want committed\r
+at step 3, git maintains a snapshot of the tree&#8217;s contents in a\r
+special staging area called "the index."</simpara>\r
+<simpara>At the beginning, the content of the index will be identical to\r
+that of the HEAD.  The command "git diff --cached", which shows\r
+the difference between the HEAD and the index, should therefore\r
+produce no output at that point.</simpara>\r
+<simpara>Modifying the index is easy:</simpara>\r
+<simpara>To update the index with the new contents of a modified file, use</simpara>\r
+<literallayout>$ git add path/to/file</literallayout>\r
+<simpara>To add the contents of a new file to the index, use</simpara>\r
+<literallayout>$ git add path/to/file</literallayout>\r
+<simpara>To remove a file from the index and from the working tree,</simpara>\r
+<literallayout>$ git rm path/to/file</literallayout>\r
+<simpara>After each step you can verify that</simpara>\r
+<literallayout>$ git diff --cached</literallayout>\r
+<simpara>always shows the difference between the HEAD and the index file&#8212;this\r
+is what you&#8217;d commit if you created the commit now&#8212;and that</simpara>\r
+<literallayout>$ git diff</literallayout>\r
+<simpara>shows the difference between the working tree and the index file.</simpara>\r
+<simpara>Note that "git-add" always adds just the current contents of a file\r
+to the index; further changes to the same file will be ignored unless\r
+you run git-add on the file again.</simpara>\r
+<simpara>When you&#8217;re ready, just run</simpara>\r
+<literallayout>$ git commit</literallayout>\r
+<simpara>and git will prompt you for a commit message and then create the new\r
+commit.  Check to make sure it looks like what you expected with</simpara>\r
+<literallayout>$ git show</literallayout>\r
+<simpara>As a special shortcut,</simpara>\r
+<literallayout>$ git commit -a</literallayout>\r
+<simpara>will update the index with any files that you&#8217;ve modified or removed\r
+and create a commit, all in one step.</simpara>\r
+<simpara>A number of commands are useful for keeping track of what you&#8217;re\r
+about to commit:</simpara>\r
+<literallayout>$ git diff --cached # difference between HEAD and the index; what\r
+                    # would be committed if you ran "commit" now.\r
+$ git diff          # difference between the index file and your\r
+                    # working directory; changes that would not\r
+                    # be included if you ran "commit" now.\r
+$ git diff HEAD     # difference between HEAD and working tree; what\r
+                    # would be committed if you ran "commit -a" now.\r
+$ git status        # a brief per-file summary of the above.</literallayout>\r
+<simpara>You can also use <ulink url="git-gui.html">git-gui(1)</ulink> to create commits, view changes in\r
+the index and the working tree files, and individually select diff hunks\r
+for inclusion in the index (by right-clicking on the diff hunk and\r
+choosing "Stage Hunk For Commit").</simpara>\r
+</section>\r
+<section id="creating-good-commit-messages">\r
+<title>Creating good commit messages</title>\r
+<simpara>Though not required, it&#8217;s a good idea to begin the commit message\r
+with a single short (less than 50 character) line summarizing the\r
+change, followed by a blank line and then a more thorough\r
+description.  Tools that turn commits into email, for example, use\r
+the first line on the Subject line and the rest of the commit in the\r
+body.</simpara>\r
+</section>\r
+<section id="ignoring-files">\r
+<title>Ignoring files</title>\r
+<simpara>A project will often generate files that you do <emphasis>not</emphasis> want to track with git.\r
+This typically includes files generated by a build process or temporary\r
+backup files made by your editor. Of course, <emphasis>not</emphasis> tracking files with git\r
+is just a matter of <emphasis>not</emphasis> calling "<literal>git-add</literal>" on them. But it quickly becomes\r
+annoying to have these untracked files lying around; e.g. they make\r
+"<literal>git add .</literal>" practically useless, and they keep showing up in the output of\r
+"<literal>git status</literal>".</simpara>\r
+<simpara>You can tell git to ignore certain files by creating a file called .gitignore\r
+in the top level of your working directory, with contents such as:</simpara>\r
+<literallayout># Lines starting with '#' are considered comments.\r
+# Ignore any file named foo.txt.\r
+foo.txt\r
+# Ignore (generated) html files,\r
+*.html\r
+# except foo.html which is maintained by hand.\r
+!foo.html\r
+# Ignore objects and archives.\r
+*.[oa]</literallayout>\r
+<simpara>See <ulink url="gitignore.html">gitignore(5)</ulink> for a detailed explanation of the syntax.  You can\r
+also place .gitignore files in other directories in your working tree, and they\r
+will apply to those directories and their subdirectories.  The <literal>.gitignore</literal>\r
+files can be added to your repository like any other files (just run <literal>git add\r
+.gitignore</literal> and <literal>git commit</literal>, as usual), which is convenient when the exclude\r
+patterns (such as patterns matching build output files) would also make sense\r
+for other users who clone your repository.</simpara>\r
+<simpara>If you wish the exclude patterns to affect only certain repositories\r
+(instead of every repository for a given project), you may instead put\r
+them in a file in your repository named .git/info/exclude, or in any file\r
+specified by the <literal>core.excludesfile</literal> configuration variable.  Some git\r
+commands can also take exclude patterns directly on the command line.\r
+See <ulink url="gitignore.html">gitignore(5)</ulink> for the details.</simpara>\r
+</section>\r
+<section id="how-to-merge">\r
+<title>How to merge</title>\r
+<simpara>You can rejoin two diverging branches of development using\r
+<ulink url="git-merge.html">git-merge(1)</ulink>:</simpara>\r
+<literallayout>$ git merge branchname</literallayout>\r
+<simpara>merges the development in the branch "branchname" into the current\r
+branch.  If there are conflicts&#8212;for example, if the same file is\r
+modified in two different ways in the remote branch and the local\r
+branch&#8212;then you are warned; the output may look something like this:</simpara>\r
+<literallayout>$ git merge next\r
+ 100% (4/4) done\r
+Auto-merged file.txt\r
+CONFLICT (content): Merge conflict in file.txt\r
+Automatic merge failed; fix conflicts and then commit the result.</literallayout>\r
+<simpara>Conflict markers are left in the problematic files, and after\r
+you resolve the conflicts manually, you can update the index\r
+with the contents and run git commit, as you normally would when\r
+creating a new file.</simpara>\r
+<simpara>If you examine the resulting commit using gitk, you will see that it\r
+has two parents, one pointing to the top of the current branch, and\r
+one to the top of the other branch.</simpara>\r
+</section>\r
+<section id="resolving-a-merge">\r
+<title>Resolving a merge</title>\r
+<simpara>When a merge isn&#8217;t resolved automatically, git leaves the index and\r
+the working tree in a special state that gives you all the\r
+information you need to help resolve the merge.</simpara>\r
+<simpara>Files with conflicts are marked specially in the index, so until you\r
+resolve the problem and update the index, <ulink url="git-commit.html">git-commit(1)</ulink> will\r
+fail:</simpara>\r
+<literallayout>$ git commit\r
+file.txt: needs merge</literallayout>\r
+<simpara>Also, <ulink url="git-status.html">git-status(1)</ulink> will list those files as "unmerged", and the\r
+files with conflicts will have conflict markers added, like this:</simpara>\r
+<literallayout>&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD:file.txt\r
+Hello world\r
+=======\r
+Goodbye\r
+&gt;&gt;&gt;&gt;&gt;&gt;&gt; 77976da35a11db4580b80ae27e8d65caf5208086:file.txt</literallayout>\r
+<simpara>All you need to do is edit the files to resolve the conflicts, and then</simpara>\r
+<literallayout>$ git add file.txt\r
+$ git commit</literallayout>\r
+<simpara>Note that the commit message will already be filled in for you with\r
+some information about the merge.  Normally you can just use this\r
+default message unchanged, but you may add additional commentary of\r
+your own if desired.</simpara>\r
+<simpara>The above is all you need to know to resolve a simple merge.  But git\r
+also provides more information to help resolve conflicts:</simpara>\r
+<section id="conflict-resolution">\r
+<title>Getting conflict-resolution help during a merge</title>\r
+<simpara>All of the changes that git was able to merge automatically are\r
+already added to the index file, so <ulink url="git-diff.html">git-diff(1)</ulink> shows only\r
+the conflicts.  It uses an unusual syntax:</simpara>\r
+<literallayout>$ git diff\r
+diff --cc file.txt\r
+index 802992c,2b60207..0000000\r
+--- a/file.txt\r
++++ b/file.txt\r
+@@@ -1,1 -1,1 +1,5 @@@\r
+++&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD:file.txt\r
+ +Hello world\r
+++=======\r
++ Goodbye\r
+++&gt;&gt;&gt;&gt;&gt;&gt;&gt; 77976da35a11db4580b80ae27e8d65caf5208086:file.txt</literallayout>\r
+<simpara>Recall that the commit which will be committed after we resolve this\r
+conflict will have two parents instead of the usual one: one parent\r
+will be HEAD, the tip of the current branch; the other will be the\r
+tip of the other branch, which is stored temporarily in MERGE_HEAD.</simpara>\r
+<simpara>During the merge, the index holds three versions of each file.  Each of\r
+these three "file stages" represents a different version of the file:</simpara>\r
+<literallayout>$ git show :1:file.txt  # the file in a common ancestor of both branches\r
+$ git show :2:file.txt  # the version from HEAD.\r
+$ git show :3:file.txt  # the version from MERGE_HEAD.</literallayout>\r
+<simpara>When you ask <ulink url="git-diff.html">git-diff(1)</ulink> to show the conflicts, it runs a\r
+three-way diff between the conflicted merge results in the work tree with\r
+stages 2 and 3 to show only hunks whose contents come from both sides,\r
+mixed (in other words, when a hunk&#8217;s merge results come only from stage 2,\r
+that part is not conflicting and is not shown.  Same for stage 3).</simpara>\r
+<simpara>The diff above shows the differences between the working-tree version of\r
+file.txt and the stage 2 and stage 3 versions.  So instead of preceding\r
+each line by a single "+" or "-", it now uses two columns: the first\r
+column is used for differences between the first parent and the working\r
+directory copy, and the second for differences between the second parent\r
+and the working directory copy.  (See the "COMBINED DIFF FORMAT" section\r
+of <ulink url="git-diff-files.html">git-diff-files(1)</ulink> for a details of the format.)</simpara>\r
+<simpara>After resolving the conflict in the obvious way (but before updating the\r
+index), the diff will look like:</simpara>\r
+<literallayout>$ git diff\r
+diff --cc file.txt\r
+index 802992c,2b60207..0000000\r
+--- a/file.txt\r
++++ b/file.txt\r
+@@@ -1,1 -1,1 +1,1 @@@\r
+- Hello world\r
+ -Goodbye\r
+++Goodbye world</literallayout>\r
+<simpara>This shows that our resolved version deleted "Hello world" from the\r
+first parent, deleted "Goodbye" from the second parent, and added\r
+"Goodbye world", which was previously absent from both.</simpara>\r
+<simpara>Some special diff options allow diffing the working directory against\r
+any of these stages:</simpara>\r
+<literallayout>$ git diff -1 file.txt          # diff against stage 1\r
+$ git diff --base file.txt      # same as the above\r
+$ git diff -2 file.txt          # diff against stage 2\r
+$ git diff --ours file.txt      # same as the above\r
+$ git diff -3 file.txt          # diff against stage 3\r
+$ git diff --theirs file.txt    # same as the above.</literallayout>\r
+<simpara>The <ulink url="git-log.html">git-log(1)</ulink> and <ulink url="gitk.html">gitk(1)</ulink> commands also provide special help\r
+for merges:</simpara>\r
+<literallayout>$ git log --merge\r
+$ gitk --merge</literallayout>\r
+<simpara>These will display all commits which exist only on HEAD or on\r
+MERGE_HEAD, and which touch an unmerged file.</simpara>\r
+<simpara>You may also use <ulink url="git-mergetool.html">git-mergetool(1)</ulink>, which lets you merge the\r
+unmerged files using external tools such as Emacs or kdiff3.</simpara>\r
+<simpara>Each time you resolve the conflicts in a file and update the index:</simpara>\r
+<literallayout>$ git add file.txt</literallayout>\r
+<simpara>the different stages of that file will be "collapsed", after which\r
+git-diff will (by default) no longer show diffs for that file.</simpara>\r
+</section>\r
+</section>\r
+<section id="undoing-a-merge">\r
+<title>Undoing a merge</title>\r
+<simpara>If you get stuck and decide to just give up and throw the whole mess\r
+away, you can always return to the pre-merge state with</simpara>\r
+<literallayout>$ git reset --hard HEAD</literallayout>\r
+<simpara>Or, if you&#8217;ve already committed the merge that you want to throw away,</simpara>\r
+<literallayout>$ git reset --hard ORIG_HEAD</literallayout>\r
+<simpara>However, this last command can be dangerous in some cases&#8212;never\r
+throw away a commit you have already committed if that commit may\r
+itself have been merged into another branch, as doing so may confuse\r
+further merges.</simpara>\r
+</section>\r
+<section id="fast-forwards">\r
+<title>Fast-forward merges</title>\r
+<simpara>There is one special case not mentioned above, which is treated\r
+differently.  Normally, a merge results in a merge commit, with two\r
+parents, one pointing at each of the two lines of development that\r
+were merged.</simpara>\r
+<simpara>However, if the current branch is a descendant of the other&#8212;so every\r
+commit present in the one is already contained in the other&#8212;then git\r
+just performs a "fast forward"; the head of the current branch is moved\r
+forward to point at the head of the merged-in branch, without any new\r
+commits being created.</simpara>\r
+</section>\r
+<section id="fixing-mistakes">\r
+<title>Fixing mistakes</title>\r
+<simpara>If you&#8217;ve messed up the working tree, but haven&#8217;t yet committed your\r
+mistake, you can return the entire working tree to the last committed\r
+state with</simpara>\r
+<literallayout>$ git reset --hard HEAD</literallayout>\r
+<simpara>If you make a commit that you later wish you hadn&#8217;t, there are two\r
+fundamentally different ways to fix the problem:</simpara>\r
+<orderedlist numeration="arabic">\r
+<listitem>\r
+<simpara>\r
+You can create a new commit that undoes whatever was done\r
+        by the old commit.  This is the correct thing if your\r
+        mistake has already been made public.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+You can go back and modify the old commit.  You should\r
+        never do this if you have already made the history public;\r
+        git does not normally expect the "history" of a project to\r
+        change, and cannot correctly perform repeated merges from\r
+        a branch that has had its history changed.\r
+</simpara>\r
+</listitem>\r
+</orderedlist>\r
+<section id="reverting-a-commit">\r
+<title>Fixing a mistake with a new commit</title>\r
+<simpara>Creating a new commit that reverts an earlier change is very easy;\r
+just pass the <ulink url="git-revert.html">git-revert(1)</ulink> command a reference to the bad\r
+commit; for example, to revert the most recent commit:</simpara>\r
+<literallayout>$ git revert HEAD</literallayout>\r
+<simpara>This will create a new commit which undoes the change in HEAD.  You\r
+will be given a chance to edit the commit message for the new commit.</simpara>\r
+<simpara>You can also revert an earlier change, for example, the next-to-last:</simpara>\r
+<literallayout>$ git revert HEAD^</literallayout>\r
+<simpara>In this case git will attempt to undo the old change while leaving\r
+intact any changes made since then.  If more recent changes overlap\r
+with the changes to be reverted, then you will be asked to fix\r
+conflicts manually, just as in the case of <link linkend="resolving-a-merge">resolving a merge</link>.</simpara>\r
+</section>\r
+<section id="fixing-a-mistake-by-rewriting-history">\r
+<title>Fixing a mistake by rewriting history</title>\r
+<simpara>If the problematic commit is the most recent commit, and you have not\r
+yet made that commit public, then you may just\r
+<link linkend="undoing-a-merge">destroy it using git-reset</link>.</simpara>\r
+<simpara>Alternatively, you\r
+can edit the working directory and update the index to fix your\r
+mistake, just as if you were going to <link linkend="how-to-make-a-commit">create a new commit</link>, then run</simpara>\r
+<literallayout>$ git commit --amend</literallayout>\r
+<simpara>which will replace the old commit by a new commit incorporating your\r
+changes, giving you a chance to edit the old commit message first.</simpara>\r
+<simpara>Again, you should never do this to a commit that may already have\r
+been merged into another branch; use <ulink url="git-revert.html">git-revert(1)</ulink> instead in\r
+that case.</simpara>\r
+<simpara>It is also possible to replace commits further back in the history, but\r
+this is an advanced topic to be left for\r
+<link linkend="cleaning-up-history">another chapter</link>.</simpara>\r
+</section>\r
+<section id="checkout-of-path">\r
+<title>Checking out an old version of a file</title>\r
+<simpara>In the process of undoing a previous bad change, you may find it\r
+useful to check out an older version of a particular file using\r
+<ulink url="git-checkout.html">git-checkout(1)</ulink>.  We&#8217;ve used git-checkout before to switch\r
+branches, but it has quite different behavior if it is given a path\r
+name: the command</simpara>\r
+<literallayout>$ git checkout HEAD^ path/to/file</literallayout>\r
+<simpara>replaces path/to/file by the contents it had in the commit HEAD^, and\r
+also updates the index to match.  It does not change branches.</simpara>\r
+<simpara>If you just want to look at an old version of the file, without\r
+modifying the working directory, you can do that with\r
+<ulink url="git-show.html">git-show(1)</ulink>:</simpara>\r
+<literallayout>$ git show HEAD^:path/to/file</literallayout>\r
+<simpara>which will display the given version of the file.</simpara>\r
+</section>\r
+<section id="interrupted-work">\r
+<title>Temporarily setting aside work in progress</title>\r
+<simpara>While you are in the middle of working on something complicated, you\r
+find an unrelated but obvious and trivial bug.  You would like to fix it\r
+before continuing.  You can use <ulink url="git-stash.html">git-stash(1)</ulink> to save the current\r
+state of your work, and after fixing the bug (or, optionally after doing\r
+so on a different branch and then coming back), unstash the\r
+work-in-progress changes.</simpara>\r
+<literallayout>$ git stash save "work in progress for foo feature"</literallayout>\r
+<simpara>This command will save your changes away to the <literal>stash</literal>, and\r
+reset your working tree and the index to match the tip of your\r
+current branch.  Then you can make your fix as usual.</simpara>\r
+<literallayout>... edit and test ...\r
+$ git commit -a -m "blorpl: typofix"</literallayout>\r
+<simpara>After that, you can go back to what you were working on with\r
+<literal>git stash apply</literal>:</simpara>\r
+<literallayout>$ git stash apply</literallayout>\r
+</section>\r
+</section>\r
+<section id="ensuring-good-performance">\r
+<title>Ensuring good performance</title>\r
+<simpara>On large repositories, git depends on compression to keep the history\r
+information from taking up too much space on disk or in memory.</simpara>\r
+<simpara>This compression is not performed automatically.  Therefore you\r
+should occasionally run <ulink url="git-gc.html">git-gc(1)</ulink>:</simpara>\r
+<literallayout>$ git gc</literallayout>\r
+<simpara>to recompress the archive.  This can be very time-consuming, so\r
+you may prefer to run git-gc when you are not doing other work.</simpara>\r
+</section>\r
+<section id="ensuring-reliability">\r
+<title>Ensuring reliability</title>\r
+<section id="checking-for-corruption">\r
+<title>Checking the repository for corruption</title>\r
+<simpara>The <ulink url="git-fsck.html">git-fsck(1)</ulink> command runs a number of self-consistency checks\r
+on the repository, and reports on any problems.  This may take some\r
+time.  The most common warning by far is about "dangling" objects:</simpara>\r
+<literallayout>$ git fsck\r
+dangling commit 7281251ddd2a61e38657c827739c57015671a6b3\r
+dangling commit 2706a059f258c6b245f298dc4ff2ccd30ec21a63\r
+dangling commit 13472b7c4b80851a1bc551779171dcb03655e9b5\r
+dangling blob 218761f9d90712d37a9c5e36f406f92202db07eb\r
+dangling commit bf093535a34a4d35731aa2bd90fe6b176302f14f\r
+dangling commit 8e4bec7f2ddaa268bef999853c25755452100f8e\r
+dangling tree d50bb86186bf27b681d25af89d3b5b68382e4085\r
+dangling tree b24c2473f1fd3d91352a624795be026d64c8841f\r
+...</literallayout>\r
+<simpara>Dangling objects are not a problem.  At worst they may take up a little\r
+extra disk space.  They can sometimes provide a last-resort method for\r
+recovering lost work&#8212;see <xref linkend="dangling-objects"/> for details.</simpara>\r
+</section>\r
+<section id="recovering-lost-changes">\r
+<title>Recovering lost changes</title>\r
+<section id="reflogs">\r
+<title>Reflogs</title>\r
+<simpara>Say you modify a branch with <literal><ulink url="git-reset.html">git-reset(1)</ulink> --hard</literal>, and then\r
+realize that the branch was the only reference you had to that point in\r
+history.</simpara>\r
+<simpara>Fortunately, git also keeps a log, called a "reflog", of all the\r
+previous values of each branch.  So in this case you can still find the\r
+old history using, for example,</simpara>\r
+<literallayout>$ git log master@{1}</literallayout>\r
+<simpara>This lists the commits reachable from the previous version of the\r
+"master" branch head.  This syntax can be used with any git command\r
+that accepts a commit, not just with git log.  Some other examples:</simpara>\r
+<literallayout>$ git show master@{2}           # See where the branch pointed 2,\r
+$ git show master@{3}           # 3, ... changes ago.\r
+$ gitk master@{yesterday}       # See where it pointed yesterday,\r
+$ gitk master@{"1 week ago"}    # ... or last week\r
+$ git log --walk-reflogs master # show reflog entries for master</literallayout>\r
+<simpara>A separate reflog is kept for the HEAD, so</simpara>\r
+<literallayout>$ git show HEAD@{"1 week ago"}</literallayout>\r
+<simpara>will show what HEAD pointed to one week ago, not what the current branch\r
+pointed to one week ago.  This allows you to see the history of what\r
+you&#8217;ve checked out.</simpara>\r
+<simpara>The reflogs are kept by default for 30 days, after which they may be\r
+pruned.  See <ulink url="git-reflog.html">git-reflog(1)</ulink> and <ulink url="git-gc.html">git-gc(1)</ulink> to learn\r
+how to control this pruning, and see the "SPECIFYING REVISIONS"\r
+section of <ulink url="git-rev-parse.html">git-rev-parse(1)</ulink> for details.</simpara>\r
+<simpara>Note that the reflog history is very different from normal git history.\r
+While normal history is shared by every repository that works on the\r
+same project, the reflog history is not shared: it tells you only about\r
+how the branches in your local repository have changed over time.</simpara>\r
+</section>\r
+<section id="dangling-object-recovery">\r
+<title>Examining dangling objects</title>\r
+<simpara>In some situations the reflog may not be able to save you.  For example,\r
+suppose you delete a branch, then realize you need the history it\r
+contained.  The reflog is also deleted; however, if you have not yet\r
+pruned the repository, then you may still be able to find the lost\r
+commits in the dangling objects that git-fsck reports.  See\r
+<xref linkend="dangling-objects"/> for the details.</simpara>\r
+<literallayout>$ git fsck\r
+dangling commit 7281251ddd2a61e38657c827739c57015671a6b3\r
+dangling commit 2706a059f258c6b245f298dc4ff2ccd30ec21a63\r
+dangling commit 13472b7c4b80851a1bc551779171dcb03655e9b5\r
+...</literallayout>\r
+<simpara>You can examine\r
+one of those dangling commits with, for example,</simpara>\r
+<literallayout>$ gitk 7281251ddd --not --all</literallayout>\r
+<simpara>which does what it sounds like: it says that you want to see the commit\r
+history that is described by the dangling commit(s), but not the\r
+history that is described by all your existing branches and tags.  Thus\r
+you get exactly the history reachable from that commit that is lost.\r
+(And notice that it might not be just one commit: we only report the\r
+"tip of the line" as being dangling, but there might be a whole deep\r
+and complex commit history that was dropped.)</simpara>\r
+<simpara>If you decide you want the history back, you can always create a new\r
+reference pointing to it, for example, a new branch:</simpara>\r
+<literallayout>$ git branch recovered-branch 7281251ddd</literallayout>\r
+<simpara>Other types of dangling objects (blobs and trees) are also possible, and\r
+dangling objects can arise in other situations.</simpara>\r
+</section>\r
+</section>\r
+</section>\r
+</section>\r
+<section id="sharing-development">\r
+<title>Sharing development with others</title>\r
+<section id="getting-updates-With-git-pull">\r
+<title>Getting updates with git-pull</title>\r
+<simpara>After you clone a repository and make a few changes of your own, you\r
+may wish to check the original repository for updates and merge them\r
+into your own work.</simpara>\r
+<simpara>We have already seen <link linkend="Updating-a-repository-With-git-fetch">how to keep remote tracking branches up to date</link> with <ulink url="git-fetch.html">git-fetch(1)</ulink>,\r
+and how to merge two branches.  So you can merge in changes from the\r
+original repository&#8217;s master branch with:</simpara>\r
+<literallayout>$ git fetch\r
+$ git merge origin/master</literallayout>\r
+<simpara>However, the <ulink url="git-pull.html">git-pull(1)</ulink> command provides a way to do this in\r
+one step:</simpara>\r
+<literallayout>$ git pull origin master</literallayout>\r
+<simpara>In fact, if you have "master" checked out, then by default "git pull"\r
+merges from the HEAD branch of the origin repository.  So often you can\r
+accomplish the above with just a simple</simpara>\r
+<literallayout>$ git pull</literallayout>\r
+<simpara>More generally, a branch that is created from a remote branch will pull\r
+by default from that branch.  See the descriptions of the\r
+branch.&lt;name&gt;.remote and branch.&lt;name&gt;.merge options in\r
+<ulink url="git-config.html">git-config(1)</ulink>, and the discussion of the <literal>--track</literal> option in\r
+<ulink url="git-checkout.html">git-checkout(1)</ulink>, to learn how to control these defaults.</simpara>\r
+<simpara>In addition to saving you keystrokes, "git pull" also helps you by\r
+producing a default commit message documenting the branch and\r
+repository that you pulled from.</simpara>\r
+<simpara>(But note that no such commit will be created in the case of a\r
+<link linkend="fast-forwards">fast forward</link>; instead, your branch will just be\r
+updated to point to the latest commit from the upstream branch.)</simpara>\r
+<simpara>The git-pull command can also be given "." as the "remote" repository,\r
+in which case it just merges in a branch from the current repository; so\r
+the commands</simpara>\r
+<literallayout>$ git pull . branch\r
+$ git merge branch</literallayout>\r
+<simpara>are roughly equivalent.  The former is actually very commonly used.</simpara>\r
+</section>\r
+<section id="submitting-patches">\r
+<title>Submitting patches to a project</title>\r
+<simpara>If you just have a few changes, the simplest way to submit them may\r
+just be to send them as patches in email:</simpara>\r
+<simpara>First, use <ulink url="git-format-patch.html">git-format-patch(1)</ulink>; for example:</simpara>\r
+<literallayout>$ git format-patch origin</literallayout>\r
+<simpara>will produce a numbered series of files in the current directory, one\r
+for each patch in the current branch but not in origin/HEAD.</simpara>\r
+<simpara>You can then import these into your mail client and send them by\r
+hand.  However, if you have a lot to send at once, you may prefer to\r
+use the <ulink url="git-send-email.html">git-send-email(1)</ulink> script to automate the process.\r
+Consult the mailing list for your project first to determine how they\r
+prefer such patches be handled.</simpara>\r
+</section>\r
+<section id="importing-patches">\r
+<title>Importing patches to a project</title>\r
+<simpara>Git also provides a tool called <ulink url="git-am.html">git-am(1)</ulink> (am stands for\r
+"apply mailbox"), for importing such an emailed series of patches.\r
+Just save all of the patch-containing messages, in order, into a\r
+single mailbox file, say "patches.mbox", then run</simpara>\r
+<literallayout>$ git am -3 patches.mbox</literallayout>\r
+<simpara>Git will apply each patch in order; if any conflicts are found, it\r
+will stop, and you can fix the conflicts as described in\r
+"<link linkend="resolving-a-merge">Resolving a merge</link>".  (The "-3" option tells\r
+git to perform a merge; if you would prefer it just to abort and\r
+leave your tree and index untouched, you may omit that option.)</simpara>\r
+<simpara>Once the index is updated with the results of the conflict\r
+resolution, instead of creating a new commit, just run</simpara>\r
+<literallayout>$ git am --resolved</literallayout>\r
+<simpara>and git will create the commit for you and continue applying the\r
+remaining patches from the mailbox.</simpara>\r
+<simpara>The final result will be a series of commits, one for each patch in\r
+the original mailbox, with authorship and commit log message each\r
+taken from the message containing each patch.</simpara>\r
+</section>\r
+<section id="public-repositories">\r
+<title>Public git repositories</title>\r
+<simpara>Another way to submit changes to a project is to tell the maintainer\r
+of that project to pull the changes from your repository using\r
+<ulink url="git-pull.html">git-pull(1)</ulink>.  In the section "<link linkend="getting-updates-With-git-pull">Getting updates with git-pull</link>" we described this as a way to get\r
+updates from the "main" repository, but it works just as well in the\r
+other direction.</simpara>\r
+<simpara>If you and the maintainer both have accounts on the same machine, then\r
+you can just pull changes from each other&#8217;s repositories directly;\r
+commands that accept repository URLs as arguments will also accept a\r
+local directory name:</simpara>\r
+<literallayout>$ git clone /path/to/repository\r
+$ git pull /path/to/other/repository</literallayout>\r
+<simpara>or an ssh URL:</simpara>\r
+<literallayout>$ git clone ssh://yourhost/~you/repository</literallayout>\r
+<simpara>For projects with few developers, or for synchronizing a few private\r
+repositories, this may be all you need.</simpara>\r
+<simpara>However, the more common way to do this is to maintain a separate public\r
+repository (usually on a different host) for others to pull changes\r
+from.  This is usually more convenient, and allows you to cleanly\r
+separate private work in progress from publicly visible work.</simpara>\r
+<simpara>You will continue to do your day-to-day work in your personal\r
+repository, but periodically "push" changes from your personal\r
+repository into your public repository, allowing other developers to\r
+pull from that repository.  So the flow of changes, in a situation\r
+where there is one other developer with a public repository, looks\r
+like this:</simpara>\r
+<literallayout class="monospaced">                      you push\r
+your personal repo ------------------&gt; your public repo\r
+      ^                                     |\r
+      |                                     |\r
+      | you pull                            | they pull\r
+      |                                     |\r
+      |                                     |\r
+      |               they push             V\r
+their public repo &lt;------------------- their repo</literallayout>\r
+<simpara>We explain how to do this in the following sections.</simpara>\r
+<section id="setting-up-a-public-repository">\r
+<title>Setting up a public repository</title>\r
+<simpara>Assume your personal repository is in the directory ~/proj.  We\r
+first create a new clone of the repository and tell git-daemon that it\r
+is meant to be public:</simpara>\r
+<literallayout>$ git clone --bare ~/proj proj.git\r
+$ touch proj.git/git-daemon-export-ok</literallayout>\r
+<simpara>The resulting directory proj.git contains a "bare" git repository&#8212;it is\r
+just the contents of the ".git" directory, without any files checked out\r
+around it.</simpara>\r
+<simpara>Next, copy proj.git to the server where you plan to host the\r
+public repository.  You can use scp, rsync, or whatever is most\r
+convenient.</simpara>\r
+</section>\r
+<section id="exporting-via-git">\r
+<title>Exporting a git repository via the git protocol</title>\r
+<simpara>This is the preferred method.</simpara>\r
+<simpara>If someone else administers the server, they should tell you what\r
+directory to put the repository in, and what git:// URL it will appear\r
+at.  You can then skip to the section\r
+"<link linkend="pushing-changes-to-a-public-repository">Pushing changes to a public repository</link>", below.</simpara>\r
+<simpara>Otherwise, all you need to do is start <ulink url="git-daemon.html">git-daemon(1)</ulink>; it will\r
+listen on port 9418.  By default, it will allow access to any directory\r
+that looks like a git directory and contains the magic file\r
+git-daemon-export-ok.  Passing some directory paths as git-daemon\r
+arguments will further restrict the exports to those paths.</simpara>\r
+<simpara>You can also run git-daemon as an inetd service; see the\r
+<ulink url="git-daemon.html">git-daemon(1)</ulink> man page for details.  (See especially the\r
+examples section.)</simpara>\r
+</section>\r
+<section id="exporting-via-http">\r
+<title>Exporting a git repository via http</title>\r
+<simpara>The git protocol gives better performance and reliability, but on a\r
+host with a web server set up, http exports may be simpler to set up.</simpara>\r
+<simpara>All you need to do is place the newly created bare git repository in\r
+a directory that is exported by the web server, and make some\r
+adjustments to give web clients some extra information they need:</simpara>\r
+<literallayout>$ mv proj.git /home/you/public_html/proj.git\r
+$ cd proj.git\r
+$ git --bare update-server-info\r
+$ mv hooks/post-update.sample hooks/post-update</literallayout>\r
+<simpara>(For an explanation of the last two lines, see\r
+<ulink url="git-update-server-info.html">git-update-server-info(1)</ulink> and <ulink url="githooks.html">githooks(5)</ulink>.)</simpara>\r
+<simpara>Advertise the URL of proj.git.  Anybody else should then be able to\r
+clone or pull from that URL, for example with a command line like:</simpara>\r
+<literallayout>$ git clone http://yourserver.com/~you/proj.git</literallayout>\r
+<simpara>(See also\r
+<ulink url="howto/setup-git-server-over-http.txt">setup-git-server-over-http</ulink>\r
+for a slightly more sophisticated setup using WebDAV which also\r
+allows pushing over http.)</simpara>\r
+</section>\r
+<section id="pushing-changes-to-a-public-repository">\r
+<title>Pushing changes to a public repository</title>\r
+<simpara>Note that the two techniques outlined above (exporting via\r
+<link linkend="exporting-via-http">http</link> or <link linkend="exporting-via-git">git</link>) allow other\r
+maintainers to fetch your latest changes, but they do not allow write\r
+access, which you will need to update the public repository with the\r
+latest changes created in your private repository.</simpara>\r
+<simpara>The simplest way to do this is using <ulink url="git-push.html">git-push(1)</ulink> and ssh; to\r
+update the remote branch named "master" with the latest state of your\r
+branch named "master", run</simpara>\r
+<literallayout>$ git push ssh://yourserver.com/~you/proj.git master:master</literallayout>\r
+<simpara>or just</simpara>\r
+<literallayout>$ git push ssh://yourserver.com/~you/proj.git master</literallayout>\r
+<simpara>As with git-fetch, git-push will complain if this does not result in a\r
+<link linkend="fast-forwards">fast forward</link>; see the following section for details on\r
+handling this case.</simpara>\r
+<simpara>Note that the target of a "push" is normally a\r
+<link linkend="def_bare_repository">bare</link> repository.  You can also push to a\r
+repository that has a checked-out working tree, but the working tree\r
+will not be updated by the push.  This may lead to unexpected results if\r
+the branch you push to is the currently checked-out branch!</simpara>\r
+<simpara>As with git-fetch, you may also set up configuration options to\r
+save typing; so, for example, after</simpara>\r
+<literallayout>$ cat &gt;&gt;.git/config &lt;&lt;EOF\r
+[remote "public-repo"]\r
+        url = ssh://yourserver.com/~you/proj.git\r
+EOF</literallayout>\r
+<simpara>you should be able to perform the above push with just</simpara>\r
+<literallayout>$ git push public-repo master</literallayout>\r
+<simpara>See the explanations of the remote.&lt;name&gt;.url, branch.&lt;name&gt;.remote,\r
+and remote.&lt;name&gt;.push options in <ulink url="git-config.html">git-config(1)</ulink> for\r
+details.</simpara>\r
+</section>\r
+<section id="forcing-push">\r
+<title>What to do when a push fails</title>\r
+<simpara>If a push would not result in a <link linkend="fast-forwards">fast forward</link> of the\r
+remote branch, then it will fail with an error like:</simpara>\r
+<literallayout>error: remote 'refs/heads/master' is not an ancestor of\r
+ local  'refs/heads/master'.\r
+ Maybe you are not up-to-date and need to pull first?\r
+error: failed to push to 'ssh://yourserver.com/~you/proj.git'</literallayout>\r
+<simpara>This can happen, for example, if you:</simpara>\r
+<itemizedlist>\r
+<listitem>\r
+<simpara>\r
+use <literal>git-reset --hard</literal> to remove already-published commits, or\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+use <literal>git-commit --amend</literal> to replace already-published commits\r
+          (as in <xref linkend="fixing-a-mistake-by-rewriting-history"/>), or\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+use <literal>git-rebase</literal> to rebase any already-published commits (as\r
+          in <xref linkend="using-git-rebase"/>).\r
+</simpara>\r
+</listitem>\r
+</itemizedlist>\r
+<simpara>You may force git-push to perform the update anyway by preceding the\r
+branch name with a plus sign:</simpara>\r
+<literallayout>$ git push ssh://yourserver.com/~you/proj.git +master</literallayout>\r
+<simpara>Normally whenever a branch head in a public repository is modified, it\r
+is modified to point to a descendant of the commit that it pointed to\r
+before.  By forcing a push in this situation, you break that convention.\r
+(See <xref linkend="problems-With-rewriting-history"/>.)</simpara>\r
+<simpara>Nevertheless, this is a common practice for people that need a simple\r
+way to publish a work-in-progress patch series, and it is an acceptable\r
+compromise as long as you warn other developers that this is how you\r
+intend to manage the branch.</simpara>\r
+<simpara>It&#8217;s also possible for a push to fail in this way when other people have\r
+the right to push to the same repository.  In that case, the correct\r
+solution is to retry the push after first updating your work: either by a\r
+pull, or by a fetch followed by a rebase; see the\r
+<link linkend="setting-up-a-shared-repository">next section</link> and\r
+<ulink url="gitcvs-migration.html">gitcvs-migration(7)</ulink> for more.</simpara>\r
+</section>\r
+<section id="setting-up-a-shared-repository">\r
+<title>Setting up a shared repository</title>\r
+<simpara>Another way to collaborate is by using a model similar to that\r
+commonly used in CVS, where several developers with special rights\r
+all push to and pull from a single shared repository.  See\r
+<ulink url="gitcvs-migration.html">gitcvs-migration(7)</ulink> for instructions on how to\r
+set this up.</simpara>\r
+<simpara>However, while there is nothing wrong with git&#8217;s support for shared\r
+repositories, this mode of operation is not generally recommended,\r
+simply because the mode of collaboration that git supports&#8212;by\r
+exchanging patches and pulling from public repositories&#8212;has so many\r
+advantages over the central shared repository:</simpara>\r
+<itemizedlist>\r
+<listitem>\r
+<simpara>\r
+Git&#8217;s ability to quickly import and merge patches allows a\r
+          single maintainer to process incoming changes even at very\r
+          high rates.  And when that becomes too much, git-pull provides\r
+          an easy way for that maintainer to delegate this job to other\r
+          maintainers while still allowing optional review of incoming\r
+          changes.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Since every developer&#8217;s repository has the same complete copy\r
+          of the project history, no repository is special, and it is\r
+          trivial for another developer to take over maintenance of a\r
+          project, either by mutual agreement, or because a maintainer\r
+          becomes unresponsive or difficult to work with.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+The lack of a central group of "committers" means there is\r
+          less need for formal decisions about who is "in" and who is\r
+          "out".\r
+</simpara>\r
+</listitem>\r
+</itemizedlist>\r
+</section>\r
+<section id="setting-up-gitweb">\r
+<title>Allowing web browsing of a repository</title>\r
+<simpara>The gitweb cgi script provides users an easy way to browse your\r
+project&#8217;s files and history without having to install git; see the file\r
+gitweb/INSTALL in the git source tree for instructions on setting it up.</simpara>\r
+</section>\r
+</section>\r
+<section id="sharing-development-examples">\r
+<title>Examples</title>\r
+<section id="maintaining-topic-branches">\r
+<title>Maintaining topic branches for a Linux subsystem maintainer</title>\r
+<simpara>This describes how Tony Luck uses git in his role as maintainer of the\r
+IA64 architecture for the Linux kernel.</simpara>\r
+<simpara>He uses two public branches:</simpara>\r
+<itemizedlist>\r
+<listitem>\r
+<simpara>\r
+A "test" tree into which patches are initially placed so that they\r
+   can get some exposure when integrated with other ongoing development.\r
+   This tree is available to Andrew for pulling into -mm whenever he\r
+   wants.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+A "release" tree into which tested patches are moved for final sanity\r
+   checking, and as a vehicle to send them upstream to Linus (by sending\r
+   him a "please pull" request.)\r
+</simpara>\r
+</listitem>\r
+</itemizedlist>\r
+<simpara>He also uses a set of temporary branches ("topic branches"), each\r
+containing a logical grouping of patches.</simpara>\r
+<simpara>To set this up, first create your work tree by cloning Linus&#8217;s public\r
+tree:</simpara>\r
+<literallayout>$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git work\r
+$ cd work</literallayout>\r
+<simpara>Linus&#8217;s tree will be stored in the remote branch named origin/master,\r
+and can be updated using <ulink url="git-fetch.html">git-fetch(1)</ulink>; you can track other\r
+public trees using <ulink url="git-remote.html">git-remote(1)</ulink> to set up a "remote" and\r
+<ulink url="git-fetch.html">git-fetch(1)</ulink> to keep them up-to-date; see\r
+<xref linkend="repositories-and-branches"/>.</simpara>\r
+<simpara>Now create the branches in which you are going to work; these start out\r
+at the current tip of origin/master branch, and should be set up (using\r
+the --track option to <ulink url="git-branch.html">git-branch(1)</ulink>) to merge changes in from\r
+Linus by default.</simpara>\r
+<literallayout>$ git branch --track test origin/master\r
+$ git branch --track release origin/master</literallayout>\r
+<simpara>These can be easily kept up to date using <ulink url="git-pull.html">git-pull(1)</ulink>.</simpara>\r
+<literallayout>$ git checkout test &amp;&amp; git pull\r
+$ git checkout release &amp;&amp; git pull</literallayout>\r
+<simpara>Important note!  If you have any local changes in these branches, then\r
+this merge will create a commit object in the history (with no local\r
+changes git will simply do a "Fast forward" merge).  Many people dislike\r
+the "noise" that this creates in the Linux history, so you should avoid\r
+doing this capriciously in the "release" branch, as these noisy commits\r
+will become part of the permanent history when you ask Linus to pull\r
+from the release branch.</simpara>\r
+<simpara>A few configuration variables (see <ulink url="git-config.html">git-config(1)</ulink>) can\r
+make it easy to push both branches to your public tree.  (See\r
+<xref linkend="setting-up-a-public-repository"/>.)</simpara>\r
+<literallayout>$ cat &gt;&gt; .git/config &lt;&lt;EOF\r
+[remote "mytree"]\r
+        url =  master.kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git\r
+        push = release\r
+        push = test\r
+EOF</literallayout>\r
+<simpara>Then you can push both the test and release trees using\r
+<ulink url="git-push.html">git-push(1)</ulink>:</simpara>\r
+<literallayout>$ git push mytree</literallayout>\r
+<simpara>or push just one of the test and release branches using:</simpara>\r
+<literallayout>$ git push mytree test</literallayout>\r
+<simpara>or</simpara>\r
+<literallayout>$ git push mytree release</literallayout>\r
+<simpara>Now to apply some patches from the community.  Think of a short\r
+snappy name for a branch to hold this patch (or related group of\r
+patches), and create a new branch from the current tip of Linus&#8217;s\r
+branch:</simpara>\r
+<literallayout>$ git checkout -b speed-up-spinlocks origin</literallayout>\r
+<simpara>Now you apply the patch(es), run some tests, and commit the change(s).  If\r
+the patch is a multi-part series, then you should apply each as a separate\r
+commit to this branch.</simpara>\r
+<literallayout>$ ... patch ... test  ... commit [ ... patch ... test ... commit ]*</literallayout>\r
+<simpara>When you are happy with the state of this change, you can pull it into the\r
+"test" branch in preparation to make it public:</simpara>\r
+<literallayout>$ git checkout test &amp;&amp; git pull . speed-up-spinlocks</literallayout>\r
+<simpara>It is unlikely that you would have any conflicts here &#8230; but you might if you\r
+spent a while on this step and had also pulled new versions from upstream.</simpara>\r
+<simpara>Some time later when enough time has passed and testing done, you can pull the\r
+same branch into the "release" tree ready to go upstream.  This is where you\r
+see the value of keeping each patch (or patch series) in its own branch.  It\r
+means that the patches can be moved into the "release" tree in any order.</simpara>\r
+<literallayout>$ git checkout release &amp;&amp; git pull . speed-up-spinlocks</literallayout>\r
+<simpara>After a while, you will have a number of branches, and despite the\r
+well chosen names you picked for each of them, you may forget what\r
+they are for, or what status they are in.  To get a reminder of what\r
+changes are in a specific branch, use:</simpara>\r
+<literallayout>$ git log linux..branchname | git shortlog</literallayout>\r
+<simpara>To see whether it has already been merged into the test or release branches,\r
+use:</simpara>\r
+<literallayout>$ git log test..branchname</literallayout>\r
+<simpara>or</simpara>\r
+<literallayout>$ git log release..branchname</literallayout>\r
+<simpara>(If this branch has not yet been merged, you will see some log entries.\r
+If it has been merged, then there will be no output.)</simpara>\r
+<simpara>Once a patch completes the great cycle (moving from test to release,\r
+then pulled by Linus, and finally coming back into your local\r
+"origin/master" branch), the branch for this change is no longer needed.\r
+You detect this when the output from:</simpara>\r
+<literallayout>$ git log origin..branchname</literallayout>\r
+<simpara>is empty.  At this point the branch can be deleted:</simpara>\r
+<literallayout>$ git branch -d branchname</literallayout>\r
+<simpara>Some changes are so trivial that it is not necessary to create a separate\r
+branch and then merge into each of the test and release branches.  For\r
+these changes, just apply directly to the "release" branch, and then\r
+merge that into the "test" branch.</simpara>\r
+<simpara>To create diffstat and shortlog summaries of changes to include in a "please\r
+pull" request to Linus you can use:</simpara>\r
+<literallayout>$ git diff --stat origin..release</literallayout>\r
+<simpara>and</simpara>\r
+<literallayout>$ git log -p origin..release | git shortlog</literallayout>\r
+<simpara>Here are some of the scripts that simplify all this even further.</simpara>\r
+<literallayout>==== update script ====\r
+# Update a branch in my GIT tree.  If the branch to be updated\r
+# is origin, then pull from kernel.org.  Otherwise merge\r
+# origin/master branch into test|release branch\r
+\r
+case "$1" in\r
+test|release)\r
+        git checkout $1 &amp;&amp; git pull . origin\r
+        ;;\r
+origin)\r
+        before=$(git rev-parse refs/remotes/origin/master)\r
+        git fetch origin\r
+        after=$(git rev-parse refs/remotes/origin/master)\r
+        if [ $before != $after ]\r
+        then\r
+                git log $before..$after | git shortlog\r
+        fi\r
+        ;;\r
+*)\r
+        echo "Usage: $0 origin|test|release" 1&gt;&amp;2\r
+        exit 1\r
+        ;;\r
+esac</literallayout>\r
+<literallayout>==== merge script ====\r
+# Merge a branch into either the test or release branch\r
+\r
+pname=$0\r
+\r
+usage()\r
+{\r
+        echo "Usage: $pname branch test|release" 1&gt;&amp;2\r
+        exit 1\r
+}\r
+\r
+git show-ref -q --verify -- refs/heads/"$1" || {\r
+        echo "Can't see branch &lt;$1&gt;" 1&gt;&amp;2\r
+        usage\r
+}\r
+\r
+case "$2" in\r
+test|release)\r
+        if [ $(git log $2..$1 | wc -c) -eq 0 ]\r
+        then\r
+                echo $1 already merged into $2 1&gt;&amp;2\r
+                exit 1\r
+        fi\r
+        git checkout $2 &amp;&amp; git pull . $1\r
+        ;;\r
+*)\r
+        usage\r
+        ;;\r
+esac</literallayout>\r
+<literallayout>==== status script ====\r
+# report on status of my ia64 GIT tree\r
+\r
+gb=$(tput setab 2)\r
+rb=$(tput setab 1)\r
+restore=$(tput setab 9)\r
+\r
+if [ `git rev-list test..release | wc -c` -gt 0 ]\r
+then\r
+        echo $rb Warning: commits in release that are not in test $restore\r
+        git log test..release\r
+fi\r
+\r
+for branch in `git show-ref --heads | sed 's|^.*/||'`\r
+do\r
+        if [ $branch = test -o $branch = release ]\r
+        then\r
+                continue\r
+        fi\r
+\r
+        echo -n $gb ======= $branch ====== $restore " "\r
+        status=\r
+        for ref in test release origin/master\r
+        do\r
+                if [ `git rev-list $ref..$branch | wc -c` -gt 0 ]\r
+                then\r
+                        status=$status${ref:0:1}\r
+                fi\r
+        done\r
+        case $status in\r
+        trl)\r
+                echo $rb Need to pull into test $restore\r
+                ;;\r
+        rl)\r
+                echo "In test"\r
+                ;;\r
+        l)\r
+                echo "Waiting for linus"\r
+                ;;\r
+        "")\r
+                echo $rb All done $restore\r
+                ;;\r
+        *)\r
+                echo $rb "&lt;$status&gt;" $restore\r
+                ;;\r
+        esac\r
+        git log origin/master..$branch | git shortlog\r
+done</literallayout>\r
+</section>\r
+</section>\r
+</section>\r
+<section id="cleaning-up-history">\r
+<title>Rewriting history and maintaining patch series</title>\r
+<simpara>Normally commits are only added to a project, never taken away or\r
+replaced.  Git is designed with this assumption, and violating it will\r
+cause git&#8217;s merge machinery (for example) to do the wrong thing.</simpara>\r
+<simpara>However, there is a situation in which it can be useful to violate this\r
+assumption.</simpara>\r
+<section id="patch-series">\r
+<title>Creating the perfect patch series</title>\r
+<simpara>Suppose you are a contributor to a large project, and you want to add a\r
+complicated feature, and to present it to the other developers in a way\r
+that makes it easy for them to read your changes, verify that they are\r
+correct, and understand why you made each change.</simpara>\r
+<simpara>If you present all of your changes as a single patch (or commit), they\r
+may find that it is too much to digest all at once.</simpara>\r
+<simpara>If you present them with the entire history of your work, complete with\r
+mistakes, corrections, and dead ends, they may be overwhelmed.</simpara>\r
+<simpara>So the ideal is usually to produce a series of patches such that:</simpara>\r
+<orderedlist numeration="arabic">\r
+<listitem>\r
+<simpara>\r
+Each patch can be applied in order.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Each patch includes a single logical change, together with a\r
+           message explaining the change.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+No patch introduces a regression: after applying any initial\r
+           part of the series, the resulting project still compiles and\r
+           works, and has no bugs that it didn&#8217;t have before.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+The complete series produces the same end result as your own\r
+           (probably much messier!) development process did.\r
+</simpara>\r
+</listitem>\r
+</orderedlist>\r
+<simpara>We will introduce some tools that can help you do this, explain how to\r
+use them, and then explain some of the problems that can arise because\r
+you are rewriting history.</simpara>\r
+</section>\r
+<section id="using-git-rebase">\r
+<title>Keeping a patch series up to date using git-rebase</title>\r
+<simpara>Suppose that you create a branch "mywork" on a remote-tracking branch\r
+"origin", and create some commits on top of it:</simpara>\r
+<literallayout>$ git checkout -b mywork origin\r
+$ vi file.txt\r
+$ git commit\r
+$ vi otherfile.txt\r
+$ git commit\r
+...</literallayout>\r
+<simpara>You have performed no merges into mywork, so it is just a simple linear\r
+sequence of patches on top of "origin":</simpara>\r
+<literallayout class="monospaced"> o--o--o &lt;-- origin\r
+        \\r
+         o--o--o &lt;-- mywork</literallayout>\r
+<simpara>Some more interesting work has been done in the upstream project, and\r
+"origin" has advanced:</simpara>\r
+<literallayout class="monospaced"> o--o--O--o--o--o &lt;-- origin\r
+        \\r
+         a--b--c &lt;-- mywork</literallayout>\r
+<simpara>At this point, you could use "pull" to merge your changes back in;\r
+the result would create a new merge commit, like this:</simpara>\r
+<literallayout class="monospaced"> o--o--O--o--o--o &lt;-- origin\r
+        \        \\r
+         a--b--c--m &lt;-- mywork</literallayout>\r
+<simpara>However, if you prefer to keep the history in mywork a simple series of\r
+commits without any merges, you may instead choose to use\r
+<ulink url="git-rebase.html">git-rebase(1)</ulink>:</simpara>\r
+<literallayout>$ git checkout mywork\r
+$ git rebase origin</literallayout>\r
+<simpara>This will remove each of your commits from mywork, temporarily saving\r
+them as patches (in a directory named ".git/rebase-apply"), update mywork to\r
+point at the latest version of origin, then apply each of the saved\r
+patches to the new mywork.  The result will look like:</simpara>\r
+<literallayout class="monospaced"> o--o--O--o--o--o &lt;-- origin\r
+                 \\r
+                  a'--b'--c' &lt;-- mywork</literallayout>\r
+<simpara>In the process, it may discover conflicts.  In that case it will stop\r
+and allow you to fix the conflicts; after fixing conflicts, use "git-add"\r
+to update the index with those contents, and then, instead of\r
+running git-commit, just run</simpara>\r
+<literallayout>$ git rebase --continue</literallayout>\r
+<simpara>and git will continue applying the rest of the patches.</simpara>\r
+<simpara>At any point you may use the <literal>--abort</literal> option to abort this process and\r
+return mywork to the state it had before you started the rebase:</simpara>\r
+<literallayout>$ git rebase --abort</literallayout>\r
+</section>\r
+<section id="rewriting-one-commit">\r
+<title>Rewriting a single commit</title>\r
+<simpara>We saw in <xref linkend="fixing-a-mistake-by-rewriting-history"/> that you can replace the\r
+most recent commit using</simpara>\r
+<literallayout>$ git commit --amend</literallayout>\r
+<simpara>which will replace the old commit by a new commit incorporating your\r
+changes, giving you a chance to edit the old commit message first.</simpara>\r
+<simpara>You can also use a combination of this and <ulink url="git-rebase.html">git-rebase(1)</ulink> to\r
+replace a commit further back in your history and recreate the\r
+intervening changes on top of it.  First, tag the problematic commit\r
+with</simpara>\r
+<literallayout>$ git tag bad mywork~5</literallayout>\r
+<simpara>(Either gitk or git-log may be useful for finding the commit.)</simpara>\r
+<simpara>Then check out that commit, edit it, and rebase the rest of the series\r
+on top of it (note that we could check out the commit on a temporary\r
+branch, but instead we&#8217;re using a <link linkend="detached-head">detached head</link>):</simpara>\r
+<literallayout>$ git checkout bad\r
+$ # make changes here and update the index\r
+$ git commit --amend\r
+$ git rebase --onto HEAD bad mywork</literallayout>\r
+<simpara>When you&#8217;re done, you&#8217;ll be left with mywork checked out, with the top\r
+patches on mywork reapplied on top of your modified commit.  You can\r
+then clean up with</simpara>\r
+<literallayout>$ git tag -d bad</literallayout>\r
+<simpara>Note that the immutable nature of git history means that you haven&#8217;t really\r
+"modified" existing commits; instead, you have replaced the old commits with\r
+new commits having new object names.</simpara>\r
+</section>\r
+<section id="reordering-patch-series">\r
+<title>Reordering or selecting from a patch series</title>\r
+<simpara>Given one existing commit, the <ulink url="git-cherry-pick.html">git-cherry-pick(1)</ulink> command\r
+allows you to apply the change introduced by that commit and create a\r
+new commit that records it.  So, for example, if "mywork" points to a\r
+series of patches on top of "origin", you might do something like:</simpara>\r
+<literallayout>$ git checkout -b mywork-new origin\r
+$ gitk origin..mywork &amp;</literallayout>\r
+<simpara>and browse through the list of patches in the mywork branch using gitk,\r
+applying them (possibly in a different order) to mywork-new using\r
+cherry-pick, and possibly modifying them as you go using <literal>commit --amend</literal>.\r
+The <ulink url="git-gui.html">git-gui(1)</ulink> command may also help as it allows you to\r
+individually select diff hunks for inclusion in the index (by\r
+right-clicking on the diff hunk and choosing "Stage Hunk for Commit").</simpara>\r
+<simpara>Another technique is to use git-format-patch to create a series of\r
+patches, then reset the state to before the patches:</simpara>\r
+<literallayout>$ git format-patch origin\r
+$ git reset --hard origin</literallayout>\r
+<simpara>Then modify, reorder, or eliminate patches as preferred before applying\r
+them again with <ulink url="git-am.html">git-am(1)</ulink>.</simpara>\r
+</section>\r
+<section id="patch-series-tools">\r
+<title>Other tools</title>\r
+<simpara>There are numerous other tools, such as StGIT, which exist for the\r
+purpose of maintaining a patch series.  These are outside of the scope of\r
+this manual.</simpara>\r
+</section>\r
+<section id="problems-With-rewriting-history">\r
+<title>Problems with rewriting history</title>\r
+<simpara>The primary problem with rewriting the history of a branch has to do\r
+with merging.  Suppose somebody fetches your branch and merges it into\r
+their branch, with a result something like this:</simpara>\r
+<literallayout class="monospaced"> o--o--O--o--o--o &lt;-- origin\r
+        \        \\r
+         t--t--t--m &lt;-- their branch:</literallayout>\r
+<simpara>Then suppose you modify the last three commits:</simpara>\r
+<literallayout class="monospaced">         o--o--o &lt;-- new head of origin\r
+        /\r
+ o--o--O--o--o--o &lt;-- old head of origin</literallayout>\r
+<simpara>If we examined all this history together in one repository, it will\r
+look like:</simpara>\r
+<literallayout class="monospaced">         o--o--o &lt;-- new head of origin\r
+        /\r
+ o--o--O--o--o--o &lt;-- old head of origin\r
+        \        \\r
+         t--t--t--m &lt;-- their branch:</literallayout>\r
+<simpara>Git has no way of knowing that the new head is an updated version of\r
+the old head; it treats this situation exactly the same as it would if\r
+two developers had independently done the work on the old and new heads\r
+in parallel.  At this point, if someone attempts to merge the new head\r
+in to their branch, git will attempt to merge together the two (old and\r
+new) lines of development, instead of trying to replace the old by the\r
+new.  The results are likely to be unexpected.</simpara>\r
+<simpara>You may still choose to publish branches whose history is rewritten,\r
+and it may be useful for others to be able to fetch those branches in\r
+order to examine or test them, but they should not attempt to pull such\r
+branches into their own work.</simpara>\r
+<simpara>For true distributed development that supports proper merging,\r
+published branches should never be rewritten.</simpara>\r
+</section>\r
+<section id="bisect-merges">\r
+<title>Why bisecting merge commits can be harder than bisecting linear history</title>\r
+<simpara>The <ulink url="git-bisect.html">git-bisect(1)</ulink> command correctly handles history that\r
+includes merge commits.  However, when the commit that it finds is a\r
+merge commit, the user may need to work harder than usual to figure out\r
+why that commit introduced a problem.</simpara>\r
+<simpara>Imagine this history:</simpara>\r
+<literallayout class="monospaced">      ---Z---o---X---...---o---A---C---D\r
+          \                       /\r
+           o---o---Y---...---o---B</literallayout>\r
+<simpara>Suppose that on the upper line of development, the meaning of one\r
+of the functions that exists at Z is changed at commit X.  The\r
+commits from Z leading to A change both the function&#8217;s\r
+implementation and all calling sites that exist at Z, as well\r
+as new calling sites they add, to be consistent.  There is no\r
+bug at A.</simpara>\r
+<simpara>Suppose that in the meantime on the lower line of development somebody\r
+adds a new calling site for that function at commit Y.  The\r
+commits from Z leading to B all assume the old semantics of that\r
+function and the callers and the callee are consistent with each\r
+other.  There is no bug at B, either.</simpara>\r
+<simpara>Suppose further that the two development lines merge cleanly at C,\r
+so no conflict resolution is required.</simpara>\r
+<simpara>Nevertheless, the code at C is broken, because the callers added\r
+on the lower line of development have not been converted to the new\r
+semantics introduced on the upper line of development.  So if all\r
+you know is that D is bad, that Z is good, and that\r
+<ulink url="git-bisect.html">git-bisect(1)</ulink> identifies C as the culprit, how will you\r
+figure out that the problem is due to this change in semantics?</simpara>\r
+<simpara>When the result of a git-bisect is a non-merge commit, you should\r
+normally be able to discover the problem by examining just that commit.\r
+Developers can make this easy by breaking their changes into small\r
+self-contained commits.  That won&#8217;t help in the case above, however,\r
+because the problem isn&#8217;t obvious from examination of any single\r
+commit; instead, a global view of the development is required.  To\r
+make matters worse, the change in semantics in the problematic\r
+function may be just one small part of the changes in the upper\r
+line of development.</simpara>\r
+<simpara>On the other hand, if instead of merging at C you had rebased the\r
+history between Z to B on top of A, you would have gotten this\r
+linear history:</simpara>\r
+<literallayout class="monospaced">    ---Z---o---X--...---o---A---o---o---Y*--...---o---B*--D*</literallayout>\r
+<simpara>Bisecting between Z and D* would hit a single culprit commit Y*,\r
+and understanding why Y* was broken would probably be easier.</simpara>\r
+<simpara>Partly for this reason, many experienced git users, even when\r
+working on an otherwise merge-heavy project, keep the history\r
+linear by rebasing against the latest upstream version before\r
+publishing.</simpara>\r
+</section>\r
+</section>\r
+<section id="advanced-branch-management">\r
+<title>Advanced branch management</title>\r
+<section id="fetching-individual-branches">\r
+<title>Fetching individual branches</title>\r
+<simpara>Instead of using <ulink url="git-remote.html">git-remote(1)</ulink>, you can also choose just\r
+to update one branch at a time, and to store it locally under an\r
+arbitrary name:</simpara>\r
+<literallayout>$ git fetch origin todo:my-todo-work</literallayout>\r
+<simpara>The first argument, "origin", just tells git to fetch from the\r
+repository you originally cloned from.  The second argument tells git\r
+to fetch the branch named "todo" from the remote repository, and to\r
+store it locally under the name refs/heads/my-todo-work.</simpara>\r
+<simpara>You can also fetch branches from other repositories; so</simpara>\r
+<literallayout>$ git fetch git://example.com/proj.git master:example-master</literallayout>\r
+<simpara>will create a new branch named "example-master" and store in it the\r
+branch named "master" from the repository at the given URL.  If you\r
+already have a branch named example-master, it will attempt to\r
+<link linkend="fast-forwards">fast-forward</link> to the commit given by example.com&#8217;s\r
+master branch.  In more detail:</simpara>\r
+</section>\r
+<section id="fetch-fast-forwards">\r
+<title>git fetch and fast-forwards</title>\r
+<simpara>In the previous example, when updating an existing branch, "git-fetch"\r
+checks to make sure that the most recent commit on the remote\r
+branch is a descendant of the most recent commit on your copy of the\r
+branch before updating your copy of the branch to point at the new\r
+commit.  Git calls this process a <link linkend="fast-forwards">fast forward</link>.</simpara>\r
+<simpara>A fast forward looks something like this:</simpara>\r
+<literallayout class="monospaced"> o--o--o--o &lt;-- old head of the branch\r
+           \\r
+            o--o--o &lt;-- new head of the branch</literallayout>\r
+<simpara>In some cases it is possible that the new head will <emphasis role="strong">not</emphasis> actually be\r
+a descendant of the old head.  For example, the developer may have\r
+realized she made a serious mistake, and decided to backtrack,\r
+resulting in a situation like:</simpara>\r
+<literallayout class="monospaced"> o--o--o--o--a--b &lt;-- old head of the branch\r
+           \\r
+            o--o--o &lt;-- new head of the branch</literallayout>\r
+<simpara>In this case, "git-fetch" will fail, and print out a warning.</simpara>\r
+<simpara>In that case, you can still force git to update to the new head, as\r
+described in the following section.  However, note that in the\r
+situation above this may mean losing the commits labeled "a" and "b",\r
+unless you&#8217;ve already created a reference of your own pointing to\r
+them.</simpara>\r
+</section>\r
+<section id="forcing-fetch">\r
+<title>Forcing git-fetch to do non-fast-forward updates</title>\r
+<simpara>If git fetch fails because the new head of a branch is not a\r
+descendant of the old head, you may force the update with:</simpara>\r
+<literallayout>$ git fetch git://example.com/proj.git +master:refs/remotes/example/master</literallayout>\r
+<simpara>Note the addition of the "+" sign.  Alternatively, you can use the "-f"\r
+flag to force updates of all the fetched branches, as in:</simpara>\r
+<literallayout>$ git fetch -f origin</literallayout>\r
+<simpara>Be aware that commits that the old version of example/master pointed at\r
+may be lost, as we saw in the previous section.</simpara>\r
+</section>\r
+<section id="remote-branch-configuration">\r
+<title>Configuring remote branches</title>\r
+<simpara>We saw above that "origin" is just a shortcut to refer to the\r
+repository that you originally cloned from.  This information is\r
+stored in git configuration variables, which you can see using\r
+<ulink url="git-config.html">git-config(1)</ulink>:</simpara>\r
+<literallayout>$ git config -l\r
+core.repositoryformatversion=0\r
+core.filemode=true\r
+core.logallrefupdates=true\r
+remote.origin.url=git://git.kernel.org/pub/scm/git/git.git\r
+remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*\r
+branch.master.remote=origin\r
+branch.master.merge=refs/heads/master</literallayout>\r
+<simpara>If there are other repositories that you also use frequently, you can\r
+create similar configuration options to save typing; for example,\r
+after</simpara>\r
+<literallayout>$ git config remote.example.url git://example.com/proj.git</literallayout>\r
+<simpara>then the following two commands will do the same thing:</simpara>\r
+<literallayout>$ git fetch git://example.com/proj.git master:refs/remotes/example/master\r
+$ git fetch example master:refs/remotes/example/master</literallayout>\r
+<simpara>Even better, if you add one more option:</simpara>\r
+<literallayout>$ git config remote.example.fetch master:refs/remotes/example/master</literallayout>\r
+<simpara>then the following commands will all do the same thing:</simpara>\r
+<literallayout>$ git fetch git://example.com/proj.git master:refs/remotes/example/master\r
+$ git fetch example master:refs/remotes/example/master\r
+$ git fetch example</literallayout>\r
+<simpara>You can also add a "+" to force the update each time:</simpara>\r
+<literallayout>$ git config remote.example.fetch +master:ref/remotes/example/master</literallayout>\r
+<simpara>Don&#8217;t do this unless you&#8217;re sure you won&#8217;t mind "git fetch" possibly\r
+throwing away commits on <emphasis>example/master</emphasis>.</simpara>\r
+<simpara>Also note that all of the above configuration can be performed by\r
+directly editing the file .git/config instead of using\r
+<ulink url="git-config.html">git-config(1)</ulink>.</simpara>\r
+<simpara>See <ulink url="git-config.html">git-config(1)</ulink> for more details on the configuration\r
+options mentioned above.</simpara>\r
+</section>\r
+</section>\r
+<section id="git-concepts">\r
+<title>Git concepts</title>\r
+<simpara>Git is built on a small number of simple but powerful ideas.  While it\r
+is possible to get things done without understanding them, you will find\r
+git much more intuitive if you do.</simpara>\r
+<simpara>We start with the most important, the  <link linkend="def_object_database">object database</link> and the <link linkend="def_index">index</link>.</simpara>\r
+<section id="the-object-database">\r
+<title>The Object Database</title>\r
+<simpara>We already saw in <xref linkend="understanding-commits"/> that all commits are stored\r
+under a 40-digit "object name".  In fact, all the information needed to\r
+represent the history of a project is stored in objects with such names.\r
+In each case the name is calculated by taking the SHA1 hash of the\r
+contents of the object.  The SHA1 hash is a cryptographic hash function.\r
+What that means to us is that it is impossible to find two different\r
+objects with the same name.  This has a number of advantages; among\r
+others:</simpara>\r
+<itemizedlist>\r
+<listitem>\r
+<simpara>\r
+Git can quickly determine whether two objects are identical or not,\r
+  just by comparing names.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Since object names are computed the same way in every repository, the\r
+  same content stored in two repositories will always be stored under\r
+  the same name.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Git can detect errors when it reads an object, by checking that the\r
+  object&#8217;s name is still the SHA1 hash of its contents.\r
+</simpara>\r
+</listitem>\r
+</itemizedlist>\r
+<simpara>(See <xref linkend="object-details"/> for the details of the object formatting and\r
+SHA1 calculation.)</simpara>\r
+<simpara>There are four different types of objects: "blob", "tree", "commit", and\r
+"tag".</simpara>\r
+<itemizedlist>\r
+<listitem>\r
+<simpara>\r
+A <link linkend="def_blob_object">"blob" object</link> is used to store file data.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+A <link linkend="def_tree_object">"tree" object</link> ties one or more\r
+  "blob" objects into a directory structure. In addition, a tree object\r
+  can refer to other tree objects, thus creating a directory hierarchy.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+A <link linkend="def_commit_object">"commit" object</link> ties such directory hierarchies\r
+  together into a <link linkend="def_DAG">directed acyclic graph</link> of revisions&#8212;each\r
+  commit contains the object name of exactly one tree designating the\r
+  directory hierarchy at the time of the commit. In addition, a commit\r
+  refers to "parent" commit objects that describe the history of how we\r
+  arrived at that directory hierarchy.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+A <link linkend="def_tag_object">"tag" object</link> symbolically identifies and can be\r
+  used to sign other objects. It contains the object name and type of\r
+  another object, a symbolic name (of course!) and, optionally, a\r
+  signature.\r
+</simpara>\r
+</listitem>\r
+</itemizedlist>\r
+<simpara>The object types in some more detail:</simpara>\r
+<section id="commit-object">\r
+<title>Commit Object</title>\r
+<simpara>The "commit" object links a physical state of a tree with a description\r
+of how we got there and why.  Use the --pretty=raw option to\r
+<ulink url="git-show.html">git-show(1)</ulink> or <ulink url="git-log.html">git-log(1)</ulink> to examine your favorite\r
+commit:</simpara>\r
+<literallayout>$ git show -s --pretty=raw 2be7fcb476\r
+commit 2be7fcb4764f2dbcee52635b91fedb1b3dcf7ab4\r
+tree fb3a8bdd0ceddd019615af4d57a53f43d8cee2bf\r
+parent 257a84d9d02e90447b149af58b271c19405edb6a\r
+author Dave Watson &lt;dwatson@mimvista.com&gt; 1187576872 -0400\r
+committer Junio C Hamano &lt;gitster@pobox.com&gt; 1187591163 -0700\r
+\r
+    Fix misspelling of 'suppress' in docs\r
+\r
+    Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;</literallayout>\r
+<simpara>As you can see, a commit is defined by:</simpara>\r
+<itemizedlist>\r
+<listitem>\r
+<simpara>\r
+a tree: The SHA1 name of a tree object (as defined below), representing\r
+  the contents of a directory at a certain point in time.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+parent(s): The SHA1 name of some number of commits which represent the\r
+  immediately previous step(s) in the history of the project.  The\r
+  example above has one parent; merge commits may have more than\r
+  one.  A commit with no parents is called a "root" commit, and\r
+  represents the initial revision of a project.  Each project must have\r
+  at least one root.  A project can also have multiple roots, though\r
+  that isn&#8217;t common (or necessarily a good idea).\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+an author: The name of the person responsible for this change, together\r
+  with its date.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+a committer: The name of the person who actually created the commit,\r
+  with the date it was done.  This may be different from the author, for\r
+  example, if the author was someone who wrote a patch and emailed it\r
+  to the person who used it to create the commit.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+a comment describing this commit.\r
+</simpara>\r
+</listitem>\r
+</itemizedlist>\r
+<simpara>Note that a commit does not itself contain any information about what\r
+actually changed; all changes are calculated by comparing the contents\r
+of the tree referred to by this commit with the trees associated with\r
+its parents.  In particular, git does not attempt to record file renames\r
+explicitly, though it can identify cases where the existence of the same\r
+file data at changing paths suggests a rename.  (See, for example, the\r
+-M option to <ulink url="git-diff.html">git-diff(1)</ulink>).</simpara>\r
+<simpara>A commit is usually created by <ulink url="git-commit.html">git-commit(1)</ulink>, which creates a\r
+commit whose parent is normally the current HEAD, and whose tree is\r
+taken from the content currently stored in the index.</simpara>\r
+</section>\r
+<section id="tree-object">\r
+<title>Tree Object</title>\r
+<simpara>The ever-versatile <ulink url="git-show.html">git-show(1)</ulink> command can also be used to\r
+examine tree objects, but <ulink url="git-ls-tree.html">git-ls-tree(1)</ulink> will give you more\r
+details:</simpara>\r
+<literallayout>$ git ls-tree fb3a8bdd0ce\r
+100644 blob 63c918c667fa005ff12ad89437f2fdc80926e21c    .gitignore\r
+100644 blob 5529b198e8d14decbe4ad99db3f7fb632de0439d    .mailmap\r
+100644 blob 6ff87c4664981e4397625791c8ea3bbb5f2279a3    COPYING\r
+040000 tree 2fb783e477100ce076f6bf57e4a6f026013dc745    Documentation\r
+100755 blob 3c0032cec592a765692234f1cba47dfdcc3a9200    GIT-VERSION-GEN\r
+100644 blob 289b046a443c0647624607d471289b2c7dcd470b    INSTALL\r
+100644 blob 4eb463797adc693dc168b926b6932ff53f17d0b1    Makefile\r
+100644 blob 548142c327a6790ff8821d67c2ee1eff7a656b52    README\r
+...</literallayout>\r
+<simpara>As you can see, a tree object contains a list of entries, each with a\r
+mode, object type, SHA1 name, and name, sorted by name.  It represents\r
+the contents of a single directory tree.</simpara>\r
+<simpara>The object type may be a blob, representing the contents of a file, or\r
+another tree, representing the contents of a subdirectory.  Since trees\r
+and blobs, like all other objects, are named by the SHA1 hash of their\r
+contents, two trees have the same SHA1 name if and only if their\r
+contents (including, recursively, the contents of all subdirectories)\r
+are identical.  This allows git to quickly determine the differences\r
+between two related tree objects, since it can ignore any entries with\r
+identical object names.</simpara>\r
+<simpara>(Note: in the presence of submodules, trees may also have commits as\r
+entries.  See <xref linkend="submodules"/> for documentation.)</simpara>\r
+<simpara>Note that the files all have mode 644 or 755: git actually only pays\r
+attention to the executable bit.</simpara>\r
+</section>\r
+<section id="blob-object">\r
+<title>Blob Object</title>\r
+<simpara>You can use <ulink url="git-show.html">git-show(1)</ulink> to examine the contents of a blob; take,\r
+for example, the blob in the entry for "COPYING" from the tree above:</simpara>\r
+<literallayout>$ git show 6ff87c4664\r
+\r
+ Note that the only valid version of the GPL as far as this project\r
+ is concerned is _this_ particular version of the license (ie v2, not\r
+ v2.2 or v3.x or whatever), unless explicitly otherwise stated.\r
+...</literallayout>\r
+<simpara>A "blob" object is nothing but a binary blob of data.  It doesn&#8217;t refer\r
+to anything else or have attributes of any kind.</simpara>\r
+<simpara>Since the blob is entirely defined by its data, if two files in a\r
+directory tree (or in multiple different versions of the repository)\r
+have the same contents, they will share the same blob object. The object\r
+is totally independent of its location in the directory tree, and\r
+renaming a file does not change the object that file is associated with.</simpara>\r
+<simpara>Note that any tree or blob object can be examined using\r
+<ulink url="git-show.html">git-show(1)</ulink> with the &lt;revision&gt;:&lt;path&gt; syntax.  This can\r
+sometimes be useful for browsing the contents of a tree that is not\r
+currently checked out.</simpara>\r
+</section>\r
+<section id="trust">\r
+<title>Trust</title>\r
+<simpara>If you receive the SHA1 name of a blob from one source, and its contents\r
+from another (possibly untrusted) source, you can still trust that those\r
+contents are correct as long as the SHA1 name agrees.  This is because\r
+the SHA1 is designed so that it is infeasible to find different contents\r
+that produce the same hash.</simpara>\r
+<simpara>Similarly, you need only trust the SHA1 name of a top-level tree object\r
+to trust the contents of the entire directory that it refers to, and if\r
+you receive the SHA1 name of a commit from a trusted source, then you\r
+can easily verify the entire history of commits reachable through\r
+parents of that commit, and all of those contents of the trees referred\r
+to by those commits.</simpara>\r
+<simpara>So to introduce some real trust in the system, the only thing you need\r
+to do is to digitally sign just <emphasis>one</emphasis> special note, which includes the\r
+name of a top-level commit.  Your digital signature shows others\r
+that you trust that commit, and the immutability of the history of\r
+commits tells others that they can trust the whole history.</simpara>\r
+<simpara>In other words, you can easily validate a whole archive by just\r
+sending out a single email that tells the people the name (SHA1 hash)\r
+of the top commit, and digitally sign that email using something\r
+like GPG/PGP.</simpara>\r
+<simpara>To assist in this, git also provides the tag object&#8230;</simpara>\r
+</section>\r
+<section id="tag-object">\r
+<title>Tag Object</title>\r
+<simpara>A tag object contains an object, object type, tag name, the name of the\r
+person ("tagger") who created the tag, and a message, which may contain\r
+a signature, as can be seen using <ulink url="git-cat-file.html">git-cat-file(1)</ulink>:</simpara>\r
+<literallayout>$ git cat-file tag v1.5.0\r
+object 437b1b20df4b356c9342dac8d38849f24ef44f27\r
+type commit\r
+tag v1.5.0\r
+tagger Junio C Hamano &lt;junkio@cox.net&gt; 1171411200 +0000\r
+\r
+GIT 1.5.0\r
+-----BEGIN PGP SIGNATURE-----\r
+Version: GnuPG v1.4.6 (GNU/Linux)\r
+\r
+iD8DBQBF0lGqwMbZpPMRm5oRAuRiAJ9ohBLd7s2kqjkKlq1qqC57SbnmzQCdG4ui\r
+nLE/L9aUXdWeTFPron96DLA=\r
+=2E+0\r
+-----END PGP SIGNATURE-----</literallayout>\r
+<simpara>See the <ulink url="git-tag.html">git-tag(1)</ulink> command to learn how to create and verify tag\r
+objects.  (Note that <ulink url="git-tag.html">git-tag(1)</ulink> can also be used to create\r
+"lightweight tags", which are not tag objects at all, but just simple\r
+references whose names begin with "refs/tags/").</simpara>\r
+</section>\r
+<section id="pack-files">\r
+<title>How git stores objects efficiently: pack files</title>\r
+<simpara>Newly created objects are initially created in a file named after the\r
+object&#8217;s SHA1 hash (stored in .git/objects).</simpara>\r
+<simpara>Unfortunately this system becomes inefficient once a project has a\r
+lot of objects.  Try this on an old project:</simpara>\r
+<literallayout>$ git count-objects\r
+6930 objects, 47620 kilobytes</literallayout>\r
+<simpara>The first number is the number of objects which are kept in\r
+individual files.  The second is the amount of space taken up by\r
+those "loose" objects.</simpara>\r
+<simpara>You can save space and make git faster by moving these loose objects in\r
+to a "pack file", which stores a group of objects in an efficient\r
+compressed format; the details of how pack files are formatted can be\r
+found in <ulink url="technical/pack-format.txt">technical/pack-format.txt</ulink>.</simpara>\r
+<simpara>To put the loose objects into a pack, just run git repack:</simpara>\r
+<literallayout>$ git repack\r
+Generating pack...\r
+Done counting 6020 objects.\r
+Deltifying 6020 objects.\r
+ 100% (6020/6020) done\r
+Writing 6020 objects.\r
+ 100% (6020/6020) done\r
+Total 6020, written 6020 (delta 4070), reused 0 (delta 0)\r
+Pack pack-3e54ad29d5b2e05838c75df582c65257b8d08e1c created.</literallayout>\r
+<simpara>You can then run</simpara>\r
+<literallayout>$ git prune</literallayout>\r
+<simpara>to remove any of the "loose" objects that are now contained in the\r
+pack.  This will also remove any unreferenced objects (which may be\r
+created when, for example, you use "git-reset" to remove a commit).\r
+You can verify that the loose objects are gone by looking at the\r
+.git/objects directory or by running</simpara>\r
+<literallayout>$ git count-objects\r
+0 objects, 0 kilobytes</literallayout>\r
+<simpara>Although the object files are gone, any commands that refer to those\r
+objects will work exactly as they did before.</simpara>\r
+<simpara>The <ulink url="git-gc.html">git-gc(1)</ulink> command performs packing, pruning, and more for\r
+you, so is normally the only high-level command you need.</simpara>\r
+</section>\r
+<section id="dangling-objects">\r
+<title>Dangling objects</title>\r
+<simpara>The <ulink url="git-fsck.html">git-fsck(1)</ulink> command will sometimes complain about dangling\r
+objects.  They are not a problem.</simpara>\r
+<simpara>The most common cause of dangling objects is that you&#8217;ve rebased a\r
+branch, or you have pulled from somebody else who rebased a branch&#8212;see\r
+<xref linkend="cleaning-up-history"/>.  In that case, the old head of the original\r
+branch still exists, as does everything it pointed to. The branch\r
+pointer itself just doesn&#8217;t, since you replaced it with another one.</simpara>\r
+<simpara>There are also other situations that cause dangling objects. For\r
+example, a "dangling blob" may arise because you did a "git-add" of a\r
+file, but then, before you actually committed it and made it part of the\r
+bigger picture, you changed something else in that file and committed\r
+that <emphasis role="strong">updated</emphasis> thing&#8212;the old state that you added originally ends up\r
+not being pointed to by any commit or tree, so it&#8217;s now a dangling blob\r
+object.</simpara>\r
+<simpara>Similarly, when the "recursive" merge strategy runs, and finds that\r
+there are criss-cross merges and thus more than one merge base (which is\r
+fairly unusual, but it does happen), it will generate one temporary\r
+midway tree (or possibly even more, if you had lots of criss-crossing\r
+merges and more than two merge bases) as a temporary internal merge\r
+base, and again, those are real objects, but the end result will not end\r
+up pointing to them, so they end up "dangling" in your repository.</simpara>\r
+<simpara>Generally, dangling objects aren&#8217;t anything to worry about. They can\r
+even be very useful: if you screw something up, the dangling objects can\r
+be how you recover your old tree (say, you did a rebase, and realized\r
+that you really didn&#8217;t want to&#8212;you can look at what dangling objects\r
+you have, and decide to reset your head to some old dangling state).</simpara>\r
+<simpara>For commits, you can just use:</simpara>\r
+<literallayout>$ gitk &lt;dangling-commit-sha-goes-here&gt; --not --all</literallayout>\r
+<simpara>This asks for all the history reachable from the given commit but not\r
+from any branch, tag, or other reference.  If you decide it&#8217;s something\r
+you want, you can always create a new reference to it, e.g.,</simpara>\r
+<literallayout>$ git branch recovered-branch &lt;dangling-commit-sha-goes-here&gt;</literallayout>\r
+<simpara>For blobs and trees, you can&#8217;t do the same, but you can still examine\r
+them.  You can just do</simpara>\r
+<literallayout>$ git show &lt;dangling-blob/tree-sha-goes-here&gt;</literallayout>\r
+<simpara>to show what the contents of the blob were (or, for a tree, basically\r
+what the "ls" for that directory was), and that may give you some idea\r
+of what the operation was that left that dangling object.</simpara>\r
+<simpara>Usually, dangling blobs and trees aren&#8217;t very interesting. They&#8217;re\r
+almost always the result of either being a half-way mergebase (the blob\r
+will often even have the conflict markers from a merge in it, if you\r
+have had conflicting merges that you fixed up by hand), or simply\r
+because you interrupted a "git-fetch" with ^C or something like that,\r
+leaving <emphasis>some</emphasis> of the new objects in the object database, but just\r
+dangling and useless.</simpara>\r
+<simpara>Anyway, once you are sure that you&#8217;re not interested in any dangling\r
+state, you can just prune all unreachable objects:</simpara>\r
+<literallayout>$ git prune</literallayout>\r
+<simpara>and they&#8217;ll be gone. But you should only run "git prune" on a quiescent\r
+repository&#8212;it&#8217;s kind of like doing a filesystem fsck recovery: you\r
+don&#8217;t want to do that while the filesystem is mounted.</simpara>\r
+<simpara>(The same is true of "git-fsck" itself, btw, but since\r
+git-fsck never actually <emphasis role="strong">changes</emphasis> the repository, it just reports\r
+on what it found, git-fsck itself is never "dangerous" to run.\r
+Running it while somebody is actually changing the repository can cause\r
+confusing and scary messages, but it won&#8217;t actually do anything bad. In\r
+contrast, running "git prune" while somebody is actively changing the\r
+repository is a <emphasis role="strong">BAD</emphasis> idea).</simpara>\r
+</section>\r
+<section id="recovering-from-repository-corruption">\r
+<title>Recovering from repository corruption</title>\r
+<simpara>By design, git treats data trusted to it with caution.  However, even in\r
+the absence of bugs in git itself, it is still possible that hardware or\r
+operating system errors could corrupt data.</simpara>\r
+<simpara>The first defense against such problems is backups.  You can back up a\r
+git directory using clone, or just using cp, tar, or any other backup\r
+mechanism.</simpara>\r
+<simpara>As a last resort, you can search for the corrupted objects and attempt\r
+to replace them by hand.  Back up your repository before attempting this\r
+in case you corrupt things even more in the process.</simpara>\r
+<simpara>We&#8217;ll assume that the problem is a single missing or corrupted blob,\r
+which is sometimes a solvable problem.  (Recovering missing trees and\r
+especially commits is <emphasis role="strong">much</emphasis> harder).</simpara>\r
+<simpara>Before starting, verify that there is corruption, and figure out where\r
+it is with <ulink url="git-fsck.html">git-fsck(1)</ulink>; this may be time-consuming.</simpara>\r
+<simpara>Assume the output looks like this:</simpara>\r
+<literallayout>$ git fsck --full\r
+broken link from    tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8\r
+              to    blob 4b9458b3786228369c63936db65827de3cc06200\r
+missing blob 4b9458b3786228369c63936db65827de3cc06200</literallayout>\r
+<simpara>(Typically there will be some "dangling object" messages too, but they\r
+aren&#8217;t interesting.)</simpara>\r
+<simpara>Now you know that blob 4b9458b3 is missing, and that the tree 2d9263c6\r
+points to it.  If you could find just one copy of that missing blob\r
+object, possibly in some other repository, you could move it into\r
+.git/objects/4b/9458b3&#8230; and be done.  Suppose you can&#8217;t.  You can\r
+still examine the tree that pointed to it with <ulink url="git-ls-tree.html">git-ls-tree(1)</ulink>,\r
+which might output something like:</simpara>\r
+<literallayout>$ git ls-tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8\r
+100644 blob 8d14531846b95bfa3564b58ccfb7913a034323b8    .gitignore\r
+100644 blob ebf9bf84da0aab5ed944264a5db2a65fe3a3e883    .mailmap\r
+100644 blob ca442d313d86dc67e0a2e5d584b465bd382cbf5c    COPYING\r
+...\r
+100644 blob 4b9458b3786228369c63936db65827de3cc06200    myfile\r
+...</literallayout>\r
+<simpara>So now you know that the missing blob was the data for a file named\r
+"myfile".  And chances are you can also identify the directory&#8212;let&#8217;s\r
+say it&#8217;s in "somedirectory".  If you&#8217;re lucky the missing copy might be\r
+the same as the copy you have checked out in your working tree at\r
+"somedirectory/myfile"; you can test whether that&#8217;s right with\r
+<ulink url="git-hash-object.html">git-hash-object(1)</ulink>:</simpara>\r
+<literallayout>$ git hash-object -w somedirectory/myfile</literallayout>\r
+<simpara>which will create and store a blob object with the contents of\r
+somedirectory/myfile, and output the sha1 of that object.  if you&#8217;re\r
+extremely lucky it might be 4b9458b3786228369c63936db65827de3cc06200, in\r
+which case you&#8217;ve guessed right, and the corruption is fixed!</simpara>\r
+<simpara>Otherwise, you need more information.  How do you tell which version of\r
+the file has been lost?</simpara>\r
+<simpara>The easiest way to do this is with:</simpara>\r
+<literallayout>$ git log --raw --all --full-history -- somedirectory/myfile</literallayout>\r
+<simpara>Because you&#8217;re asking for raw output, you&#8217;ll now get something like</simpara>\r
+<literallayout>commit abc\r
+Author:\r
+Date:\r
+...\r
+:100644 100644 4b9458b... newsha... M somedirectory/myfile\r
+\r
+\r
+commit xyz\r
+Author:\r
+Date:\r
+\r
+...\r
+:100644 100644 oldsha... 4b9458b... M somedirectory/myfile</literallayout>\r
+<simpara>This tells you that the immediately preceding version of the file was\r
+"newsha", and that the immediately following version was "oldsha".\r
+You also know the commit messages that went with the change from oldsha\r
+to 4b9458b and with the change from 4b9458b to newsha.</simpara>\r
+<simpara>If you&#8217;ve been committing small enough changes, you may now have a good\r
+shot at reconstructing the contents of the in-between state 4b9458b.</simpara>\r
+<simpara>If you can do that, you can now recreate the missing object with</simpara>\r
+<literallayout>$ git hash-object -w &lt;recreated-file&gt;</literallayout>\r
+<simpara>and your repository is good again!</simpara>\r
+<simpara>(Btw, you could have ignored the fsck, and started with doing a</simpara>\r
+<literallayout>$ git log --raw --all</literallayout>\r
+<simpara>and just looked for the sha of the missing object (4b9458b..) in that\r
+whole thing. It&#8217;s up to you - git does <emphasis role="strong">have</emphasis> a lot of information, it is\r
+just missing one particular blob version.</simpara>\r
+</section>\r
+</section>\r
+<section id="the-index">\r
+<title>The index</title>\r
+<simpara>The index is a binary file (generally kept in .git/index) containing a\r
+sorted list of path names, each with permissions and the SHA1 of a blob\r
+object; <ulink url="git-ls-files.html">git-ls-files(1)</ulink> can show you the contents of the index:</simpara>\r
+<literallayout>$ git ls-files --stage\r
+100644 63c918c667fa005ff12ad89437f2fdc80926e21c 0       .gitignore\r
+100644 5529b198e8d14decbe4ad99db3f7fb632de0439d 0       .mailmap\r
+100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0       COPYING\r
+100644 a37b2152bd26be2c2289e1f57a292534a51a93c7 0       Documentation/.gitignore\r
+100644 fbefe9a45b00a54b58d94d06eca48b03d40a50e0 0       Documentation/Makefile\r
+...\r
+100644 2511aef8d89ab52be5ec6a5e46236b4b6bcd07ea 0       xdiff/xtypes.h\r
+100644 2ade97b2574a9f77e7ae4002a4e07a6a38e46d07 0       xdiff/xutils.c\r
+100644 d5de8292e05e7c36c4b68857c1cf9855e3d2f70a 0       xdiff/xutils.h</literallayout>\r
+<simpara>Note that in older documentation you may see the index called the\r
+"current directory cache" or just the "cache".  It has three important\r
+properties:</simpara>\r
+<orderedlist numeration="arabic">\r
+<listitem>\r
+<simpara>\r
+The index contains all the information necessary to generate a single\r
+(uniquely determined) tree object.\r
+</simpara>\r
+<simpara>For example, running <ulink url="git-commit.html">git-commit(1)</ulink> generates this tree object\r
+from the index, stores it in the object database, and uses it as the\r
+tree object associated with the new commit.</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+The index enables fast comparisons between the tree object it defines\r
+and the working tree.\r
+</simpara>\r
+<simpara>It does this by storing some additional data for each entry (such as\r
+the last modified time).  This data is not displayed above, and is not\r
+stored in the created tree object, but it can be used to determine\r
+quickly which files in the working directory differ from what was\r
+stored in the index, and thus save git from having to read all of the\r
+data from such files to look for changes.</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+It can efficiently represent information about merge conflicts\r
+between different tree objects, allowing each pathname to be\r
+associated with sufficient information about the trees involved that\r
+you can create a three-way merge between them.\r
+</simpara>\r
+<simpara>We saw in <xref linkend="conflict-resolution"/> that during a merge the index can\r
+store multiple versions of a single file (called "stages").  The third\r
+column in the <ulink url="git-ls-files.html">git-ls-files(1)</ulink> output above is the stage\r
+number, and will take on values other than 0 for files with merge\r
+conflicts.</simpara>\r
+</listitem>\r
+</orderedlist>\r
+<simpara>The index is thus a sort of temporary staging area, which is filled with\r
+a tree which you are in the process of working on.</simpara>\r
+<simpara>If you blow the index away entirely, you generally haven&#8217;t lost any\r
+information as long as you have the name of the tree that it described.</simpara>\r
+</section>\r
+</section>\r
+<section id="submodules">\r
+<title>Submodules</title>\r
+<simpara>Large projects are often composed of smaller, self-contained modules.  For\r
+example, an embedded Linux distribution&#8217;s source tree would include every\r
+piece of software in the distribution with some local modifications; a movie\r
+player might need to build against a specific, known-working version of a\r
+decompression library; several independent programs might all share the same\r
+build scripts.</simpara>\r
+<simpara>With centralized revision control systems this is often accomplished by\r
+including every module in one single repository.  Developers can check out\r
+all modules or only the modules they need to work with.  They can even modify\r
+files across several modules in a single commit while moving things around\r
+or updating APIs and translations.</simpara>\r
+<simpara>Git does not allow partial checkouts, so duplicating this approach in Git\r
+would force developers to keep a local copy of modules they are not\r
+interested in touching.  Commits in an enormous checkout would be slower\r
+than you&#8217;d expect as Git would have to scan every directory for changes.\r
+If modules have a lot of local history, clones would take forever.</simpara>\r
+<simpara>On the plus side, distributed revision control systems can much better\r
+integrate with external sources.  In a centralized model, a single arbitrary\r
+snapshot of the external project is exported from its own revision control\r
+and then imported into the local revision control on a vendor branch.  All\r
+the history is hidden.  With distributed revision control you can clone the\r
+entire external history and much more easily follow development and re-merge\r
+local changes.</simpara>\r
+<simpara>Git&#8217;s submodule support allows a repository to contain, as a subdirectory, a\r
+checkout of an external project.  Submodules maintain their own identity;\r
+the submodule support just stores the submodule repository location and\r
+commit ID, so other developers who clone the containing project\r
+("superproject") can easily clone all the submodules at the same revision.\r
+Partial checkouts of the superproject are possible: you can tell Git to\r
+clone none, some or all of the submodules.</simpara>\r
+<simpara>The <ulink url="git-submodule.html">git-submodule(1)</ulink> command is available since Git 1.5.3.  Users\r
+with Git 1.5.2 can look up the submodule commits in the repository and\r
+manually check them out; earlier versions won&#8217;t recognize the submodules at\r
+all.</simpara>\r
+<simpara>To see how submodule support works, create (for example) four example\r
+repositories that can be used later as a submodule:</simpara>\r
+<literallayout>$ mkdir ~/git\r
+$ cd ~/git\r
+$ for i in a b c d\r
+do\r
+        mkdir $i\r
+        cd $i\r
+        git init\r
+        echo "module $i" &gt; $i.txt\r
+        git add $i.txt\r
+        git commit -m "Initial commit, submodule $i"\r
+        cd ..\r
+done</literallayout>\r
+<simpara>Now create the superproject and add all the submodules:</simpara>\r
+<literallayout>$ mkdir super\r
+$ cd super\r
+$ git init\r
+$ for i in a b c d\r
+do\r
+        git submodule add ~/git/$i $i\r
+done</literallayout>\r
+<note><simpara>Do not use local URLs here if you plan to publish your superproject!</simpara></note>\r
+<simpara>See what files <literal>git-submodule</literal> created:</simpara>\r
+<literallayout>$ ls -a\r
+.  ..  .git  .gitmodules  a  b  c  d</literallayout>\r
+<simpara>The <literal>git-submodule add &lt;repo&gt; &lt;path&gt;</literal> command does a couple of things:</simpara>\r
+<itemizedlist>\r
+<listitem>\r
+<simpara>\r
+It clones the submodule from &lt;repo&gt; to the given &lt;path&gt; under the\r
+  current directory and by default checks out the master branch.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+It adds the submodule&#8217;s clone path to the <ulink url="gitmodules.html">gitmodules(5)</ulink> file and\r
+  adds this file to the index, ready to be committed.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+It adds the submodule&#8217;s current commit ID to the index, ready to be\r
+  committed.\r
+</simpara>\r
+</listitem>\r
+</itemizedlist>\r
+<simpara>Commit the superproject:</simpara>\r
+<literallayout>$ git commit -m "Add submodules a, b, c and d."</literallayout>\r
+<simpara>Now clone the superproject:</simpara>\r
+<literallayout>$ cd ..\r
+$ git clone super cloned\r
+$ cd cloned</literallayout>\r
+<simpara>The submodule directories are there, but they&#8217;re empty:</simpara>\r
+<literallayout>$ ls -a a\r
+.  ..\r
+$ git submodule status\r
+-d266b9873ad50488163457f025db7cdd9683d88b a\r
+-e81d457da15309b4fef4249aba9b50187999670d b\r
+-c1536a972b9affea0f16e0680ba87332dc059146 c\r
+-d96249ff5d57de5de093e6baff9e0aafa5276a74 d</literallayout>\r
+<note><simpara>The commit object names shown above would be different for you, but they\r
+should match the HEAD commit object names of your repositories.  You can check\r
+it by running <literal>git ls-remote ../a</literal>.</simpara></note>\r
+<simpara>Pulling down the submodules is a two-step process. First run <literal>git submodule\r
+init</literal> to add the submodule repository URLs to <literal>.git/config</literal>:</simpara>\r
+<literallayout>$ git submodule init</literallayout>\r
+<simpara>Now use <literal>git-submodule update</literal> to clone the repositories and check out the\r
+commits specified in the superproject:</simpara>\r
+<literallayout>$ git submodule update\r
+$ cd a\r
+$ ls -a\r
+.  ..  .git  a.txt</literallayout>\r
+<simpara>One major difference between <literal>git-submodule update</literal> and <literal>git-submodule add</literal> is\r
+that <literal>git-submodule update</literal> checks out a specific commit, rather than the tip\r
+of a branch. It&#8217;s like checking out a tag: the head is detached, so you&#8217;re not\r
+working on a branch.</simpara>\r
+<literallayout>$ git branch\r
+* (no branch)\r
+  master</literallayout>\r
+<simpara>If you want to make a change within a submodule and you have a detached head,\r
+then you should create or checkout a branch, make your changes, publish the\r
+change within the submodule, and then update the superproject to reference the\r
+new commit:</simpara>\r
+<literallayout>$ git checkout master</literallayout>\r
+<simpara>or</simpara>\r
+<literallayout>$ git checkout -b fix-up</literallayout>\r
+<simpara>then</simpara>\r
+<literallayout>$ echo "adding a line again" &gt;&gt; a.txt\r
+$ git commit -a -m "Updated the submodule from within the superproject."\r
+$ git push\r
+$ cd ..\r
+$ git diff\r
+diff --git a/a b/a\r
+index d266b98..261dfac 160000\r
+--- a/a\r
++++ b/a\r
+@@ -1 +1 @@\r
+-Subproject commit d266b9873ad50488163457f025db7cdd9683d88b\r
++Subproject commit 261dfac35cb99d380eb966e102c1197139f7fa24\r
+$ git add a\r
+$ git commit -m "Updated submodule a."\r
+$ git push</literallayout>\r
+<simpara>You have to run <literal>git submodule update</literal> after <literal>git pull</literal> if you want to update\r
+submodules, too.</simpara>\r
+<section id="_pitfalls_with_submodules">\r
+<title>Pitfalls with submodules</title>\r
+<simpara>Always publish the submodule change before publishing the change to the\r
+superproject that references it. If you forget to publish the submodule change,\r
+others won&#8217;t be able to clone the repository:</simpara>\r
+<literallayout>$ cd ~/git/super/a\r
+$ echo i added another line to this file &gt;&gt; a.txt\r
+$ git commit -a -m "doing it wrong this time"\r
+$ cd ..\r
+$ git add a\r
+$ git commit -m "Updated submodule a again."\r
+$ git push\r
+$ cd ~/git/cloned\r
+$ git pull\r
+$ git submodule update\r
+error: pathspec '261dfac35cb99d380eb966e102c1197139f7fa24' did not match any file(s) known to git.\r
+Did you forget to 'git add'?\r
+Unable to checkout '261dfac35cb99d380eb966e102c1197139f7fa24' in submodule path 'a'</literallayout>\r
+<simpara>You also should not rewind branches in a submodule beyond commits that were\r
+ever recorded in any superproject.</simpara>\r
+<simpara>It&#8217;s not safe to run <literal>git submodule update</literal> if you&#8217;ve made and committed\r
+changes within a submodule without checking out a branch first. They will be\r
+silently overwritten:</simpara>\r
+<literallayout>$ cat a.txt\r
+module a\r
+$ echo line added from private2 &gt;&gt; a.txt\r
+$ git commit -a -m "line added inside private2"\r
+$ cd ..\r
+$ git submodule update\r
+Submodule path 'a': checked out 'd266b9873ad50488163457f025db7cdd9683d88b'\r
+$ cd a\r
+$ cat a.txt\r
+module a</literallayout>\r
+<note><simpara>The changes are still visible in the submodule&#8217;s reflog.</simpara></note>\r
+<simpara>This is not the case if you did not commit your changes.</simpara>\r
+</section>\r
+</section>\r
+<section id="low-level-operations">\r
+<title>Low-level git operations</title>\r
+<simpara>Many of the higher-level commands were originally implemented as shell\r
+scripts using a smaller core of low-level git commands.  These can still\r
+be useful when doing unusual things with git, or just as a way to\r
+understand its inner workings.</simpara>\r
+<section id="object-manipulation">\r
+<title>Object access and manipulation</title>\r
+<simpara>The <ulink url="git-cat-file.html">git-cat-file(1)</ulink> command can show the contents of any object,\r
+though the higher-level <ulink url="git-show.html">git-show(1)</ulink> is usually more useful.</simpara>\r
+<simpara>The <ulink url="git-commit-tree.html">git-commit-tree(1)</ulink> command allows constructing commits with\r
+arbitrary parents and trees.</simpara>\r
+<simpara>A tree can be created with <ulink url="git-write-tree.html">git-write-tree(1)</ulink> and its data can be\r
+accessed by <ulink url="git-ls-tree.html">git-ls-tree(1)</ulink>.  Two trees can be compared with\r
+<ulink url="git-diff-tree.html">git-diff-tree(1)</ulink>.</simpara>\r
+<simpara>A tag is created with <ulink url="git-mktag.html">git-mktag(1)</ulink>, and the signature can be\r
+verified by <ulink url="git-verify-tag.html">git-verify-tag(1)</ulink>, though it is normally simpler to\r
+use <ulink url="git-tag.html">git-tag(1)</ulink> for both.</simpara>\r
+</section>\r
+<section id="the-workflow">\r
+<title>The Workflow</title>\r
+<simpara>High-level operations such as <ulink url="git-commit.html">git-commit(1)</ulink>,\r
+<ulink url="git-checkout.html">git-checkout(1)</ulink> and <ulink url="git-reset.html">git-reset(1)</ulink> work by moving data\r
+between the working tree, the index, and the object database.  Git\r
+provides low-level operations which perform each of these steps\r
+individually.</simpara>\r
+<simpara>Generally, all "git" operations work on the index file. Some operations\r
+work <emphasis role="strong">purely</emphasis> on the index file (showing the current state of the\r
+index), but most operations move data between the index file and either\r
+the database or the working directory. Thus there are four main\r
+combinations:</simpara>\r
+<section id="working-directory-to-index">\r
+<title>working directory &#8594; index</title>\r
+<simpara>The <ulink url="git-update-index.html">git-update-index(1)</ulink> command updates the index with\r
+information from the working directory.  You generally update the\r
+index information by just specifying the filename you want to update,\r
+like so:</simpara>\r
+<literallayout>$ git update-index filename</literallayout>\r
+<simpara>but to avoid common mistakes with filename globbing etc, the command\r
+will not normally add totally new entries or remove old entries,\r
+i.e. it will normally just update existing cache entries.</simpara>\r
+<simpara>To tell git that yes, you really do realize that certain files no\r
+longer exist, or that new files should be added, you\r
+should use the <literal>--remove</literal> and <literal>--add</literal> flags respectively.</simpara>\r
+<simpara>NOTE! A <literal>--remove</literal> flag does <emphasis>not</emphasis> mean that subsequent filenames will\r
+necessarily be removed: if the files still exist in your directory\r
+structure, the index will be updated with their new status, not\r
+removed. The only thing <literal>--remove</literal> means is that update-index will be\r
+considering a removed file to be a valid thing, and if the file really\r
+does not exist any more, it will update the index accordingly.</simpara>\r
+<simpara>As a special case, you can also do <literal>git update-index --refresh</literal>, which\r
+will refresh the "stat" information of each index to match the current\r
+stat information. It will <emphasis>not</emphasis> update the object status itself, and\r
+it will only update the fields that are used to quickly test whether\r
+an object still matches its old backing store object.</simpara>\r
+<simpara>The previously introduced <ulink url="git-add.html">git-add(1)</ulink> is just a wrapper for\r
+<ulink url="git-update-index.html">git-update-index(1)</ulink>.</simpara>\r
+</section>\r
+<section id="index-to-object-database">\r
+<title>index &#8594; object database</title>\r
+<simpara>You write your current index file to a "tree" object with the program</simpara>\r
+<literallayout>$ git write-tree</literallayout>\r
+<simpara>that doesn&#8217;t come with any options&#8212;it will just write out the\r
+current index into the set of tree objects that describe that state,\r
+and it will return the name of the resulting top-level tree. You can\r
+use that tree to re-generate the index at any time by going in the\r
+other direction:</simpara>\r
+</section>\r
+<section id="object-database-to-index">\r
+<title>object database &#8594; index</title>\r
+<simpara>You read a "tree" file from the object database, and use that to\r
+populate (and overwrite&#8212;don&#8217;t do this if your index contains any\r
+unsaved state that you might want to restore later!) your current\r
+index.  Normal operation is just</simpara>\r
+<literallayout>$ git read-tree &lt;sha1 of tree&gt;</literallayout>\r
+<simpara>and your index file will now be equivalent to the tree that you saved\r
+earlier. However, that is only your <emphasis>index</emphasis> file: your working\r
+directory contents have not been modified.</simpara>\r
+</section>\r
+<section id="index-to-working-directory">\r
+<title>index &#8594; working directory</title>\r
+<simpara>You update your working directory from the index by "checking out"\r
+files. This is not a very common operation, since normally you&#8217;d just\r
+keep your files updated, and rather than write to your working\r
+directory, you&#8217;d tell the index files about the changes in your\r
+working directory (i.e. <literal>git-update-index</literal>).</simpara>\r
+<simpara>However, if you decide to jump to a new version, or check out somebody\r
+else&#8217;s version, or just restore a previous tree, you&#8217;d populate your\r
+index file with read-tree, and then you need to check out the result\r
+with</simpara>\r
+<literallayout>$ git checkout-index filename</literallayout>\r
+<simpara>or, if you want to check out all of the index, use <literal>-a</literal>.</simpara>\r
+<simpara>NOTE! git-checkout-index normally refuses to overwrite old files, so\r
+if you have an old version of the tree already checked out, you will\r
+need to use the "-f" flag (<emphasis>before</emphasis> the "-a" flag or the filename) to\r
+<emphasis>force</emphasis> the checkout.</simpara>\r
+<simpara>Finally, there are a few odds and ends which are not purely moving\r
+from one representation to the other:</simpara>\r
+</section>\r
+<section id="tying-it-all-together">\r
+<title>Tying it all together</title>\r
+<simpara>To commit a tree you have instantiated with "git write-tree", you&#8217;d\r
+create a "commit" object that refers to that tree and the history\r
+behind it&#8212;most notably the "parent" commits that preceded it in\r
+history.</simpara>\r
+<simpara>Normally a "commit" has one parent: the previous state of the tree\r
+before a certain change was made. However, sometimes it can have two\r
+or more parent commits, in which case we call it a "merge", due to the\r
+fact that such a commit brings together ("merges") two or more\r
+previous states represented by other commits.</simpara>\r
+<simpara>In other words, while a "tree" represents a particular directory state\r
+of a working directory, a "commit" represents that state in "time",\r
+and explains how we got there.</simpara>\r
+<simpara>You create a commit object by giving it the tree that describes the\r
+state at the time of the commit, and a list of parents:</simpara>\r
+<literallayout>$ git commit-tree &lt;tree&gt; -p &lt;parent&gt; [-p &lt;parent2&gt; ..]</literallayout>\r
+<simpara>and then giving the reason for the commit on stdin (either through\r
+redirection from a pipe or file, or by just typing it at the tty).</simpara>\r
+<simpara>git-commit-tree will return the name of the object that represents\r
+that commit, and you should save it away for later use. Normally,\r
+you&#8217;d commit a new <literal>HEAD</literal> state, and while git doesn&#8217;t care where you\r
+save the note about that state, in practice we tend to just write the\r
+result to the file pointed at by <literal>.git/HEAD</literal>, so that we can always see\r
+what the last committed state was.</simpara>\r
+<simpara>Here is an ASCII art by Jon Loeliger that illustrates how\r
+various pieces fit together.</simpara>\r
+<literallayout>                     commit-tree\r
+                      commit obj\r
+                       +----+\r
+                       |    |\r
+                       |    |\r
+                       V    V\r
+                    +-----------+\r
+                    | Object DB |\r
+                    |  Backing  |\r
+                    |   Store   |\r
+                    +-----------+\r
+                       ^\r
+           write-tree  |     |\r
+             tree obj  |     |\r
+                       |     |  read-tree\r
+                       |     |  tree obj\r
+                             V\r
+                    +-----------+\r
+                    |   Index   |\r
+                    |  "cache"  |\r
+                    +-----------+\r
+         update-index  ^\r
+             blob obj  |     |\r
+                       |     |\r
+    checkout-index -u  |     |  checkout-index\r
+             stat      |     |  blob obj\r
+                             V\r
+                    +-----------+\r
+                    |  Working  |\r
+                    | Directory |\r
+                    +-----------+</literallayout>\r
+</section>\r
+</section>\r
+<section id="examining-the-data">\r
+<title>Examining the data</title>\r
+<simpara>You can examine the data represented in the object database and the\r
+index with various helper tools. For every object, you can use\r
+<ulink url="git-cat-file.html">git-cat-file(1)</ulink> to examine details about the\r
+object:</simpara>\r
+<literallayout>$ git cat-file -t &lt;objectname&gt;</literallayout>\r
+<simpara>shows the type of the object, and once you have the type (which is\r
+usually implicit in where you find the object), you can use</simpara>\r
+<literallayout>$ git cat-file blob|tree|commit|tag &lt;objectname&gt;</literallayout>\r
+<simpara>to show its contents. NOTE! Trees have binary content, and as a result\r
+there is a special helper for showing that content, called\r
+<literal>git-ls-tree</literal>, which turns the binary content into a more easily\r
+readable form.</simpara>\r
+<simpara>It&#8217;s especially instructive to look at "commit" objects, since those\r
+tend to be small and fairly self-explanatory. In particular, if you\r
+follow the convention of having the top commit name in <literal>.git/HEAD</literal>,\r
+you can do</simpara>\r
+<literallayout>$ git cat-file commit HEAD</literallayout>\r
+<simpara>to see what the top commit was.</simpara>\r
+</section>\r
+<section id="merging-multiple-trees">\r
+<title>Merging multiple trees</title>\r
+<simpara>Git helps you do a three-way merge, which you can expand to n-way by\r
+repeating the merge procedure arbitrary times until you finally\r
+"commit" the state.  The normal situation is that you&#8217;d only do one\r
+three-way merge (two parents), and commit it, but if you like to, you\r
+can do multiple parents in one go.</simpara>\r
+<simpara>To do a three-way merge, you need the two sets of "commit" objects\r
+that you want to merge, use those to find the closest common parent (a\r
+third "commit" object), and then use those commit objects to find the\r
+state of the directory ("tree" object) at these points.</simpara>\r
+<simpara>To get the "base" for the merge, you first look up the common parent\r
+of two commits with</simpara>\r
+<literallayout>$ git merge-base &lt;commit1&gt; &lt;commit2&gt;</literallayout>\r
+<simpara>which will return you the commit they are both based on.  You should\r
+now look up the "tree" objects of those commits, which you can easily\r
+do with (for example)</simpara>\r
+<literallayout>$ git cat-file commit &lt;commitname&gt; | head -1</literallayout>\r
+<simpara>since the tree object information is always the first line in a commit\r
+object.</simpara>\r
+<simpara>Once you know the three trees you are going to merge (the one "original"\r
+tree, aka the common tree, and the two "result" trees, aka the branches\r
+you want to merge), you do a "merge" read into the index. This will\r
+complain if it has to throw away your old index contents, so you should\r
+make sure that you&#8217;ve committed those&#8212;in fact you would normally\r
+always do a merge against your last commit (which should thus match what\r
+you have in your current index anyway).</simpara>\r
+<simpara>To do the merge, do</simpara>\r
+<literallayout>$ git read-tree -m -u &lt;origtree&gt; &lt;yourtree&gt; &lt;targettree&gt;</literallayout>\r
+<simpara>which will do all trivial merge operations for you directly in the\r
+index file, and you can just write the result out with\r
+<literal>git write-tree</literal>.</simpara>\r
+</section>\r
+<section id="merging-multiple-trees-2">\r
+<title>Merging multiple trees, continued</title>\r
+<simpara>Sadly, many merges aren&#8217;t trivial. If there are files that have\r
+been added, moved or removed, or if both branches have modified the\r
+same file, you will be left with an index tree that contains "merge\r
+entries" in it. Such an index tree can <emphasis>NOT</emphasis> be written out to a tree\r
+object, and you will have to resolve any such merge clashes using\r
+other tools before you can write out the result.</simpara>\r
+<simpara>You can examine such index state with <literal>git ls-files --unmerged</literal>\r
+command.  An example:</simpara>\r
+<literallayout>$ git read-tree -m $orig HEAD $target\r
+$ git ls-files --unmerged\r
+100644 263414f423d0e4d70dae8fe53fa34614ff3e2860 1       hello.c\r
+100644 06fa6a24256dc7e560efa5687fa84b51f0263c3a 2       hello.c\r
+100644 cc44c73eb783565da5831b4d820c962954019b69 3       hello.c</literallayout>\r
+<simpara>Each line of the <literal>git ls-files --unmerged</literal> output begins with\r
+the blob mode bits, blob SHA1, <emphasis>stage number</emphasis>, and the\r
+filename.  The <emphasis>stage number</emphasis> is git&#8217;s way to say which tree it\r
+came from: stage 1 corresponds to <literal>$orig</literal> tree, stage 2 <literal>HEAD</literal>\r
+tree, and stage3 <literal>$target</literal> tree.</simpara>\r
+<simpara>Earlier we said that trivial merges are done inside\r
+<literal>git-read-tree -m</literal>.  For example, if the file did not change\r
+from <literal>$orig</literal> to <literal>HEAD</literal> nor <literal>$target</literal>, or if the file changed\r
+from <literal>$orig</literal> to <literal>HEAD</literal> and <literal>$orig</literal> to <literal>$target</literal> the same way,\r
+obviously the final outcome is what is in <literal>HEAD</literal>.  What the\r
+above example shows is that file <literal>hello.c</literal> was changed from\r
+<literal>$orig</literal> to <literal>HEAD</literal> and <literal>$orig</literal> to <literal>$target</literal> in a different way.\r
+You could resolve this by running your favorite 3-way merge\r
+program, e.g.  <literal>diff3</literal>, <literal>merge</literal>, or git&#8217;s own merge-file, on\r
+the blob objects from these three stages yourself, like this:</simpara>\r
+<literallayout>$ git cat-file blob 263414f... &gt;hello.c~1\r
+$ git cat-file blob 06fa6a2... &gt;hello.c~2\r
+$ git cat-file blob cc44c73... &gt;hello.c~3\r
+$ git merge-file hello.c~2 hello.c~1 hello.c~3</literallayout>\r
+<simpara>This would leave the merge result in <literal>hello.c~2</literal> file, along\r
+with conflict markers if there are conflicts.  After verifying\r
+the merge result makes sense, you can tell git what the final\r
+merge result for this file is by:</simpara>\r
+<literallayout>$ mv -f hello.c~2 hello.c\r
+$ git update-index hello.c</literallayout>\r
+<simpara>When a path is in the "unmerged" state, running <literal>git-update-index</literal> for\r
+that path tells git to mark the path resolved.</simpara>\r
+<simpara>The above is the description of a git merge at the lowest level,\r
+to help you understand what conceptually happens under the hood.\r
+In practice, nobody, not even git itself, runs <literal>git-cat-file</literal> three times\r
+for this.  There is a <literal>git-merge-index</literal> program that extracts the\r
+stages to temporary files and calls a "merge" script on it:</simpara>\r
+<literallayout>$ git merge-index git-merge-one-file hello.c</literallayout>\r
+<simpara>and that is what higher level <literal>git-merge -s resolve</literal> is implemented with.</simpara>\r
+</section>\r
+</section>\r
+<section id="hacking-git">\r
+<title>Hacking git</title>\r
+<simpara>This chapter covers internal details of the git implementation which\r
+probably only git developers need to understand.</simpara>\r
+<section id="object-details">\r
+<title>Object storage format</title>\r
+<simpara>All objects have a statically determined "type" which identifies the\r
+format of the object (i.e. how it is used, and how it can refer to other\r
+objects).  There are currently four different object types: "blob",\r
+"tree", "commit", and "tag".</simpara>\r
+<simpara>Regardless of object type, all objects share the following\r
+characteristics: they are all deflated with zlib, and have a header\r
+that not only specifies their type, but also provides size information\r
+about the data in the object.  It&#8217;s worth noting that the SHA1 hash\r
+that is used to name the object is the hash of the original data\r
+plus this header, so <literal>sha1sum</literal> <emphasis>file</emphasis> does not match the object name\r
+for <emphasis>file</emphasis>.\r
+(Historical note: in the dawn of the age of git the hash\r
+was the sha1 of the <emphasis>compressed</emphasis> object.)</simpara>\r
+<simpara>As a result, the general consistency of an object can always be tested\r
+independently of the contents or the type of the object: all objects can\r
+be validated by verifying that (a) their hashes match the content of the\r
+file and (b) the object successfully inflates to a stream of bytes that\r
+forms a sequence of &lt;ascii type without space&gt; &#43; &lt;space&gt; &#43; &lt;ascii decimal\r
+size&gt; &#43; &lt;byte\0&gt; &#43; &lt;binary object data&gt;.</simpara>\r
+<simpara>The structured objects can further have their structure and\r
+connectivity to other objects verified. This is generally done with\r
+the <literal>git-fsck</literal> program, which generates a full dependency graph\r
+of all objects, and verifies their internal consistency (in addition\r
+to just verifying their superficial consistency through the hash).</simpara>\r
+</section>\r
+<section id="birdview-on-the-source-code">\r
+<title>A birds-eye view of Git&#8217;s source code</title>\r
+<simpara>It is not always easy for new developers to find their way through Git&#8217;s\r
+source code.  This section gives you a little guidance to show where to\r
+start.</simpara>\r
+<simpara>A good place to start is with the contents of the initial commit, with:</simpara>\r
+<literallayout>$ git checkout e83c5163</literallayout>\r
+<simpara>The initial revision lays the foundation for almost everything git has\r
+today, but is small enough to read in one sitting.</simpara>\r
+<simpara>Note that terminology has changed since that revision.  For example, the\r
+README in that revision uses the word "changeset" to describe what we\r
+now call a <link linkend="def_commit_object">commit</link>.</simpara>\r
+<simpara>Also, we do not call it "cache" any more, but rather "index"; however, the\r
+file is still called <literal>cache.h</literal>.  Remark: Not much reason to change it now,\r
+especially since there is no good single name for it anyway, because it is\r
+basically <emphasis>the</emphasis> header file which is included by <emphasis>all</emphasis> of Git&#8217;s C sources.</simpara>\r
+<simpara>If you grasp the ideas in that initial commit, you should check out a\r
+more recent version and skim <literal>cache.h</literal>, <literal>object.h</literal> and <literal>commit.h</literal>.</simpara>\r
+<simpara>In the early days, Git (in the tradition of UNIX) was a bunch of programs\r
+which were extremely simple, and which you used in scripts, piping the\r
+output of one into another. This turned out to be good for initial\r
+development, since it was easier to test new things.  However, recently\r
+many of these parts have become builtins, and some of the core has been\r
+"libified", i.e. put into libgit.a for performance, portability reasons,\r
+and to avoid code duplication.</simpara>\r
+<simpara>By now, you know what the index is (and find the corresponding data\r
+structures in <literal>cache.h</literal>), and that there are just a couple of object types\r
+(blobs, trees, commits and tags) which inherit their common structure from\r
+<literal>struct object</literal>, which is their first member (and thus, you can cast e.g.\r
+<literal>(struct object *)commit</literal> to achieve the <emphasis>same</emphasis> as <literal>&amp;commit&#8594;object</literal>, i.e.\r
+get at the object name and flags).</simpara>\r
+<simpara>Now is a good point to take a break to let this information sink in.</simpara>\r
+<simpara>Next step: get familiar with the object naming.  Read <xref linkend="naming-commits"/>.\r
+There are quite a few ways to name an object (and not only revisions!).\r
+All of these are handled in <literal>sha1_name.c</literal>. Just have a quick look at\r
+the function <literal>get_sha1()</literal>. A lot of the special handling is done by\r
+functions like <literal>get_sha1_basic()</literal> or the likes.</simpara>\r
+<simpara>This is just to get you into the groove for the most libified part of Git:\r
+the revision walker.</simpara>\r
+<simpara>Basically, the initial version of <literal>git-log</literal> was a shell script:</simpara>\r
+<literallayout>$ git-rev-list --pretty $(git-rev-parse --default HEAD "$@") | \\r
+        LESS=-S ${PAGER:-less}</literallayout>\r
+<simpara>What does this mean?</simpara>\r
+<simpara><literal>git-rev-list</literal> is the original version of the revision walker, which\r
+<emphasis>always</emphasis> printed a list of revisions to stdout.  It is still functional,\r
+and needs to, since most new Git programs start out as scripts using\r
+<literal>git-rev-list</literal>.</simpara>\r
+<simpara><literal>git-rev-parse</literal> is not as important any more; it was only used to filter out\r
+options that were relevant for the different plumbing commands that were\r
+called by the script.</simpara>\r
+<simpara>Most of what <literal>git-rev-list</literal> did is contained in <literal>revision.c</literal> and\r
+<literal>revision.h</literal>.  It wraps the options in a struct named <literal>rev_info</literal>, which\r
+controls how and what revisions are walked, and more.</simpara>\r
+<simpara>The original job of <literal>git-rev-parse</literal> is now taken by the function\r
+<literal>setup_revisions()</literal>, which parses the revisions and the common command line\r
+options for the revision walker. This information is stored in the struct\r
+<literal>rev_info</literal> for later consumption. You can do your own command line option\r
+parsing after calling <literal>setup_revisions()</literal>. After that, you have to call\r
+<literal>prepare_revision_walk()</literal> for initialization, and then you can get the\r
+commits one by one with the function <literal>get_revision()</literal>.</simpara>\r
+<simpara>If you are interested in more details of the revision walking process,\r
+just have a look at the first implementation of <literal>cmd_log()</literal>; call\r
+<literal>git show v1.3.0&#126;155^2&#126;4</literal> and scroll down to that function (note that you\r
+no longer need to call <literal>setup_pager()</literal> directly).</simpara>\r
+<simpara>Nowadays, <literal>git-log</literal> is a builtin, which means that it is <emphasis>contained</emphasis> in the\r
+command <literal>git</literal>.  The source side of a builtin is</simpara>\r
+<itemizedlist>\r
+<listitem>\r
+<simpara>\r
+a function called <literal>cmd_&lt;bla&gt;</literal>, typically defined in <literal>builtin-&lt;bla&gt;.c</literal>,\r
+  and declared in <literal>builtin.h</literal>,\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+an entry in the <literal>commands[]</literal> array in <literal>git.c</literal>, and\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+an entry in <literal>BUILTIN_OBJECTS</literal> in the <literal>Makefile</literal>.\r
+</simpara>\r
+</listitem>\r
+</itemizedlist>\r
+<simpara>Sometimes, more than one builtin is contained in one source file.  For\r
+example, <literal>cmd_whatchanged()</literal> and <literal>cmd_log()</literal> both reside in <literal>builtin-log.c</literal>,\r
+since they share quite a bit of code.  In that case, the commands which are\r
+<emphasis>not</emphasis> named like the <literal>.c</literal> file in which they live have to be listed in\r
+<literal>BUILT_INS</literal> in the <literal>Makefile</literal>.</simpara>\r
+<simpara><literal>git-log</literal> looks more complicated in C than it does in the original script,\r
+but that allows for a much greater flexibility and performance.</simpara>\r
+<simpara>Here again it is a good point to take a pause.</simpara>\r
+<simpara>Lesson three is: study the code.  Really, it is the best way to learn about\r
+the organization of Git (after you know the basic concepts).</simpara>\r
+<simpara>So, think about something which you are interested in, say, "how can I\r
+access a blob just knowing the object name of it?".  The first step is to\r
+find a Git command with which you can do it.  In this example, it is either\r
+<literal>git-show</literal> or <literal>git-cat-file</literal>.</simpara>\r
+<simpara>For the sake of clarity, let&#8217;s stay with <literal>git-cat-file</literal>, because it</simpara>\r
+<itemizedlist>\r
+<listitem>\r
+<simpara>\r
+is plumbing, and\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+was around even in the initial commit (it literally went only through\r
+  some 20 revisions as <literal>cat-file.c</literal>, was renamed to <literal>builtin-cat-file.c</literal>\r
+  when made a builtin, and then saw less than 10 versions).\r
+</simpara>\r
+</listitem>\r
+</itemizedlist>\r
+<simpara>So, look into <literal>builtin-cat-file.c</literal>, search for <literal>cmd_cat_file()</literal> and look what\r
+it does.</simpara>\r
+<literallayout>        git_config(git_default_config);\r
+        if (argc != 3)\r
+                usage("git-cat-file [-t|-s|-e|-p|&lt;type&gt;] &lt;sha1&gt;");\r
+        if (get_sha1(argv[2], sha1))\r
+                die("Not a valid object name %s", argv[2]);</literallayout>\r
+<simpara>Let&#8217;s skip over the obvious details; the only really interesting part\r
+here is the call to <literal>get_sha1()</literal>.  It tries to interpret <literal>argv[2]</literal> as an\r
+object name, and if it refers to an object which is present in the current\r
+repository, it writes the resulting SHA-1 into the variable <literal>sha1</literal>.</simpara>\r
+<simpara>Two things are interesting here:</simpara>\r
+<itemizedlist>\r
+<listitem>\r
+<simpara>\r
+<literal>get_sha1()</literal> returns 0 on <emphasis>success</emphasis>.  This might surprise some new\r
+  Git hackers, but there is a long tradition in UNIX to return different\r
+  negative numbers in case of different errors&#8212;and 0 on success.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+the variable <literal>sha1</literal> in the function signature of <literal>get_sha1()</literal> is <literal>unsigned\r
+  char *</literal>, but is actually expected to be a pointer to <literal>unsigned\r
+  char[20]</literal>.  This variable will contain the 160-bit SHA-1 of the given\r
+  commit.  Note that whenever a SHA-1 is passed as <literal>unsigned char \*</literal>, it\r
+  is the binary representation, as opposed to the ASCII representation in\r
+  hex characters, which is passed as <literal>char *</literal>.\r
+</simpara>\r
+</listitem>\r
+</itemizedlist>\r
+<simpara>You will see both of these things throughout the code.</simpara>\r
+<simpara>Now, for the meat:</simpara>\r
+<literallayout>        case 0:\r
+                buf = read_object_with_reference(sha1, argv[1], &amp;size, NULL);</literallayout>\r
+<simpara>This is how you read a blob (actually, not only a blob, but any type of\r
+object).  To know how the function <literal>read_object_with_reference()</literal> actually\r
+works, find the source code for it (something like <literal>git grep\r
+read_object_with | grep ":[a-z]"</literal> in the git repository), and read\r
+the source.</simpara>\r
+<simpara>To find out how the result can be used, just read on in <literal>cmd_cat_file()</literal>:</simpara>\r
+<literallayout>        write_or_die(1, buf, size);</literallayout>\r
+<simpara>Sometimes, you do not know where to look for a feature.  In many such cases,\r
+it helps to search through the output of <literal>git log</literal>, and then <literal>git-show</literal> the\r
+corresponding commit.</simpara>\r
+<simpara>Example: If you know that there was some test case for <literal>git-bundle</literal>, but\r
+do not remember where it was (yes, you <emphasis>could</emphasis> <literal>git grep bundle t/</literal>, but that\r
+does not illustrate the point!):</simpara>\r
+<literallayout>$ git log --no-merges t/</literallayout>\r
+<simpara>In the pager (<literal>less</literal>), just search for "bundle", go a few lines back,\r
+and see that it is in commit 18449ab0&#8230;  Now just copy this object name,\r
+and paste it into the command line</simpara>\r
+<literallayout>$ git show 18449ab0</literallayout>\r
+<simpara>Voila.</simpara>\r
+<simpara>Another example: Find out what to do in order to make some script a\r
+builtin:</simpara>\r
+<literallayout>$ git log --no-merges --diff-filter=A builtin-*.c</literallayout>\r
+<simpara>You see, Git is actually the best tool to find out about the source of Git\r
+itself!</simpara>\r
+</section>\r
+</section>\r
+<section id="glossary">\r
+<title>GIT Glossary</title>\r
+<variablelist>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_alternate_object_database" xreflabel="[def_alternate_object_database]"/>alternate object database\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Via the alternates mechanism, a <link linkend="def_repository">repository</link>\r
+        can inherit part of its <link linkend="def_object_database">object database</link>\r
+        from another object database, which is called "alternate".\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_bare_repository" xreflabel="[def_bare_repository]"/>bare repository\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        A bare repository is normally an appropriately\r
+        named <link linkend="def_directory">directory</link> with a <literal>.git</literal> suffix that does not\r
+        have a locally checked-out copy of any of the files under\r
+        revision control. That is, all of the <literal>git</literal>\r
+        administrative and control files that would normally be present in the\r
+        hidden <literal>.git</literal> sub-directory are directly present in the\r
+        <literal>repository.git</literal> directory instead,\r
+        and no other files are present and checked out. Usually publishers of\r
+        public repositories make bare repositories available.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_blob_object" xreflabel="[def_blob_object]"/>blob object\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Untyped <link linkend="def_object">object</link>, e.g. the contents of a file.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_branch" xreflabel="[def_branch]"/>branch\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        A "branch" is an active line of development.  The most recent\r
+        <link linkend="def_commit">commit</link> on a branch is referred to as the tip of\r
+        that branch.  The tip of the branch is referenced by a branch\r
+        <link linkend="def_head">head</link>, which moves forward as additional development\r
+        is done on the branch.  A single git\r
+        <link linkend="def_repository">repository</link> can track an arbitrary number of\r
+        branches, but your <link linkend="def_working_tree">working tree</link> is\r
+        associated with just one of them (the "current" or "checked out"\r
+        branch), and <link linkend="def_HEAD">HEAD</link> points to that branch.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_cache" xreflabel="[def_cache]"/>cache\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Obsolete for: <link linkend="def_index">index</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_chain" xreflabel="[def_chain]"/>chain\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        A list of objects, where each <link linkend="def_object">object</link> in the list contains\r
+        a reference to its successor (for example, the successor of a\r
+        <link linkend="def_commit">commit</link> could be one of its <link linkend="def_parent">parents</link>).\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_changeset" xreflabel="[def_changeset]"/>changeset\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        BitKeeper/cvsps speak for "<link linkend="def_commit">commit</link>". Since git does not\r
+        store changes, but states, it really does not make sense to use the term\r
+        "changesets" with git.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_checkout" xreflabel="[def_checkout]"/>checkout\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        The action of updating all or part of the\r
+        <link linkend="def_working_tree">working tree</link> with a <link linkend="def_tree_object">tree object</link>\r
+        or <link linkend="def_blob_object">blob</link> from the\r
+        <link linkend="def_object_database">object database</link>, and updating the\r
+        <link linkend="def_index">index</link> and <link linkend="def_HEAD">HEAD</link> if the whole working tree has\r
+        been pointed at a new <link linkend="def_branch">branch</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_cherry-picking" xreflabel="[def_cherry-picking]"/>cherry-picking\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        In <link linkend="def_SCM">SCM</link> jargon, "cherry pick" means to choose a subset of\r
+        changes out of a series of changes (typically commits) and record them\r
+        as a new series of changes on top of a different codebase. In GIT, this is\r
+        performed by the "git cherry-pick" command to extract the change introduced\r
+        by an existing <link linkend="def_commit">commit</link> and to record it based on the tip\r
+        of the current <link linkend="def_branch">branch</link> as a new commit.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_clean" xreflabel="[def_clean]"/>clean\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        A <link linkend="def_working_tree">working tree</link> is clean, if it\r
+        corresponds to the <link linkend="def_revision">revision</link> referenced by the current\r
+        <link linkend="def_head">head</link>. Also see "<link linkend="def_dirty">dirty</link>".\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_commit" xreflabel="[def_commit]"/>commit\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        As a noun: A single point in the\r
+        git history; the entire history of a project is represented as a\r
+        set of interrelated commits.  The word "commit" is often\r
+        used by git in the same places other revision control systems\r
+        use the words "revision" or "version".  Also used as a short\r
+        hand for <link linkend="def_commit_object">commit object</link>.\r
+</simpara>\r
+<simpara>As a verb: The action of storing a new snapshot of the project&#8217;s\r
+state in the git history, by creating a new commit representing the current\r
+state of the <link linkend="def_index">index</link> and advancing <link linkend="def_HEAD">HEAD</link>\r
+to point at the new commit.</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_commit_object" xreflabel="[def_commit_object]"/>commit object\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        An <link linkend="def_object">object</link> which contains the information about a\r
+        particular <link linkend="def_revision">revision</link>, such as <link linkend="def_parent">parents</link>, committer,\r
+        author, date and the <link linkend="def_tree_object">tree object</link> which corresponds\r
+        to the top <link linkend="def_directory">directory</link> of the stored\r
+        revision.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_core_git" xreflabel="[def_core_git]"/>core git\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Fundamental data structures and utilities of git. Exposes only limited\r
+        source code management tools.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_DAG" xreflabel="[def_DAG]"/>DAG\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Directed acyclic graph. The <link linkend="def_commit_object">commit objects</link> form a\r
+        directed acyclic graph, because they have parents (directed), and the\r
+        graph of commit objects is acyclic (there is no <link linkend="def_chain">chain</link>\r
+        which begins and ends with the same <link linkend="def_object">object</link>).\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_dangling_object" xreflabel="[def_dangling_object]"/>dangling object\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        An <link linkend="def_unreachable_object">unreachable object</link> which is not\r
+        <link linkend="def_reachable">reachable</link> even from other unreachable objects; a\r
+        dangling object has no references to it from any\r
+        reference or <link linkend="def_object">object</link> in the <link linkend="def_repository">repository</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_detached_HEAD" xreflabel="[def_detached_HEAD]"/>detached HEAD\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Normally the <link linkend="def_HEAD">HEAD</link> stores the name of a\r
+        <link linkend="def_branch">branch</link>.  However, git also allows you to <link linkend="def_checkout">check out</link>\r
+        an arbitrary <link linkend="def_commit">commit</link> that isn&#8217;t necessarily the tip of any\r
+        particular branch.  In this case HEAD is said to be "detached".\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_dircache" xreflabel="[def_dircache]"/>dircache\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        You are <emphasis role="strong">waaaaay</emphasis> behind. See <link linkend="def_index">index</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_directory" xreflabel="[def_directory]"/>directory\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        The list you get with "ls" :-)\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_dirty" xreflabel="[def_dirty]"/>dirty\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        A <link linkend="def_working_tree">working tree</link> is said to be "dirty" if\r
+        it contains modifications which have not been <link linkend="def_commit">committed</link> to the current\r
+        <link linkend="def_branch">branch</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_ent" xreflabel="[def_ent]"/>ent\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Favorite synonym to "<link linkend="def_tree-ish">tree-ish</link>" by some total geeks. See\r
+        <literal>http://en.wikipedia.org/wiki/Ent_(Middle-earth)</literal> for an in-depth\r
+        explanation. Avoid this term, not to confuse people.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_evil_merge" xreflabel="[def_evil_merge]"/>evil merge\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        An evil merge is a <link linkend="def_merge">merge</link> that introduces changes that\r
+        do not appear in any <link linkend="def_parent">parent</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_fast_forward" xreflabel="[def_fast_forward]"/>fast forward\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        A fast-forward is a special type of <link linkend="def_merge">merge</link> where you have a\r
+        <link linkend="def_revision">revision</link> and you are "merging" another\r
+        <link linkend="def_branch">branch</link>'s changes that happen to be a descendant of what\r
+        you have. In such these cases, you do not make a new <link linkend="def_merge">merge</link>\r
+        <link linkend="def_commit">commit</link> but instead just update to his\r
+        revision. This will happen frequently on a\r
+        <link linkend="def_tracking_branch">tracking branch</link> of a remote\r
+        <link linkend="def_repository">repository</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_fetch" xreflabel="[def_fetch]"/>fetch\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Fetching a <link linkend="def_branch">branch</link> means to get the\r
+        branch&#8217;s <link linkend="def_head_ref">head ref</link> from a remote\r
+        <link linkend="def_repository">repository</link>, to find out which objects are\r
+        missing from the local <link linkend="def_object_database">object database</link>,\r
+        and to get them, too.  See also <ulink url="git-fetch.html">git-fetch(1)</ulink>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_file_system" xreflabel="[def_file_system]"/>file system\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Linus Torvalds originally designed git to be a user space file system,\r
+        i.e. the infrastructure to hold files and directories. That ensured the\r
+        efficiency and speed of git.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_git_archive" xreflabel="[def_git_archive]"/>git archive\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Synonym for <link linkend="def_repository">repository</link> (for arch people).\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_grafts" xreflabel="[def_grafts]"/>grafts\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Grafts enables two otherwise different lines of development to be joined\r
+        together by recording fake ancestry information for commits. This way\r
+        you can make git pretend the set of <link linkend="def_parent">parents</link> a <link linkend="def_commit">commit</link> has\r
+        is different from what was recorded when the commit was\r
+        created. Configured via the <literal>.git/info/grafts</literal> file.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_hash" xreflabel="[def_hash]"/>hash\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        In git&#8217;s context, synonym to <link linkend="def_object_name">object name</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_head" xreflabel="[def_head]"/>head\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        A <link linkend="def_ref">named reference</link> to the <link linkend="def_commit">commit</link> at the tip of a\r
+        <link linkend="def_branch">branch</link>.  Heads are stored in\r
+        <literal>$GIT_DIR/refs/heads/</literal>, except when using packed refs. (See\r
+        <ulink url="git-pack-refs.html">git-pack-refs(1)</ulink>.)\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_HEAD" xreflabel="[def_HEAD]"/>HEAD\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        The current <link linkend="def_branch">branch</link>.  In more detail: Your <link linkend="def_working_tree">working tree</link> is normally derived from the state of the tree\r
+        referred to by HEAD.  HEAD is a reference to one of the\r
+        <link linkend="def_head">heads</link> in your repository, except when using a\r
+        <link linkend="def_detached_HEAD">detached HEAD</link>, in which case it may\r
+        reference an arbitrary commit.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_head_ref" xreflabel="[def_head_ref]"/>head ref\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        A synonym for <link linkend="def_head">head</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_hook" xreflabel="[def_hook]"/>hook\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        During the normal execution of several git commands, call-outs are made\r
+        to optional scripts that allow a developer to add functionality or\r
+        checking. Typically, the hooks allow for a command to be pre-verified\r
+        and potentially aborted, and allow for a post-notification after the\r
+        operation is done. The hook scripts are found in the\r
+        <literal>$GIT_DIR/hooks/</literal> directory, and are enabled by simply\r
+        removing the <literal>.sample</literal> suffix from the filename. In earlier versions\r
+        of git you had to make them executable.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_index" xreflabel="[def_index]"/>index\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        A collection of files with stat information, whose contents are stored\r
+        as objects. The index is a stored version of your\r
+        <link linkend="def_working_tree">working tree</link>. Truth be told, it can also contain a second, and even\r
+        a third version of a working tree, which are used\r
+        when <link linkend="def_merge">merging</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_index_entry" xreflabel="[def_index_entry]"/>index entry\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        The information regarding a particular file, stored in the\r
+        <link linkend="def_index">index</link>. An index entry can be unmerged, if a\r
+        <link linkend="def_merge">merge</link> was started, but not yet finished (i.e. if\r
+        the index contains multiple versions of that file).\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_master" xreflabel="[def_master]"/>master\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        The default development <link linkend="def_branch">branch</link>. Whenever you\r
+        create a git <link linkend="def_repository">repository</link>, a branch named\r
+        "master" is created, and becomes the active branch. In most\r
+        cases, this contains the local development, though that is\r
+        purely by convention and is not required.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_merge" xreflabel="[def_merge]"/>merge\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        As a verb: To bring the contents of another\r
+        <link linkend="def_branch">branch</link> (possibly from an external\r
+        <link linkend="def_repository">repository</link>) into the current branch.  In the\r
+        case where the merged-in branch is from a different repository,\r
+        this is done by first <link linkend="def_fetch">fetching</link> the remote branch\r
+        and then merging the result into the current branch.  This\r
+        combination of fetch and merge operations is called a\r
+        <link linkend="def_pull">pull</link>.  Merging is performed by an automatic process\r
+        that identifies changes made since the branches diverged, and\r
+        then applies all those changes together.  In cases where changes\r
+        conflict, manual intervention may be required to complete the\r
+        merge.\r
+</simpara>\r
+<simpara>As a noun: unless it is a <link linkend="def_fast_forward">fast forward</link>, a\r
+successful merge results in the creation of a new <link linkend="def_commit">commit</link>\r
+representing the result of the merge, and having as\r
+<link linkend="def_parent">parents</link> the tips of the merged <link linkend="def_branch">branches</link>.\r
+This commit is referred to as a "merge commit", or sometimes just a\r
+"merge".</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_object" xreflabel="[def_object]"/>object\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        The unit of storage in git. It is uniquely identified by the\r
+        <link linkend="def_SHA1">SHA1</link> of its contents. Consequently, an\r
+        object can not be changed.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_object_database" xreflabel="[def_object_database]"/>object database\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Stores a set of "objects", and an individual <link linkend="def_object">object</link> is\r
+        identified by its <link linkend="def_object_name">object name</link>. The objects usually\r
+        live in <literal>$GIT_DIR/objects/</literal>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_object_identifier" xreflabel="[def_object_identifier]"/>object identifier\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Synonym for <link linkend="def_object_name">object name</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_object_name" xreflabel="[def_object_name]"/>object name\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        The unique identifier of an <link linkend="def_object">object</link>. The <link linkend="def_hash">hash</link>\r
+        of the object&#8217;s contents using the Secure Hash Algorithm\r
+        1 and usually represented by the 40 character hexadecimal encoding of\r
+        the <link linkend="def_hash">hash</link> of the object.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_object_type" xreflabel="[def_object_type]"/>object type\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        One of the identifiers "<link linkend="def_commit_object">commit</link>",\r
+        "<link linkend="def_tree_object">tree</link>", "<link linkend="def_tag_object">tag</link>" or\r
+        "<link linkend="def_blob_object">blob</link>" describing the type of an\r
+        <link linkend="def_object">object</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_octopus" xreflabel="[def_octopus]"/>octopus\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        To <link linkend="def_merge">merge</link> more than two <link linkend="def_branch">branches</link>. Also denotes an\r
+        intelligent predator.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_origin" xreflabel="[def_origin]"/>origin\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        The default upstream <link linkend="def_repository">repository</link>. Most projects have\r
+        at least one upstream project which they track. By default\r
+        <emphasis>origin</emphasis> is used for that purpose. New upstream updates\r
+        will be fetched into remote <link linkend="def_tracking_branch">tracking branches</link> named\r
+        origin/name-of-upstream-branch, which you can see using\r
+        "<literal>git branch -r</literal>".\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_pack" xreflabel="[def_pack]"/>pack\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        A set of objects which have been compressed into one file (to save space\r
+        or to transmit them efficiently).\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_pack_index" xreflabel="[def_pack_index]"/>pack index\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        The list of identifiers, and other information, of the objects in a\r
+        <link linkend="def_pack">pack</link>, to assist in efficiently accessing the contents of a\r
+        pack.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_parent" xreflabel="[def_parent]"/>parent\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        A <link linkend="def_commit_object">commit object</link> contains a (possibly empty) list\r
+        of the logical predecessor(s) in the line of development, i.e. its\r
+        parents.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_pickaxe" xreflabel="[def_pickaxe]"/>pickaxe\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        The term <link linkend="def_pickaxe">pickaxe</link> refers to an option to the diffcore\r
+        routines that help select changes that add or delete a given text\r
+        string. With the <literal>--pickaxe-all</literal> option, it can be used to view the full\r
+        <link linkend="def_changeset">changeset</link> that introduced or removed, say, a\r
+        particular line of text. See <ulink url="git-diff.html">git-diff(1)</ulink>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_plumbing" xreflabel="[def_plumbing]"/>plumbing\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Cute name for <link linkend="def_core_git">core git</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_porcelain" xreflabel="[def_porcelain]"/>porcelain\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Cute name for programs and program suites depending on\r
+        <link linkend="def_core_git">core git</link>, presenting a high level access to\r
+        core git. Porcelains expose more of a <link linkend="def_SCM">SCM</link>\r
+        interface than the <link linkend="def_plumbing">plumbing</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_pull" xreflabel="[def_pull]"/>pull\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Pulling a <link linkend="def_branch">branch</link> means to <link linkend="def_fetch">fetch</link> it and\r
+        <link linkend="def_merge">merge</link> it.  See also <ulink url="git-pull.html">git-pull(1)</ulink>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_push" xreflabel="[def_push]"/>push\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Pushing a <link linkend="def_branch">branch</link> means to get the branch&#8217;s\r
+        <link linkend="def_head_ref">head ref</link> from a remote <link linkend="def_repository">repository</link>,\r
+        find out if it is a direct ancestor to the branch&#8217;s local\r
+        head ref, and in that case, putting all\r
+        objects, which are <link linkend="def_reachable">reachable</link> from the local\r
+        head ref, and which are missing from the remote\r
+        repository, into the remote\r
+        <link linkend="def_object_database">object database</link>, and updating the remote\r
+        head ref. If the remote <link linkend="def_head">head</link> is not an\r
+        ancestor to the local head, the push fails.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_reachable" xreflabel="[def_reachable]"/>reachable\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        All of the ancestors of a given <link linkend="def_commit">commit</link> are said to be\r
+        "reachable" from that commit. More\r
+        generally, one <link linkend="def_object">object</link> is reachable from\r
+        another if we can reach the one from the other by a <link linkend="def_chain">chain</link>\r
+        that follows <link linkend="def_tag">tags</link> to whatever they tag,\r
+        <link linkend="def_commit_object">commits</link> to their parents or trees, and\r
+        <link linkend="def_tree_object">trees</link> to the trees or <link linkend="def_blob_object">blobs</link>\r
+        that they contain.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_rebase" xreflabel="[def_rebase]"/>rebase\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        To reapply a series of changes from a <link linkend="def_branch">branch</link> to a\r
+        different base, and reset the <link linkend="def_head">head</link> of that branch\r
+        to the result.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_ref" xreflabel="[def_ref]"/>ref\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        A 40-byte hex representation of a <link linkend="def_SHA1">SHA1</link> or a name that\r
+        denotes a particular <link linkend="def_object">object</link>. These may be stored in\r
+        <literal>$GIT_DIR/refs/</literal>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_reflog" xreflabel="[def_reflog]"/>reflog\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        A reflog shows the local "history" of a ref.  In other words,\r
+        it can tell you what the 3rd last revision in <emphasis>this</emphasis> repository\r
+        was, and what was the current state in <emphasis>this</emphasis> repository,\r
+        yesterday 9:14pm.  See <ulink url="git-reflog.html">git-reflog(1)</ulink> for details.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_refspec" xreflabel="[def_refspec]"/>refspec\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        A "refspec" is used by <link linkend="def_fetch">fetch</link> and\r
+        <link linkend="def_push">push</link> to describe the mapping between remote\r
+        <link linkend="def_ref">ref</link> and local ref. They are combined with a colon in\r
+        the format &lt;src&gt;:&lt;dst&gt;, preceded by an optional plus sign, +.\r
+        For example: <literal>git fetch $URL\r
+        refs/heads/master:refs/heads/origin</literal> means "grab the master\r
+        <link linkend="def_branch">branch</link> <link linkend="def_head">head</link> from the $URL and store\r
+        it as my origin branch head". And <literal>git push\r
+        $URL refs/heads/master:refs/heads/to-upstream</literal> means "publish my\r
+        master branch head as to-upstream branch at $URL". See also\r
+        <ulink url="git-push.html">git-push(1)</ulink>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_repository" xreflabel="[def_repository]"/>repository\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        A collection of <link linkend="def_ref">refs</link> together with an\r
+        <link linkend="def_object_database">object database</link> containing all objects\r
+        which are <link linkend="def_reachable">reachable</link> from the refs, possibly\r
+        accompanied by meta data from one or more <link linkend="def_porcelain">porcelains</link>. A\r
+        repository can share an object database with other repositories\r
+        via <link linkend="def_alternate_object_database">alternates mechanism</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_resolve" xreflabel="[def_resolve]"/>resolve\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        The action of fixing up manually what a failed automatic\r
+        <link linkend="def_merge">merge</link> left behind.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_revision" xreflabel="[def_revision]"/>revision\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        A particular state of files and directories which was stored in the\r
+        <link linkend="def_object_database">object database</link>. It is referenced by a\r
+        <link linkend="def_commit_object">commit object</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_rewind" xreflabel="[def_rewind]"/>rewind\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        To throw away part of the development, i.e. to assign the\r
+        <link linkend="def_head">head</link> to an earlier <link linkend="def_revision">revision</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_SCM" xreflabel="[def_SCM]"/>SCM\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Source code management (tool).\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_SHA1" xreflabel="[def_SHA1]"/>SHA1\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Synonym for <link linkend="def_object_name">object name</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_shallow_repository" xreflabel="[def_shallow_repository]"/>shallow repository\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        A shallow <link linkend="def_repository">repository</link> has an incomplete\r
+        history some of whose <link linkend="def_commit">commits</link> have <link linkend="def_parent">parents</link> cauterized away (in other\r
+        words, git is told to pretend that these commits do not have the\r
+        parents, even though they are recorded in the <link linkend="def_commit_object">commit         object</link>). This is sometimes useful when you are interested only in the\r
+        recent history of a project even though the real history recorded in the\r
+        upstream is much larger. A shallow repository\r
+        is created by giving the <literal>--depth</literal> option to <ulink url="git-clone.html">git-clone(1)</ulink>, and\r
+        its history can be later deepened with <ulink url="git-fetch.html">git-fetch(1)</ulink>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_symref" xreflabel="[def_symref]"/>symref\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Symbolic reference: instead of containing the <link linkend="def_SHA1">SHA1</link>\r
+        id itself, it is of the format <emphasis>ref: refs/some/thing</emphasis> and when\r
+        referenced, it recursively dereferences to this reference.\r
+        <emphasis><link linkend="def_HEAD">HEAD</link></emphasis> is a prime example of a symref. Symbolic\r
+        references are manipulated with the <ulink url="git-symbolic-ref.html">git-symbolic-ref(1)</ulink>\r
+        command.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_tag" xreflabel="[def_tag]"/>tag\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        A <link linkend="def_ref">ref</link> pointing to a <link linkend="def_tag_object">tag</link> or\r
+        <link linkend="def_commit_object">commit object</link>. In contrast to a <link linkend="def_head">head</link>,\r
+        a tag is not changed by a <link linkend="def_commit">commit</link>. Tags (not\r
+        <link linkend="def_tag_object">tag objects</link>) are stored in <literal>$GIT_DIR/refs/tags/</literal>. A\r
+        git tag has nothing to do with a Lisp tag (which would be\r
+        called an <link linkend="def_object_type">object type</link> in git&#8217;s context). A\r
+        tag is most typically used to mark a particular point in the\r
+        commit ancestry <link linkend="def_chain">chain</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_tag_object" xreflabel="[def_tag_object]"/>tag object\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        An <link linkend="def_object">object</link> containing a <link linkend="def_ref">ref</link> pointing to\r
+        another object, which can contain a message just like a\r
+        <link linkend="def_commit_object">commit object</link>. It can also contain a (PGP)\r
+        signature, in which case it is called a "signed tag object".\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_topic_branch" xreflabel="[def_topic_branch]"/>topic branch\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        A regular git <link linkend="def_branch">branch</link> that is used by a developer to\r
+        identify a conceptual line of development. Since branches are very easy\r
+        and inexpensive, it is often desirable to have several small branches\r
+        that each contain very well defined concepts or small incremental yet\r
+        related changes.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_tracking_branch" xreflabel="[def_tracking_branch]"/>tracking branch\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        A regular git <link linkend="def_branch">branch</link> that is used to follow changes from\r
+        another <link linkend="def_repository">repository</link>. A tracking\r
+        branch should not contain direct modifications or have local commits\r
+        made to it. A tracking branch can usually be\r
+        identified as the right-hand-side <link linkend="def_ref">ref</link> in a Pull:\r
+        <link linkend="def_refspec">refspec</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_tree" xreflabel="[def_tree]"/>tree\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Either a <link linkend="def_working_tree">working tree</link>, or a <link linkend="def_tree_object">tree         object</link> together with the dependent <link linkend="def_blob_object">blob</link> and tree objects\r
+        (i.e. a stored representation of a working tree).\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_tree_object" xreflabel="[def_tree_object]"/>tree object\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        An <link linkend="def_object">object</link> containing a list of file names and modes along\r
+        with refs to the associated blob and/or tree objects. A\r
+        <link linkend="def_tree">tree</link> is equivalent to a <link linkend="def_directory">directory</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_tree-ish" xreflabel="[def_tree-ish]"/>tree-ish\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        A <link linkend="def_ref">ref</link> pointing to either a <link linkend="def_commit_object">commit         object</link>, a <link linkend="def_tree_object">tree object</link>, or a <link linkend="def_tag_object">tag         object</link> pointing to a tag or commit or tree object.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_unmerged_index" xreflabel="[def_unmerged_index]"/>unmerged index\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        An <link linkend="def_index">index</link> which contains unmerged\r
+        <link linkend="def_index_entry">index entries</link>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_unreachable_object" xreflabel="[def_unreachable_object]"/>unreachable object\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        An <link linkend="def_object">object</link> which is not <link linkend="def_reachable">reachable</link> from a\r
+        <link linkend="def_branch">branch</link>, <link linkend="def_tag">tag</link>, or any other reference.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+<anchor id="def_working_tree" xreflabel="[def_working_tree]"/>working tree\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        The tree of actual checked out files.  The working tree is\r
+        normally equal to the <link linkend="def_HEAD">HEAD</link> plus any local changes\r
+        that you have made but not yet committed.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+</variablelist>\r
+</section>\r
+<appendix id="git-quick-start">\r
+<title>Git Quick Reference</title>\r
+<simpara>This is a quick summary of the major commands; the previous chapters\r
+explain how these work in more detail.</simpara>\r
+<section id="quick-creating-a-new-repository">\r
+<title>Creating a new repository</title>\r
+<simpara>From a tarball:</simpara>\r
+<literallayout>$ tar xzf project.tar.gz\r
+$ cd project\r
+$ git init\r
+Initialized empty Git repository in .git/\r
+$ git add .\r
+$ git commit</literallayout>\r
+<simpara>From a remote repository:</simpara>\r
+<literallayout>$ git clone git://example.com/pub/project.git\r
+$ cd project</literallayout>\r
+</section>\r
+<section id="managing-branches">\r
+<title>Managing branches</title>\r
+<literallayout>$ git branch         # list all local branches in this repo\r
+$ git checkout test  # switch working directory to branch "test"\r
+$ git branch new     # create branch "new" starting at current HEAD\r
+$ git branch -d new  # delete branch "new"</literallayout>\r
+<simpara>Instead of basing a new branch on current HEAD (the default), use:</simpara>\r
+<literallayout>$ git branch new test    # branch named "test"\r
+$ git branch new v2.6.15 # tag named v2.6.15\r
+$ git branch new HEAD^   # commit before the most recent\r
+$ git branch new HEAD^^  # commit before that\r
+$ git branch new test~10 # ten commits before tip of branch "test"</literallayout>\r
+<simpara>Create and switch to a new branch at the same time:</simpara>\r
+<literallayout>$ git checkout -b new v2.6.15</literallayout>\r
+<simpara>Update and examine branches from the repository you cloned from:</simpara>\r
+<literallayout>$ git fetch             # update\r
+$ git branch -r         # list\r
+  origin/master\r
+  origin/next\r
+  ...\r
+$ git checkout -b masterwork origin/master</literallayout>\r
+<simpara>Fetch a branch from a different repository, and give it a new\r
+name in your repository:</simpara>\r
+<literallayout>$ git fetch git://example.com/project.git theirbranch:mybranch\r
+$ git fetch git://example.com/project.git v2.6.15:mybranch</literallayout>\r
+<simpara>Keep a list of repositories you work with regularly:</simpara>\r
+<literallayout>$ git remote add example git://example.com/project.git\r
+$ git remote                    # list remote repositories\r
+example\r
+origin\r
+$ git remote show example       # get details\r
+* remote example\r
+  URL: git://example.com/project.git\r
+  Tracked remote branches\r
+    master\r
+    next\r
+    ...\r
+$ git fetch example             # update branches from example\r
+$ git branch -r                 # list all remote branches</literallayout>\r
+</section>\r
+<section id="exploring-history">\r
+<title>Exploring history</title>\r
+<literallayout>$ gitk                      # visualize and browse history\r
+$ git log                   # list all commits\r
+$ git log src/              # ...modifying src/\r
+$ git log v2.6.15..v2.6.16  # ...in v2.6.16, not in v2.6.15\r
+$ git log master..test      # ...in branch test, not in branch master\r
+$ git log test..master      # ...in branch master, but not in test\r
+$ git log test...master     # ...in one branch, not in both\r
+$ git log -S'foo()'         # ...where difference contain "foo()"\r
+$ git log --since="2 weeks ago"\r
+$ git log -p                # show patches as well\r
+$ git show                  # most recent commit\r
+$ git diff v2.6.15..v2.6.16 # diff between two tagged versions\r
+$ git diff v2.6.15..HEAD    # diff with current head\r
+$ git grep "foo()"          # search working directory for "foo()"\r
+$ git grep v2.6.15 "foo()"  # search old tree for "foo()"\r
+$ git show v2.6.15:a.txt    # look at old version of a.txt</literallayout>\r
+<simpara>Search for regressions:</simpara>\r
+<literallayout>$ git bisect start\r
+$ git bisect bad                # current version is bad\r
+$ git bisect good v2.6.13-rc2   # last known good revision\r
+Bisecting: 675 revisions left to test after this\r
+                                # test here, then:\r
+$ git bisect good               # if this revision is good, or\r
+$ git bisect bad                # if this revision is bad.\r
+                                # repeat until done.</literallayout>\r
+</section>\r
+<section id="making-changes">\r
+<title>Making changes</title>\r
+<simpara>Make sure git knows who to blame:</simpara>\r
+<literallayout>$ cat &gt;&gt;~/.gitconfig &lt;&lt;\EOF\r
+[user]\r
+        name = Your Name Comes Here\r
+        email = you@yourdomain.example.com\r
+EOF</literallayout>\r
+<simpara>Select file contents to include in the next commit, then make the\r
+commit:</simpara>\r
+<literallayout>$ git add a.txt    # updated file\r
+$ git add b.txt    # new file\r
+$ git rm c.txt     # old file\r
+$ git commit</literallayout>\r
+<simpara>Or, prepare and create the commit in one step:</simpara>\r
+<literallayout>$ git commit d.txt # use latest content only of d.txt\r
+$ git commit -a    # use latest content of all tracked files</literallayout>\r
+</section>\r
+<section id="merging">\r
+<title>Merging</title>\r
+<literallayout>$ git merge test   # merge branch "test" into the current branch\r
+$ git pull git://example.com/project.git master\r
+                   # fetch and merge in remote branch\r
+$ git pull . test  # equivalent to git merge test</literallayout>\r
+</section>\r
+<section id="sharing-your-changes">\r
+<title>Sharing your changes</title>\r
+<simpara>Importing or exporting patches:</simpara>\r
+<literallayout>$ git format-patch origin..HEAD # format a patch for each commit\r
+                                # in HEAD but not in origin\r
+$ git am mbox # import patches from the mailbox "mbox"</literallayout>\r
+<simpara>Fetch a branch in a different git repository, then merge into the\r
+current branch:</simpara>\r
+<literallayout>$ git pull git://example.com/project.git theirbranch</literallayout>\r
+<simpara>Store the fetched branch into a local branch before merging into the\r
+current branch:</simpara>\r
+<literallayout>$ git pull git://example.com/project.git theirbranch:mybranch</literallayout>\r
+<simpara>After creating commits on a local branch, update the remote\r
+branch with your commits:</simpara>\r
+<literallayout>$ git push ssh://example.com/project.git mybranch:theirbranch</literallayout>\r
+<simpara>When remote and local branch are both named "test":</simpara>\r
+<literallayout>$ git push ssh://example.com/project.git test</literallayout>\r
+<simpara>Shortcut version for a frequently used remote repository:</simpara>\r
+<literallayout>$ git remote add example ssh://example.com/project.git\r
+$ git push example test</literallayout>\r
+</section>\r
+<section id="repository-maintenance">\r
+<title>Repository maintenance</title>\r
+<simpara>Check for corruption:</simpara>\r
+<literallayout>$ git fsck</literallayout>\r
+<simpara>Recompress, remove unused cruft:</simpara>\r
+<literallayout>$ git gc</literallayout>\r
+</section>\r
+</appendix>\r
+<appendix id="todo">\r
+<title>Notes and todo list for this manual</title>\r
+<simpara>This is a work in progress.</simpara>\r
+<simpara>The basic requirements:</simpara>\r
+<itemizedlist>\r
+<listitem>\r
+<simpara>\r
+It must be readable in order, from beginning to end, by someone\r
+  intelligent with a basic grasp of the UNIX command line, but without\r
+  any special knowledge of git.  If necessary, any other prerequisites\r
+  should be specifically mentioned as they arise.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Whenever possible, section headings should clearly describe the task\r
+  they explain how to do, in language that requires no more knowledge\r
+  than necessary: for example, "importing patches into a project" rather\r
+  than "the git-am command"\r
+</simpara>\r
+</listitem>\r
+</itemizedlist>\r
+<simpara>Think about how to create a clear chapter dependency graph that will\r
+allow people to get to important topics without necessarily reading\r
+everything in between.</simpara>\r
+<simpara>Scan Documentation/ for other stuff left out; in particular:</simpara>\r
+<itemizedlist>\r
+<listitem>\r
+<simpara>\r
+howto&#8217;s\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+some of technical/?\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+hooks\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+list of commands in <ulink url="git.html">git(1)</ulink>\r
+</simpara>\r
+</listitem>\r
+</itemizedlist>\r
+<simpara>Scan email archives for other stuff left out</simpara>\r
+<simpara>Scan man pages to see if any assume more background than this manual\r
+provides.</simpara>\r
+<simpara>Simplify beginning by suggesting disconnected head instead of\r
+temporary branch creation?</simpara>\r
+<simpara>Add more good examples.  Entire sections of just cookbook examples\r
+might be a good idea; maybe make an "advanced examples" section a\r
+standard end-of-chapter section?</simpara>\r
+<simpara>Include cross-references to the glossary, where appropriate.</simpara>\r
+<simpara>Document shallow clones?  See draft 1.5.0 release notes for some\r
+documentation.</simpara>\r
+<simpara>Add a section on working with other version control systems, including\r
+CVS, Subversion, and just imports of series of release tarballs.</simpara>\r
+<simpara>More details on gitweb?</simpara>\r
+<simpara>Write a chapter on using plumbing and writing scripts.</simpara>\r
+<simpara>Alternates, clone -reference, etc.</simpara>\r
+<simpara>More on recovery from repository corruption.  See:\r
+        <ulink url="http://marc.theaimsgroup.com/?l=git&amp;m=117263864820799&amp;w=2">http://marc.theaimsgroup.com/?l=git&amp;m=117263864820799&amp;w=2</ulink>\r
+        <ulink url="http://marc.theaimsgroup.com/?l=git&amp;m=117147855503798&amp;w=2">http://marc.theaimsgroup.com/?l=git&amp;m=117147855503798&amp;w=2</ulink></simpara>\r
+</appendix>\r
+</article>\r