├── .gitignore ├── COPYING ├── README ├── Rakefile ├── TODO.markdown ├── assets ├── blueprint │ ├── ie.css │ ├── plugins │ │ └── fancy-type │ │ │ ├── readme.txt │ │ │ └── screen.css │ ├── print.css │ ├── screen.css │ └── src │ │ ├── forms.css │ │ ├── grid.css │ │ ├── grid.png │ │ ├── ie.css │ │ ├── print.css │ │ ├── reset.css │ │ └── typography.css ├── images │ ├── figure │ │ ├── model-dag.png │ │ ├── model-real.png │ │ ├── object-blob.png │ │ ├── object-commit.png │ │ ├── object-tag.png │ │ ├── object-tree.png │ │ ├── object_types.png │ │ ├── objects-example.png │ │ ├── pack-index.png │ │ ├── packfile-format.png │ │ ├── packfile-index.png │ │ ├── packfile-logic.png │ │ ├── rebase0.png │ │ ├── rebase1.png │ │ ├── rebase2.png │ │ ├── rebase3.png │ │ ├── rebase4.png │ │ └── rebase5.png │ ├── git-logo.png │ ├── github.png │ ├── header-book.gif │ ├── pdf.png │ ├── tar.png │ └── zip.png ├── javascripts │ ├── application.js │ ├── jquery-1.2.6.min.js │ └── jquery.corner.js └── stylesheets │ ├── mac_classic.css │ └── style.css ├── layout ├── book_index_template.html ├── chapter_template.html ├── mac_classic.css ├── pdf_template.html └── second.css ├── output └── .gitignore ├── script ├── html.rb ├── local.rb ├── merge.rb ├── pdf.rb ├── prince.rb ├── publish.rb └── upload.sh └── text ├── .DS_Store ├── 01_Introduction ├── 00_Section_Introduction.markdown └── 0_ Introduction.markdown ├── 02_Git_Object_Db_Basics ├── 0_ Git_Object_Db_Basics.markdown ├── 1_Trees_and_Blobs.markdown ├── 2_Commits.markdown └── 3_Trust_and_Tags.markdown ├── 02a_Git_Directory_and_Working_Directory └── 0_ Git_Directory_and_Working_Directory.markdown ├── 03_The_Git_Index └── 0_ The_Git_Index.markdown ├── 05_Installing_Git ├── 00_Section.markdown ├── 0_Installing_Git.markdown ├── 0_Source.markdown ├── 1_Linux.markdown ├── 2_Mac_104.markdown ├── 3_Mac_105.markdown └── 4_Windows.markdown ├── 06_Setup_and_Initialization ├── 0_ Setup_and_Initialization.markdown └── 1_Git_Config.markdown ├── 06a_Getting_A_Repo ├── 00_Section_Basic_Usage.markdown └── 1_Getting_a_Git_Repo.markdown ├── 07_Normal_Workflow └── 0_ Normal_Workflow.markdown ├── 08_Basic_Branching_and_Merging └── 0_ Basic_Branching_and_Merging.markdown ├── 09_Reviewing_History_Git_Log └── 0_ Reviewing_History_Git_Log.markdown ├── 10_Comparing_Commits_Git_Diff └── 0_ Comparing_Commits_Git_Diff.markdown ├── 11_Distributed_Workflows_Clone_Fetch_Push └── 0_ Distributed_Workflows_Clone_Fetch_Push.markdown ├── 12_Git_Tag └── 0_ Git_Tag.markdown ├── 12a_Ignoring_Files ├── 00_Section_Intermediate_Usage.markdown └── 0_Ignoring_Files.markdown ├── 13_Rebasing └── 0_ Rebasing.markdown ├── 14_Interactive_Rebasing └── 0_ Interactive_Rebasing.markdown ├── 15_Interactive_Adding └── 0_ Interactive_Adding.markdown ├── 16_Stashing └── 0_ Stashing.markdown ├── 17_Git_Treeishes └── 0_ Git_Treeishes.markdown ├── 18_Tracking_Branches └── 0_ Tracking_Branches.markdown ├── 19_Finding_in_Git_Grep └── 0_ Finding_in_Git_Grep.markdown ├── 21_Redoing_Git_Reset_and_Revert └── 0_ Redoing_Git_Reset_and_Revert.markdown ├── 22_Maintaining_Git_Gc_Prune_Fsck └── 0_ Maintaining_Git_Gc_Prune_Fsck.markdown ├── 230_Setting_Up_A_Public_Repo_Git_Http_Ssh_Gitosis └── 0_ Setting_Up_A_Public_Repo.markdown ├── 23A_Setting_Up_Private_Repo └── 0_Setting_Up_Private_Repo.markdown ├── 24_Creating_New_Empty_Branches ├── 00_Section_Advanced_Git.markdown └── 0_ Creating_New_Empty_Branches.markdown ├── 25_Changing_Your_History └── 0_Changing_History.markdown ├── 26_Advanced_Branching_And_Merging ├── 0_Advanced_Branching_And_Merging.markdown └── 1_Advanced_Merging_Multiway_Merge_Subtree.markdown ├── 27_Finding_Issues_Git_Bisect └── 0_ Finding_Issues_Git_Bisect.markdown ├── 28_Finding_Issues_Git_Blame └── 0_ Finding_Issues_Git_Blame.markdown ├── 29_Git_and_Email_Am_Format_Patch └── 0_ Git_and_Email_Am_Format.markdown ├── 30_Customizing_Git_Git_Config └── 0_ Customizing_Git_Git_Config.markdown ├── 31_Git_Hooks └── 0_ Git_Hooks.markdown ├── 32_Git_Recovery_Corrupted_Objects └── 0_ Git_Recovery_Corrupted_Objects.markdown ├── 34_Git_Submodules └── 1_Submodules.markdown ├── 35_Git_on_Windows ├── 00_Section_Working_with_Git.markdown └── 0_ Git_on_Windows.markdown ├── 37_Deploying_with_Git └── 0_ Capistrano_and_Git.markdown ├── 38_Subversion_Integration └── 0_ Subversion_Integration.markdown ├── 39_SCM_Migration └── 0_Scm_Migration.markdown ├── 40_Graphical_Git_gitgui_gitk └── 0_ Graphical_Git_gitgui_gitk.markdown ├── 41_Hosting_Git_gitweb_repoorcz_github_gitorious └── 0_ Hosting_Git_gitweb_repoorcz_github.markdown ├── 42_Alternative_Uses_TicGit └── 0_ Alternative_Uses_ContentDistribution.markdown ├── 44_Scripting_and_Git └── 0_ Ruby_and_Git_grit.markdown ├── 47_Git_and_Editors_tm_eclipse_nb └── 0_ Git_and_Editors_tm_eclipse.markdown ├── 48_How_Git_Stores_Objects ├── 00_Section_Internals_and_Plumbing.markdown └── 0_ How_Git_Stores_Objects.markdown ├── 49_Browsing_Git_Objects └── 0_ Browsing_Git_Objects.markdown ├── 50_Git_References_updateref └── 0_ Git_References_updateref.markdown ├── 51_The_Git_Index_lsfiles └── 0_ The_Git_Index_lsfiles.markdown ├── 52_The_Packfile └── 0_The_Packfile.markdown ├── 53_Raw_Git_readtree_writetree_committree └── 0_ Raw_Git_readtree_writetree_committree.markdown ├── 54_Transfer_Protocols └── 0_Transfer_Protocols.markdown └── 55_Glossary └── 0_Glossary.markdown /.gitignore: -------------------------------------------------------------------------------- 1 | output/* 2 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | == The Community Git Book == 2 | 3 | This is an attempt to make a comprehensive, easy to follow Git learning 4 | resource to be hosted on the main Git website. 5 | 6 | == Contributing == 7 | 8 | * Clone this source, add to it and send me (schacon@gmail.com) a patch or pull request 9 | * Install required gems: 10 | $ gem install rake ultraviolet discount rdiscount builder 11 | * For PDF output install prince (http://www.princexml.com/download/) 12 | * Generate book through 13 | $ rake html 14 | or 15 | $ rake pdf 16 | 17 | == References == 18 | 19 | * A bunch of the scripts for building and such from the Rails 2.1 book by Carlos Brando 20 | 21 | == Authors == 22 | 23 | * Scott Chacon 24 | * Emil Sit 25 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'script/merge' 2 | require 'script/html' 3 | require 'script/pdf' 4 | require 'script/prince' 5 | require 'script/publish' 6 | -------------------------------------------------------------------------------- /TODO.markdown: -------------------------------------------------------------------------------- 1 | # Maint Tasks # 2 | 3 | * pre-processors: 4 | - linkgit:(command) 5 | - gitcasts links working (stripped from pdf) 6 | 7 | * link pdf to html page for downloading 8 | - generate cover page for pdf 9 | 10 | 11 | ## Content To-Do ## 12 | 13 | * Clean up the intro (blobs, etc) 14 | * Link gitcasts everywhere 15 | 16 | * Terms Page 17 | * Git Directory and Working Directory 18 | * Installing Git 19 | * More on Diff 20 | * 21 | -------------------------------------------------------------------------------- /assets/blueprint/ie.css: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | 3 | Blueprint CSS Framework 0.7.1 4 | http://blueprintcss.googlecode.com 5 | 6 | * Copyright (c) 2007-2008. See LICENSE for more info. 7 | * See README for instructions on how to use Blueprint. 8 | * For credits and origins, see AUTHORS. 9 | * This is a compressed file. See the sources in the 'src' directory. 10 | 11 | ----------------------------------------------------------------------- */ 12 | 13 | /* ie.css */ 14 | body {text-align:center;} 15 | .container {text-align:left;} 16 | * html .column {overflow-x:hidden;} 17 | * html legend {margin:-18px -8px 16px 0;padding:0;} 18 | ol {margin-left:2em;} 19 | sup {vertical-align:text-top;} 20 | sub {vertical-align:text-bottom;} 21 | html>body p code {*white-space:normal;} 22 | hr {margin:-8px auto 11px;} -------------------------------------------------------------------------------- /assets/blueprint/plugins/fancy-type/readme.txt: -------------------------------------------------------------------------------- 1 | Fancy Type 2 | 3 | * Gives you classes to use if you'd like some 4 | extra fancy typography. 5 | 6 | Credits and instructions are specified above each class 7 | in the fancy-type.css file in this directory. 8 | 9 | 10 | Usage 11 | ---------------------------------------------------------------- 12 | 13 | 1) Add this plugin to lib/settings.yml. 14 | See compress.rb for instructions. 15 | -------------------------------------------------------------------------------- /assets/blueprint/plugins/fancy-type/screen.css: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------------------------- 2 | 3 | fancy-type.css 4 | * Lots of pretty advanced classes for manipulating text. 5 | 6 | See the Readme file in this folder for additional instructions. 7 | 8 | -------------------------------------------------------------- */ 9 | 10 | /* Indentation instead of line shifts for sibling paragraphs. */ 11 | p + p { text-indent:2em; margin-top:-1.5em; } 12 | form p + p { text-indent: 0; } /* Don't want this in forms. */ 13 | 14 | 15 | /* For great looking type, use this code instead of asdf: 16 | asdf 17 | Best used on prepositions and ampersands. */ 18 | 19 | .alt { 20 | color: #666; 21 | font-family: "Warnock Pro", "Goudy Old Style","Palatino","Book Antiqua", Georgia, serif; 22 | font-style: italic; 23 | font-weight: normal; 24 | } 25 | 26 | 27 | /* For great looking quote marks in titles, replace "asdf" with: 28 | “asdf” 29 | (That is, when the title starts with a quote mark). 30 | (You may have to change this value depending on your font size). */ 31 | 32 | .dquo { margin-left: -.5em; } 33 | 34 | 35 | /* Reduced size type with incremental leading 36 | (http://www.markboulton.co.uk/journal/comments/incremental_leading/) 37 | 38 | This could be used for side notes. For smaller type, you don't necessarily want to 39 | follow the 1.5x vertical rhythm -- the line-height is too much. 40 | 41 | Using this class, it reduces your font size and line-height so that for 42 | every four lines of normal sized type, there is five lines of the sidenote. eg: 43 | 44 | New type size in em's: 45 | 10px (wanted side note size) / 12px (existing base size) = 0.8333 (new type size in ems) 46 | 47 | New line-height value: 48 | 12px x 1.5 = 18px (old line-height) 49 | 18px x 4 = 72px 50 | 72px / 5 = 14.4px (new line height) 51 | 14.4px / 10px = 1.44 (new line height in em's) */ 52 | 53 | p.incr, .incr p { 54 | font-size: 10px; 55 | line-height: 1.44em; 56 | margin-bottom: 1.5em; 57 | } 58 | 59 | 60 | /* Surround uppercase words and abbreviations with this class. 61 | Based on work by Jørgen Arnor Gårdsø Lom [http://twistedintellect.com/] */ 62 | 63 | .caps { 64 | font-variant: small-caps; 65 | letter-spacing: 1px; 66 | text-transform: lowercase; 67 | font-size:1.2em; 68 | line-height:1%; 69 | font-weight:bold; 70 | padding:0 2px; 71 | } 72 | -------------------------------------------------------------------------------- /assets/blueprint/print.css: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | 3 | Blueprint CSS Framework 0.7.1 4 | http://blueprintcss.googlecode.com 5 | 6 | * Copyright (c) 2007-2008. See LICENSE for more info. 7 | * See README for instructions on how to use Blueprint. 8 | * For credits and origins, see AUTHORS. 9 | * This is a compressed file. See the sources in the 'src' directory. 10 | 11 | ----------------------------------------------------------------------- */ 12 | 13 | /* print.css */ 14 | body {line-height:1.5;font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;color:#000;background:none;font-size:10pt;} 15 | .container {background:none;} 16 | hr {background:#ccc;color:#ccc;width:100%;height:2px;margin:2em 0;padding:0;border:none;} 17 | hr.space {background:#fff;color:#fff;} 18 | h1, h2, h3, h4, h5, h6 {font-family:"Helvetica Neue", Arial, "Lucida Grande", sans-serif;} 19 | code {font:.9em "Courier New", Monaco, Courier, monospace;} 20 | img {float:left;margin:1.5em 1.5em 1.5em 0;} 21 | a img {border:none;} 22 | p img.top {margin-top:0;} 23 | blockquote {margin:1.5em;padding:1em;font-style:italic;font-size:.9em;} 24 | .small {font-size:.9em;} 25 | .large {font-size:1.1em;} 26 | .quiet {color:#999;} 27 | .hide {display:none;} 28 | a:link, a:visited {background:transparent;font-weight:700;text-decoration:underline;} 29 | a:link:after, a:visited:after {content:" (" attr(href) ") ";font-size:90%;} -------------------------------------------------------------------------------- /assets/blueprint/screen.css: -------------------------------------------------------------------------------- 1 | /* 2 | BLUEPRINT CSS 3 | * Filename: compressed.css 4 | * Version: 0.7.1 (2008-02-25) YYYY-MM-DD 5 | * Website: http://code.google.com/p/blueprintcss/ 6 | 7 | Generated by: 8 | * Blueprint CSS Grid Generator (2008-07-22) [http://kematzy.com/blueprint-generator/] 9 | 10 | == STRUCTURE: ======================== 11 | * Page width: 788 px 12 | * Number of columns: 21 13 | * Column width: 28 px 14 | * Margin width: 10 px 15 | ====================================== 16 | 17 | */ 18 | 19 | /* reset.css */ 20 | html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, code, del, dfn, em, img, q, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td {margin:0;padding:0;border:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;} 21 | body {line-height:1.5;} 22 | table {border-collapse:separate;border-spacing:0;} 23 | caption, th, td {text-align:left;font-weight:normal;} 24 | table, td, th {vertical-align:middle;} 25 | blockquote:before, blockquote:after, q:before, q:after {content:"";} 26 | blockquote, q {quotes:"" "";} 27 | a img {border:none;} 28 | 29 | /* typography.css */ 30 | body {font-size:75%;color:#222;background:#fff;font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;} 31 | h1, h2, h3, h4, h5, h6 {font-weight:normal;color:#111;} 32 | h1 {font-size:3em;line-height:1;margin-bottom:0.5em;} 33 | h2 {font-size:2em;margin-bottom:0.75em;} 34 | h3 {font-size:1.5em;line-height:1;margin-bottom:1em;} 35 | h4 {font-size:1.2em;line-height:1.25;margin-bottom:1.25em;height:1.25em;} 36 | h5 {font-size:1em;font-weight:bold;margin-bottom:1.5em;} 37 | h6 {font-size:1em;font-weight:bold;} 38 | h1 img, h2 img, h3 img, h4 img, h5 img, h6 img {margin:0;} 39 | p {margin:0 0 1.5em;} 40 | p img {float:left;margin:1.5em 1.5em 1.5em 0;padding:0;} 41 | p img.right {float:right;margin:1.5em 0 1.5em 1.5em;} 42 | a:focus, a:hover {color:#000;} 43 | a {color:#009;text-decoration:underline;} 44 | blockquote {margin:1.5em;color:#666;font-style:italic;} 45 | strong {font-weight:bold;} 46 | em, dfn {font-style:italic;} 47 | dfn {font-weight:bold;} 48 | sup, sub {line-height:0;} 49 | abbr, acronym {border-bottom:1px dotted #666;} 50 | address {margin:0 0 1.5em;font-style:italic;} 51 | del {color:#666;} 52 | pre, code {margin:1.5em 0;white-space:pre;} 53 | pre, code, tt {font:1em 'andale mono', 'lucida console', monospace;line-height:1.5;} 54 | li ul, li ol {margin:0 1.5em;} 55 | ul, ol {margin:0 1.5em 1.5em 1.5em;} 56 | ul {list-style-type:disc;} 57 | ol {list-style-type:decimal;} 58 | dl {margin:0 0 1.5em 0;} 59 | dl dt {font-weight:bold;} 60 | dd {margin-left:1.5em;} 61 | table {margin-bottom:1.4em;width:100%;} 62 | th {font-weight:bold;background:#C3D9FF;} 63 | th, td {padding:4px 10px 4px 5px;} 64 | tr.even td {background:#E5ECF9;} 65 | tfoot {font-style:italic;} 66 | caption {background:#eee;} 67 | .small {font-size:.8em;margin-bottom:1.875em;line-height:1.875em;} 68 | .large {font-size:1.2em;line-height:2.5em;margin-bottom:1.25em;} 69 | .hide {display:none;} 70 | .quiet {color:#666;} 71 | .loud {color:#000;} 72 | .highlight {background:#ff0;} 73 | .added {background:#060;color:#fff;} 74 | .removed {background:#900;color:#fff;} 75 | .first {margin-left:0;padding-left:0;} 76 | .last {margin-right:0;padding-right:0;} 77 | .top {margin-top:0;padding-top:0;} 78 | .bottom {margin-bottom:0;padding-bottom:0;} 79 | 80 | /* grid.css */ 81 | .container {width:788px;margin:0 auto;} 82 | .showgrid {background:url(src/grid.png);} 83 | body {margin:1.5em 0;} 84 | div.span-1, div.span-2, div.span-3, div.span-4, div.span-5, div.span-6, div.span-7, div.span-8, div.span-9, div.span-10, div.span-11, div.span-12, div.span-13, div.span-14, div.span-15, div.span-16, div.span-17, div.span-18, div.span-19, div.span-20, div.span-21 {float:left;margin-right: 10px;} 85 | 86 | div.last {margin-right:0;} 87 | .span-1 { width: 28px;} 88 | .span-2 { width: 66px;} 89 | .span-3 { width: 104px;} 90 | .span-4 { width: 142px;} 91 | .span-5 { width: 180px;} 92 | .span-6 { width: 218px;} 93 | .span-7 { width: 256px;} 94 | .span-8 { width: 294px;} 95 | .span-9 { width: 332px;} 96 | .span-10 { width: 370px;} 97 | .span-11 { width: 408px;} 98 | .span-12 { width: 446px;} 99 | .span-13 { width: 484px;} 100 | .span-14 { width: 522px;} 101 | .span-15 { width: 560px;} 102 | .span-16 { width: 598px;} 103 | .span-17 { width: 636px;} 104 | .span-18 { width: 674px;} 105 | .span-19 { width: 712px;} 106 | .span-20 { width: 750px;} 107 | .span-21, div.span-21 { width: 788px; margin: 0; } 108 | 109 | .append-1 { padding-right: 38px;} 110 | .append-2 { padding-right: 76px;} 111 | .append-3 { padding-right: 114px;} 112 | .append-4 { padding-right: 152px;} 113 | .append-5 { padding-right: 190px;} 114 | .append-6 { padding-right: 228px;} 115 | .append-7 { padding-right: 266px;} 116 | .append-8 { padding-right: 304px;} 117 | .append-9 { padding-right: 342px;} 118 | .append-10 { padding-right: 380px;} 119 | .append-11 { padding-right: 418px;} 120 | .append-12 { padding-right: 456px;} 121 | .append-13 { padding-right: 494px;} 122 | .append-14 { padding-right: 532px;} 123 | .append-15 { padding-right: 570px;} 124 | .append-16 { padding-right: 608px;} 125 | .append-17 { padding-right: 646px;} 126 | .append-18 { padding-right: 684px;} 127 | .append-19 { padding-right: 722px;} 128 | .append-20 { padding-right: 760px;} 129 | 130 | .prepend-1 { padding-left: 38px;} 131 | .prepend-2 { padding-left: 76px;} 132 | .prepend-3 { padding-left: 114px;} 133 | .prepend-4 { padding-left: 152px;} 134 | .prepend-5 { padding-left: 190px;} 135 | .prepend-6 { padding-left: 228px;} 136 | .prepend-7 { padding-left: 266px;} 137 | .prepend-8 { padding-left: 304px;} 138 | .prepend-9 { padding-left: 342px;} 139 | .prepend-10 { padding-left: 380px;} 140 | .prepend-11 { padding-left: 418px;} 141 | .prepend-12 { padding-left: 456px;} 142 | .prepend-13 { padding-left: 494px;} 143 | .prepend-14 { padding-left: 532px;} 144 | .prepend-15 { padding-left: 570px;} 145 | .prepend-16 { padding-left: 608px;} 146 | .prepend-17 { padding-left: 646px;} 147 | .prepend-18 { padding-left: 684px;} 148 | .prepend-19 { padding-left: 722px;} 149 | .prepend-20 { padding-left: 760px;} 150 | 151 | div.border{padding-right:4px;margin-right:5px;border-right:1px solid #eee;} 152 | div.colborder { padding-right:24px;margin-right:23px;border-right:1px solid #eee;} 153 | .pull-1 { margin-left: -38px;} 154 | .pull-2 { margin-left: -76px;} 155 | .pull-3 { margin-left: -114px;} 156 | .pull-4 { margin-left: -152px;} 157 | .pull-5 { margin-left: -190px;} 158 | .pull-6 { margin-left: -228px;} 159 | .pull-7 { margin-left: -266px;} 160 | .pull-8 { margin-left: -304px;} 161 | .pull-9 { margin-left: -342px;} 162 | .pull-10 { margin-left: -380px;} 163 | .pull-11 { margin-left: -418px;} 164 | .pull-12 { margin-left: -456px;} 165 | .pull-13 { margin-left: -494px;} 166 | .pull-14 { margin-left: -532px;} 167 | .pull-15 { margin-left: -570px;} 168 | .pull-16 { margin-left: -608px;} 169 | .pull-17 { margin-left: -646px;} 170 | .pull-18 { margin-left: -684px;} 171 | .pull-19 { margin-left: -722px;} 172 | .pull-20 { margin-left: -760px;} 173 | .pull-21 { margin-left: -798px;} 174 | 175 | .pull-1, .pull-2, .pull-3, .pull-4, .pull-5, .pull-6, .pull-7, .pull-8, .pull-9, .pull-10, .pull-11, .pull-12, .pull-13, .pull-14, .pull-15, .pull-16, .pull-17, .pull-18, .pull-19, .pull-20, .pull-21 {float:left;position:relative;} 176 | 177 | .push-1 { margin: 0 -38px 1.5em 38px;} 178 | .push-2 { margin: 0 -76px 1.5em 76px;} 179 | .push-3 { margin: 0 -114px 1.5em 114px;} 180 | .push-4 { margin: 0 -152px 1.5em 152px;} 181 | .push-5 { margin: 0 -190px 1.5em 190px;} 182 | .push-6 { margin: 0 -228px 1.5em 228px;} 183 | .push-7 { margin: 0 -266px 1.5em 266px;} 184 | .push-8 { margin: 0 -304px 1.5em 304px;} 185 | .push-9 { margin: 0 -342px 1.5em 342px;} 186 | .push-10 { margin: 0 -380px 1.5em 380px;} 187 | .push-11 { margin: 0 -418px 1.5em 418px;} 188 | .push-12 { margin: 0 -456px 1.5em 456px;} 189 | .push-13 { margin: 0 -494px 1.5em 494px;} 190 | .push-14 { margin: 0 -532px 1.5em 532px;} 191 | .push-15 { margin: 0 -570px 1.5em 570px;} 192 | .push-16 { margin: 0 -608px 1.5em 608px;} 193 | .push-17 { margin: 0 -646px 1.5em 646px;} 194 | .push-18 { margin: 0 -684px 1.5em 684px;} 195 | .push-19 { margin: 0 -722px 1.5em 722px;} 196 | .push-20 { margin: 0 -760px 1.5em 760px;} 197 | .push-21 { margin: 0 -798px 1.5em 798px;} 198 | 199 | .push-1, .push-2, .push-3, .push-4, .push-5, .push-6, .push-7, .push-8, .push-9, .push-10, .push-11, .push-12, .push-13, .push-14, .push-15, .push-16, .push-17, .push-18, .push-19, .push-20, .push-21 {float:right;position:relative;} 200 | 201 | .box {padding:1.5em;margin-bottom:1.5em;background:#E5ECF9;} 202 | hr {background:#ddd;color:#ddd;clear:both;float:none;width:100%;height:.1em;margin:0 0 1.45em;border:none;} 203 | hr.space {background:#fff;color:#fff;} 204 | .clearfix:after, .container:after {content:".";display:block;height:0;clear:both;visibility:hidden;} 205 | .clearfix, .container {display:inline-block;} 206 | * html .clearfix, * html .container {height:1%;} 207 | .clearfix, .container {display:block;} 208 | .clear {clear:both;} 209 | 210 | /* forms.css */ 211 | label {font-weight:bold;} 212 | fieldset {padding:1.4em;margin:0 0 1.5em 0;border:1px solid #ccc;} 213 | legend {font-weight:bold;font-size:1.2em;} 214 | input.text, input.title, textarea, select {margin:0.5em 0;border:1px solid #bbb;} 215 | input.text:focus, input.title:focus, textarea:focus, select:focus {border:1px solid #666;} 216 | input.text, input.title {width:300px;padding:5px;} 217 | input.title {font-size:1.5em;} 218 | textarea {width:390px;height:250px;padding:5px;} 219 | .error, .notice, .success {padding:.8em;margin-bottom:1em;border:2px solid #ddd;} 220 | .error {background:#FBE3E4;color:#8a1f11;border-color:#FBC2C4;} 221 | .notice {background:#FFF6BF;color:#514721;border-color:#FFD324;} 222 | .success {background:#E6EFC2;color:#264409;border-color:#C6D880;} 223 | .error a {color:#8a1f11;} 224 | .notice a {color:#514721;} 225 | .success a {color:#264409;} -------------------------------------------------------------------------------- /assets/blueprint/src/forms.css: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------------------------- 2 | 3 | forms.css 4 | * Sets up some default styling for forms 5 | * Gives you classes to enhance your forms 6 | 7 | Usage: 8 | * For text fields, use class .title or .text 9 | 10 | -------------------------------------------------------------- */ 11 | 12 | label { font-weight: bold; } 13 | fieldset { padding:1.4em; margin: 0 0 1.5em 0; border: 1px solid #ccc; } 14 | legend { font-weight: bold; font-size:1.2em; } 15 | 16 | 17 | /* Form fields 18 | -------------------------------------------------------------- */ 19 | 20 | input.text, input.title, 21 | textarea, select { 22 | margin:0.5em 0; 23 | border:1px solid #bbb; 24 | } 25 | 26 | input.text:focus, input.title:focus, 27 | textarea:focus, select:focus { 28 | border:1px solid #666; 29 | } 30 | 31 | input.text, 32 | input.title { width: 300px; padding:5px; } 33 | input.title { font-size:1.5em; } 34 | textarea { width: 390px; height: 250px; padding:5px; } 35 | 36 | 37 | /* Success, notice and error boxes 38 | -------------------------------------------------------------- */ 39 | 40 | .error, 41 | .notice, 42 | .success { padding: .8em; margin-bottom: 1em; border: 2px solid #ddd; } 43 | 44 | .error { background: #FBE3E4; color: #8a1f11; border-color: #FBC2C4; } 45 | .notice { background: #FFF6BF; color: #514721; border-color: #FFD324; } 46 | .success { background: #E6EFC2; color: #264409; border-color: #C6D880; } 47 | .error a { color: #8a1f11; } 48 | .notice a { color: #514721; } 49 | .success a { color: #264409; } 50 | -------------------------------------------------------------------------------- /assets/blueprint/src/grid.css: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------------------------- 2 | 3 | BLUEPRINT CSS 4 | * Filename: grid.css 5 | * Version: 0.7.1 (2008-02-25) YYYY-MM-DD 6 | * Website: http://code.google.com/p/blueprintcss/ 7 | 8 | Generated by: 9 | * Blueprint CSS Grid Generator (2008-07-23) [http://kematzy.com/blueprint-generator/] 10 | 11 | Based on work by: 12 | * Olav Bjorkoy [bjorkoy.com] 13 | * Nathan Borror [playgroundblues.com] 14 | * Jeff Croft [jeffcroft.com] 15 | * Christian Metts [mintchaos.com] 16 | * Khoi Vinh [subtraction.com] 17 | 18 | == STRUCTURE: ======================== 19 | * Page width: 788 px 20 | * Number of columns: 21 21 | * Column width: 28 px 22 | * Margin width: 10 px 23 | ====================================== 24 | 25 | By default, the grid is 788px wide, with 21 columns 26 | spanning 28px, and a 10px margin between columns. 27 | 28 | If you need fewer or more columns, use this formula to calculate 29 | the new total width: 30 | 31 | Total width = (number_of_columns * column_width) - margin_width 32 | 33 | Read more about using a grid here: 34 | * subtraction.com/archives/2007/0318_oh_yeeaahh.php 35 | 36 | -------------------------------------------------------------- */ 37 | 38 | /* A container should group all your columns. */ 39 | .container { 40 | width: 788px; 41 | margin: 0 auto; 42 | } 43 | 44 | /* Use this class on any div.span / container to see the grid. */ 45 | .showgrid { 46 | background: url(src/grid.png); 47 | } 48 | 49 | /* Body margin for a sensile default look. */ 50 | body { 51 | margin:1.5em 0; 52 | } 53 | 54 | 55 | /* Columns 56 | -------------------------------------------------------------- */ 57 | 58 | /* Sets up basic grid floating and margin. */ 59 | div.span-1, div.span-2, div.span-3, div.span-4, div.span-5, div.span-6, div.span-7, div.span-8, div.span-9, div.span-10, div.span-11, div.span-12, div.span-13, div.span-14, div.span-15, div.span-16, div.span-17, div.span-18, div.span-19, div.span-20, div.span-21 {float:left;margin-right: 10px;} 60 | 61 | /* The last column in a row needs this class. */ 62 | div.last { margin-right: 0; } 63 | 64 | /* Use these classes to set the width of a column. */ 65 | .span-1 { width: 28px;} 66 | .span-2 { width: 66px;} 67 | .span-3 { width: 104px;} 68 | .span-4 { width: 142px;} 69 | .span-5 { width: 180px;} 70 | .span-6 { width: 218px;} 71 | .span-7 { width: 256px;} 72 | .span-8 { width: 294px;} 73 | .span-9 { width: 332px;} 74 | .span-10 { width: 370px;} 75 | .span-11 { width: 408px;} 76 | .span-12 { width: 446px;} 77 | .span-13 { width: 484px;} 78 | .span-14 { width: 522px;} 79 | .span-15 { width: 560px;} 80 | .span-16 { width: 598px;} 81 | .span-17 { width: 636px;} 82 | .span-18 { width: 674px;} 83 | .span-19 { width: 712px;} 84 | .span-20 { width: 750px;} 85 | .span-21, div.span-21 { width: 788px; margin: 0; } 86 | 87 | 88 | /* Add these to a column to append empty cols. */ 89 | .append-1 { padding-right: 38px;} 90 | .append-2 { padding-right: 76px;} 91 | .append-3 { padding-right: 114px;} 92 | .append-4 { padding-right: 152px;} 93 | .append-5 { padding-right: 190px;} 94 | .append-6 { padding-right: 228px;} 95 | .append-7 { padding-right: 266px;} 96 | .append-8 { padding-right: 304px;} 97 | .append-9 { padding-right: 342px;} 98 | .append-10 { padding-right: 380px;} 99 | .append-11 { padding-right: 418px;} 100 | .append-12 { padding-right: 456px;} 101 | .append-13 { padding-right: 494px;} 102 | .append-14 { padding-right: 532px;} 103 | .append-15 { padding-right: 570px;} 104 | .append-16 { padding-right: 608px;} 105 | .append-17 { padding-right: 646px;} 106 | .append-18 { padding-right: 684px;} 107 | .append-19 { padding-right: 722px;} 108 | .append-20 { padding-right: 760px;} 109 | 110 | 111 | /* Add these to a column to prepend empty cols. */ 112 | .prepend-1 { padding-left: 38px;} 113 | .prepend-2 { padding-left: 76px;} 114 | .prepend-3 { padding-left: 114px;} 115 | .prepend-4 { padding-left: 152px;} 116 | .prepend-5 { padding-left: 190px;} 117 | .prepend-6 { padding-left: 228px;} 118 | .prepend-7 { padding-left: 266px;} 119 | .prepend-8 { padding-left: 304px;} 120 | .prepend-9 { padding-left: 342px;} 121 | .prepend-10 { padding-left: 380px;} 122 | .prepend-11 { padding-left: 418px;} 123 | .prepend-12 { padding-left: 456px;} 124 | .prepend-13 { padding-left: 494px;} 125 | .prepend-14 { padding-left: 532px;} 126 | .prepend-15 { padding-left: 570px;} 127 | .prepend-16 { padding-left: 608px;} 128 | .prepend-17 { padding-left: 646px;} 129 | .prepend-18 { padding-left: 684px;} 130 | .prepend-19 { padding-left: 722px;} 131 | .prepend-20 { padding-left: 760px;} 132 | 133 | 134 | 135 | /* Border on right hand side of a column. */ 136 | div.border { 137 | padding-right:4px; 138 | margin-right:5px; 139 | border-right: 1px solid #eee; 140 | } 141 | 142 | /* Border with more whitespace, spans one column. */ 143 | div.colborder { 144 | padding-right:26px; 145 | margin-right:23px; 146 | border-right: 1px solid #eee; 147 | } 148 | 149 | /* Use these classes on an element to push it into the 150 | next column, or to pull it into the previous column. */ 151 | 152 | .pull-1 { margin-left: -38px;} 153 | .pull-2 { margin-left: -76px;} 154 | .pull-3 { margin-left: -114px;} 155 | .pull-4 { margin-left: -152px;} 156 | .pull-5 { margin-left: -190px;} 157 | .pull-6 { margin-left: -228px;} 158 | .pull-7 { margin-left: -266px;} 159 | .pull-8 { margin-left: -304px;} 160 | .pull-9 { margin-left: -342px;} 161 | .pull-10 { margin-left: -380px;} 162 | .pull-11 { margin-left: -418px;} 163 | .pull-12 { margin-left: -456px;} 164 | .pull-13 { margin-left: -494px;} 165 | .pull-14 { margin-left: -532px;} 166 | .pull-15 { margin-left: -570px;} 167 | .pull-16 { margin-left: -608px;} 168 | .pull-17 { margin-left: -646px;} 169 | .pull-18 { margin-left: -684px;} 170 | .pull-19 { margin-left: -722px;} 171 | .pull-20 { margin-left: -760px;} 172 | .pull-21 { margin-left: -798px;} 173 | 174 | .pull-1, .pull-2, .pull-3, .pull-4, .pull-5, .pull-6, .pull-7, .pull-8, .pull-9, .pull-10, .pull-11, .pull-12, .pull-13, .pull-14, .pull-15, .pull-16, .pull-17, .pull-18, .pull-19, .pull-20, .pull-21 {float:left;position:relative;} 175 | 176 | 177 | .push-1 { margin: 0 -38px 1.5em 38px;} 178 | .push-2 { margin: 0 -76px 1.5em 76px;} 179 | .push-3 { margin: 0 -114px 1.5em 114px;} 180 | .push-4 { margin: 0 -152px 1.5em 152px;} 181 | .push-5 { margin: 0 -190px 1.5em 190px;} 182 | .push-6 { margin: 0 -228px 1.5em 228px;} 183 | .push-7 { margin: 0 -266px 1.5em 266px;} 184 | .push-8 { margin: 0 -304px 1.5em 304px;} 185 | .push-9 { margin: 0 -342px 1.5em 342px;} 186 | .push-10 { margin: 0 -380px 1.5em 380px;} 187 | .push-11 { margin: 0 -418px 1.5em 418px;} 188 | .push-12 { margin: 0 -456px 1.5em 456px;} 189 | .push-13 { margin: 0 -494px 1.5em 494px;} 190 | .push-14 { margin: 0 -532px 1.5em 532px;} 191 | .push-15 { margin: 0 -570px 1.5em 570px;} 192 | .push-16 { margin: 0 -608px 1.5em 608px;} 193 | .push-17 { margin: 0 -646px 1.5em 646px;} 194 | .push-18 { margin: 0 -684px 1.5em 684px;} 195 | .push-19 { margin: 0 -722px 1.5em 722px;} 196 | .push-20 { margin: 0 -760px 1.5em 760px;} 197 | .push-21 { margin: 0 -798px 1.5em 798px;} 198 | 199 | .push-1, .push-2, .push-3, .push-4, .push-5, .push-6, .push-7, .push-8, .push-9, .push-10, .push-11, .push-12, .push-13, .push-14, .push-15, .push-16, .push-17, .push-18, .push-19, .push-20, .push-21 {float:right;position:relative;} 200 | 201 | 202 | 203 | /* Misc classes and elements 204 | -------------------------------------------------------------- */ 205 | 206 | /* Use a .box to create a padded box inside a column. */ 207 | .box { 208 | padding: 1.5em; 209 | margin-bottom: 1.5em; 210 | background: #E5ECF9; 211 | } 212 | 213 | /* Use this to create a horizontal ruler across a column. */ 214 | hr { 215 | background: #ddd; 216 | color: #ddd; 217 | clear: both; 218 | float: none; 219 | width: 100%; 220 | height: .1em; 221 | margin: 0 0 1.45em; 222 | border: none; 223 | } 224 | hr.space { 225 | background: #fff; 226 | color: #fff; 227 | } 228 | 229 | 230 | /* Clearing floats without extra markup 231 | Based on How To Clear Floats Without Structural Markup by PiE 232 | [http://www.positioniseverything.net/easyclearing.html] */ 233 | 234 | .clearfix:after, .container:after { 235 | content: "."; 236 | display: block; 237 | height: 0; 238 | clear: both; 239 | visibility: hidden; 240 | } 241 | .clearfix, .container {display: inline-block;} 242 | * html .clearfix, 243 | * html .container {height: 1%;} 244 | .clearfix, .container {display: block;} 245 | 246 | /* Regular clearing 247 | apply to column that should drop below previous ones. */ 248 | 249 | .clear { clear:both; } 250 | 251 | -------------------------------------------------------------------------------- /assets/blueprint/src/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/blueprint/src/grid.png -------------------------------------------------------------------------------- /assets/blueprint/src/ie.css: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------------------------- 2 | 3 | ie.css 4 | 5 | Contains every hack for Internet Explorer, 6 | so that our core files stay sweet and nimble. 7 | 8 | -------------------------------------------------------------- */ 9 | 10 | /* Make sure the layout is centered in IE5 */ 11 | body { text-align: center; } 12 | .container { text-align: left; } 13 | 14 | /* Fixes IE margin bugs */ 15 | * html .column { overflow-x: hidden; } 16 | 17 | 18 | /* Elements 19 | -------------------------------------------------------------- */ 20 | 21 | /* Fixes incorrect styling of legend in IE6. */ 22 | * html legend { margin:-18px -8px 16px 0; padding:0; } 23 | 24 | /* Fixes incorrect placement of ol numbers in IE6/7. */ 25 | ol { margin-left:2em; } 26 | 27 | /* Fixes wrong line-height on sup/sub in IE. */ 28 | sup { vertical-align: text-top; } 29 | sub { vertical-align: text-bottom; } 30 | 31 | /* Fixes IE7 missing wrapping of code elements. */ 32 | html>body p code { *white-space: normal; } 33 | 34 | /* IE 6&7 has problems with setting proper
,. */ 34 | blockquote:before, blockquote:after, q:before, q:after { content: ""; } 35 | blockquote, q { quotes: "" ""; } 36 | 37 | /* Remove annoying border on linked images. */ 38 | a img { border: none; } 39 | -------------------------------------------------------------------------------- /assets/blueprint/src/typography.css: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------------------------- 2 | 3 | typography.css 4 | * Sets up some sensible default typography. 5 | 6 | -------------------------------------------------------------- */ 7 | 8 | /* Default font settings. 9 | The font-size percentage is of 16px. (0.75 * 16px = 12px) */ 10 | body { 11 | font-size: 75%; 12 | color: #222; 13 | background: #fff; 14 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 15 | } 16 | 17 | 18 | /* Headings 19 | -------------------------------------------------------------- */ 20 | 21 | h1,h2,h3,h4,h5,h6 { font-weight: normal; color: #111; } 22 | 23 | h1 { font-size: 3em; line-height: 1; margin-bottom: 0.5em; } 24 | h2 { font-size: 2em; margin-bottom: 0.75em; } 25 | h3 { font-size: 1.5em; line-height: 1; margin-bottom: 1em; } 26 | h4 { font-size: 1.2em; line-height: 1.25; margin-bottom: 1.25em; height: 1.25em; } 27 | h5 { font-size: 1em; font-weight: bold; margin-bottom: 1.5em; } 28 | h6 { font-size: 1em; font-weight: bold; } 29 | 30 | h1 img, h2 img, h3 img, 31 | h4 img, h5 img, h6 img { 32 | margin: 0; 33 | } 34 | 35 | 36 | /* Text elements 37 | -------------------------------------------------------------- */ 38 | 39 | p { margin: 0 0 1.5em; } 40 | p img { float: left; margin: 1.5em 1.5em 1.5em 0; padding: 0; } 41 | p img.right { float: right; margin: 1.5em 0 1.5em 1.5em; } 42 | 43 | a:focus, 44 | a:hover { color: #000; } 45 | a { color: #009; text-decoration: underline; } 46 | 47 | blockquote { margin: 1.5em; color: #666; font-style: italic; } 48 | strong { font-weight: bold; } 49 | em,dfn { font-style: italic; } 50 | dfn { font-weight: bold; } 51 | sup, sub { line-height: 0; } 52 | 53 | abbr, 54 | acronym { border-bottom: 1px dotted #666; } 55 | address { margin: 0 0 1.5em; font-style: italic; } 56 | del { color:#666; } 57 | 58 | pre,code { margin: 1.5em 0; white-space: pre; } 59 | pre,code,tt { font: 1em 'andale mono', 'lucida console', monospace; line-height: 1.5; } 60 | 61 | 62 | /* Lists 63 | -------------------------------------------------------------- */ 64 | 65 | li ul, 66 | li ol { margin:0 1.5em; } 67 | ul, ol { margin: 0 1.5em 1.5em 1.5em; } 68 | 69 | ul { list-style-type: disc; } 70 | ol { list-style-type: decimal; } 71 | 72 | dl { margin: 0 0 1.5em 0; } 73 | dl dt { font-weight: bold; } 74 | dd { margin-left: 1.5em;} 75 | 76 | 77 | /* Tables 78 | -------------------------------------------------------------- */ 79 | 80 | table { margin-bottom: 1.4em; width:100%; } 81 | th { font-weight: bold; background: #C3D9FF; } 82 | th,td { padding: 4px 10px 4px 5px; } 83 | tr.even td { background: #E5ECF9; } 84 | tfoot { font-style: italic; } 85 | caption { background: #eee; } 86 | 87 | 88 | /* Misc classes 89 | -------------------------------------------------------------- */ 90 | 91 | .small { font-size: .8em; margin-bottom: 1.875em; line-height: 1.875em; } 92 | .large { font-size: 1.2em; line-height: 2.5em; margin-bottom: 1.25em; } 93 | .hide { display: none; } 94 | 95 | .quiet { color: #666; } 96 | .loud { color: #000; } 97 | .highlight { background:#ff0; } 98 | .added { background:#060; color: #fff; } 99 | .removed { background:#900; color: #fff; } 100 | 101 | .first { margin-left:0; padding-left:0; } 102 | .last { margin-right:0; padding-right:0; } 103 | .top { margin-top:0; padding-top:0; } 104 | .bottom { margin-bottom:0; padding-bottom:0; } 105 | -------------------------------------------------------------------------------- /assets/images/figure/model-dag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/figure/model-dag.png -------------------------------------------------------------------------------- /assets/images/figure/model-real.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/figure/model-real.png -------------------------------------------------------------------------------- /assets/images/figure/object-blob.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/figure/object-blob.png -------------------------------------------------------------------------------- /assets/images/figure/object-commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/figure/object-commit.png -------------------------------------------------------------------------------- /assets/images/figure/object-tag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/figure/object-tag.png -------------------------------------------------------------------------------- /assets/images/figure/object-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/figure/object-tree.png -------------------------------------------------------------------------------- /assets/images/figure/object_types.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/figure/object_types.png -------------------------------------------------------------------------------- /assets/images/figure/objects-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/figure/objects-example.png -------------------------------------------------------------------------------- /assets/images/figure/pack-index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/figure/pack-index.png -------------------------------------------------------------------------------- /assets/images/figure/packfile-format.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/figure/packfile-format.png -------------------------------------------------------------------------------- /assets/images/figure/packfile-index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/figure/packfile-index.png -------------------------------------------------------------------------------- /assets/images/figure/packfile-logic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/figure/packfile-logic.png -------------------------------------------------------------------------------- /assets/images/figure/rebase0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/figure/rebase0.png -------------------------------------------------------------------------------- /assets/images/figure/rebase1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/figure/rebase1.png -------------------------------------------------------------------------------- /assets/images/figure/rebase2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/figure/rebase2.png -------------------------------------------------------------------------------- /assets/images/figure/rebase3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/figure/rebase3.png -------------------------------------------------------------------------------- /assets/images/figure/rebase4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/figure/rebase4.png -------------------------------------------------------------------------------- /assets/images/figure/rebase5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/figure/rebase5.png -------------------------------------------------------------------------------- /assets/images/git-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/git-logo.png -------------------------------------------------------------------------------- /assets/images/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/github.png -------------------------------------------------------------------------------- /assets/images/header-book.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/header-book.gif -------------------------------------------------------------------------------- /assets/images/pdf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/pdf.png -------------------------------------------------------------------------------- /assets/images/tar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/tar.png -------------------------------------------------------------------------------- /assets/images/zip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/assets/images/zip.png -------------------------------------------------------------------------------- /assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // Place your application-specific JavaScript functions and classes here 2 | // This file is automatically included by javascript_include_tag :defaults 3 | -------------------------------------------------------------------------------- /assets/stylesheets/mac_classic.css: -------------------------------------------------------------------------------- 1 | pre.mac_classic .EmbeddedSource { 2 | background-color: #0C0C0C; 3 | } 4 | pre.mac_classic .LibraryObject { 5 | font-weight: bold; 6 | color: #6D79DE; 7 | } 8 | pre.mac_classic .Section { 9 | font-style: italic; 10 | } 11 | pre.mac_classic .FunctionArgumentAndResultTypes { 12 | color: #70727E; 13 | } 14 | pre.mac_classic .TypeName { 15 | text-decoration: underline; 16 | } 17 | pre.mac_classic .Number { 18 | color: #0000CD; 19 | } 20 | pre.mac_classic { 21 | background-color: #FFFFFF; 22 | color: #000000; 23 | } 24 | pre.mac_classic .MarkupList { 25 | color: #B90690; 26 | } 27 | pre.mac_classic .MarkupTagAttribute { 28 | font-style: italic; 29 | } 30 | pre.mac_classic .LibraryVariable { 31 | font-weight: bold; 32 | color: #21439C; 33 | } 34 | pre.mac_classic .line-numbers { 35 | background-color: #4D97FF; 36 | color: #000000; 37 | } 38 | pre.mac_classic .FunctionParameter { 39 | font-style: italic; 40 | } 41 | pre.mac_classic .MarkupTag { 42 | color: #1C02FF; 43 | } 44 | pre.mac_classic .MarkupHeading { 45 | font-weight: bold; 46 | color: #0C07FF; 47 | } 48 | pre.mac_classic .JsOperator { 49 | color: #687687; 50 | } 51 | pre.mac_classic .InheritedClassName { 52 | font-style: italic; 53 | } 54 | pre.mac_classic .StringInterpolation { 55 | color: #26B31A; 56 | } 57 | pre.mac_classic .MarkupQuote { 58 | color: #000000; 59 | font-style: italic; 60 | } 61 | pre.mac_classic .MarkupNameOfTag { 62 | font-weight: bold; 63 | } 64 | pre.mac_classic .InvalidTrailingWhitespace { 65 | background-color: #FFD0D0; 66 | } 67 | pre.mac_classic .LibraryConstant { 68 | font-weight: bold; 69 | color: #06960E; 70 | } 71 | pre.mac_classic .MarkupXmlDeclaration { 72 | color: #68685B; 73 | } 74 | pre.mac_classic .EmbeddedEmbeddedSource { 75 | background-color: #0E0E0E; 76 | } 77 | pre.mac_classic .PreprocessorDirective { 78 | font-weight: bold; 79 | color: #0C450D; 80 | } 81 | pre.mac_classic .BuiltInConstant { 82 | font-weight: bold; 83 | color: #585CF6; 84 | } 85 | pre.mac_classic .MarkupDtd { 86 | font-style: italic; 87 | } 88 | pre.mac_classic .Invalid { 89 | background-color: #990000; 90 | color: #FFFFFF; 91 | } 92 | pre.mac_classic .LibraryFunction { 93 | font-weight: bold; 94 | color: #3C4C72; 95 | } 96 | pre.mac_classic .String { 97 | color: #036A07; 98 | } 99 | pre.mac_classic .UserDefinedConstant { 100 | font-weight: bold; 101 | color: #C5060B; 102 | } 103 | pre.mac_classic .Keyword { 104 | font-weight: bold; 105 | color: #0000FF; 106 | } 107 | pre.mac_classic .MarkupDoctype { 108 | color: #888888; 109 | } 110 | pre.mac_classic .FunctionName { 111 | font-weight: bold; 112 | color: #0000A2; 113 | } 114 | pre.mac_classic .PreprocessorLine { 115 | color: #1A921C; 116 | } 117 | pre.mac_classic .Variable { 118 | color: #318495; 119 | } 120 | pre.mac_classic .Comment { 121 | color: #0066FF; 122 | font-style: italic; 123 | } 124 | -------------------------------------------------------------------------------- /assets/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | /* COLOR SCHEME 2 | base: #FFE9B7 3 | darker: #E3D185 4 | green: #9AB54F 5 | red: #6E212E 6 | lred: #B5463F 7 | */ 8 | 9 | body { 10 | background:#fff; 11 | color: #333; 12 | } 13 | a { color: #6E212E; } 14 | .center { text-align: center; } 15 | .pad { padding: 5px; } 16 | .chapter img { display: block; } 17 | 18 | #toc { padding: 10px; font-size: 120%; } 19 | #toc ul { display: inline; } 20 | #toc ul li { display: inline; margin-left: 20px; margin-right: 20px;} 21 | #toc ul li a { color: #240; } 22 | 23 | .chapter { font-size: 120%; } 24 | .chapter .header { background: #9AB54F; padding: 5px; } 25 | .chapter .header .title a { color: #fff; text-align: left; font-weight: bold; font-size: 120%;} 26 | .chapter .header .nav { float: right } 27 | .chapter .header .nav a { color: #fff; } 28 | 29 | ul.a-index li#m-index a, ul.a-about li#m-about a, 30 | ul.a-documentation li#m-documentation a, ul.a-download li#m-download a, 31 | ul.a-tools li#m-tools a { font-weight: bold; color: #fff; text-decoration: none;} 32 | 33 | ul#about-list li { padding: 5px; } 34 | ul#about-list li b { color: #6E212E; } 35 | 36 | .header h1 { text-align: center; } 37 | .navbar { text-align: center; background: #9AB54F;} 38 | .footer { text-align: center; background: #E3D185;} 39 | .menu { padding: 10px; } 40 | 41 | h2.section-start { text-align:center; background: #9AB54F; color: #240; } 42 | h3.title { background: #eee; padding: 5px;} 43 | 44 | .inner { background: #eee; padding: 5px 10px;} 45 | .inner p { margin: 10px 0; } 46 | 47 | .example { background: #eee; padding: 10px; } 48 | img.book { border: 1px solid #666; } 49 | 50 | #book-intro { padding: 10px; margin-bottom: 15px; background: #FFE9B7;} 51 | #book-intro h3 { color: #630; font-size: 200%; font-weight: bold;} 52 | 53 | #download { padding: 10px; background: #9AB54F; text-align:center; } 54 | #download h3 { color: #efe; font-size: 150%; font-weight: bold; text-align: center;} 55 | #download .inner { background: #efe; padding: 5px 10px;} 56 | 57 | #new-to-git { padding: 10px; padding-bottom:15px; background: #B5463F; } 58 | #new-to-git h3 { color: #fee; font-size: 150%; font-weight: bold; text-align: center;} 59 | #new-to-git h3 small { color: #eee; font-weight: normal; font-size: 70%;} 60 | 61 | a.chapter-link { font-size: 120%; } 62 | a.todo { color: #888 !important; } 63 | 64 | table tr td { vertical-align: top;} 65 | 66 | table.data-table tr td { vertical-align: top;} 67 | table.data-table tr td h3 { background: #B5463F; color: #fff; padding: 5px; } 68 | 69 | pre { background: #eee !important; padding: 5px;} 70 | .gitcast { padding: 20px; background: #FFE9B7; border: 1px solid #E3D185; text-align: center;} -------------------------------------------------------------------------------- /layout/book_index_template.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 |Git Community Book 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |19 | 20 | 23 | 24 | 36 | 37 |99 | 100 | 108 | 112 | 113 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /layout/chapter_template.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 |38 |40 | 41 |
39 |42 |56 | 57 | 58 |43 |55 |The Git Community Book
44 |45 | Welcome to the Git Community Book. 46 | This book has been built by dozens of people in the Git community, and 47 | is meant to help you learn how to use Git as quickly and easily as possible. 48 |
49 |50 | If you see anything out of date, have a suggestion on how to improve it, 51 | or would like to help add to the book, 52 | please see the How to Contribute page, or just send 53 | our maintainer a note. 54 |
59 |68 | 69 |60 |67 |Download
61 | 66 |70 |81 | 82 |71 |80 |New to Git?
72 |73 |79 |If you want to really understand Git, 74 | You may want to start at the beginning.
75 |76 | If you just want to jump right in, you can skip right to setting it up. 77 |
78 |83 | #body 84 |85 | 86 | 94 | 97 | 98 |Git Book - #title 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |18 | 19 |51 | 52 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /layout/mac_classic.css: -------------------------------------------------------------------------------- 1 | pre.mac_classic .EmbeddedSource { 2 | background-color: #0C0C0C; 3 | } 4 | pre.mac_classic .LibraryObject { 5 | font-weight: bold; 6 | color: #6D79DE; 7 | } 8 | pre.mac_classic .Section { 9 | font-style: italic; 10 | } 11 | pre.mac_classic .FunctionArgumentAndResultTypes { 12 | color: #70727E; 13 | } 14 | pre.mac_classic .TypeName { 15 | text-decoration: underline; 16 | } 17 | pre.mac_classic .Number { 18 | color: #0000CD; 19 | } 20 | pre.mac_classic { 21 | background-color: #FFFFFF; 22 | color: #000000; 23 | } 24 | pre.mac_classic .MarkupList { 25 | color: #B90690; 26 | } 27 | pre.mac_classic .MarkupTagAttribute { 28 | font-style: italic; 29 | } 30 | pre.mac_classic .LibraryVariable { 31 | font-weight: bold; 32 | color: #21439C; 33 | } 34 | pre.mac_classic .line-numbers { 35 | background-color: #4D97FF; 36 | color: #000000; 37 | } 38 | pre.mac_classic .FunctionParameter { 39 | font-style: italic; 40 | } 41 | pre.mac_classic .MarkupTag { 42 | color: #1C02FF; 43 | } 44 | pre.mac_classic .MarkupHeading { 45 | font-weight: bold; 46 | color: #0C07FF; 47 | } 48 | pre.mac_classic .JsOperator { 49 | color: #687687; 50 | } 51 | pre.mac_classic .InheritedClassName { 52 | font-style: italic; 53 | } 54 | pre.mac_classic .StringInterpolation { 55 | color: #26B31A; 56 | } 57 | pre.mac_classic .MarkupQuote { 58 | color: #000000; 59 | font-style: italic; 60 | } 61 | pre.mac_classic .MarkupNameOfTag { 62 | font-weight: bold; 63 | } 64 | pre.mac_classic .InvalidTrailingWhitespace { 65 | background-color: #FFD0D0; 66 | } 67 | pre.mac_classic .LibraryConstant { 68 | font-weight: bold; 69 | color: #06960E; 70 | } 71 | pre.mac_classic .MarkupXmlDeclaration { 72 | color: #68685B; 73 | } 74 | pre.mac_classic .EmbeddedEmbeddedSource { 75 | background-color: #0E0E0E; 76 | } 77 | pre.mac_classic .PreprocessorDirective { 78 | font-weight: bold; 79 | color: #0C450D; 80 | } 81 | pre.mac_classic .BuiltInConstant { 82 | font-weight: bold; 83 | color: #585CF6; 84 | } 85 | pre.mac_classic .MarkupDtd { 86 | font-style: italic; 87 | } 88 | pre.mac_classic .Invalid { 89 | background-color: #990000; 90 | color: #FFFFFF; 91 | } 92 | pre.mac_classic .LibraryFunction { 93 | font-weight: bold; 94 | color: #3C4C72; 95 | } 96 | pre.mac_classic .String { 97 | color: #036A07; 98 | } 99 | pre.mac_classic .UserDefinedConstant { 100 | font-weight: bold; 101 | color: #C5060B; 102 | } 103 | pre.mac_classic .Keyword { 104 | font-weight: bold; 105 | color: #0000FF; 106 | } 107 | pre.mac_classic .MarkupDoctype { 108 | color: #888888; 109 | } 110 | pre.mac_classic .FunctionName { 111 | font-weight: bold; 112 | color: #0000A2; 113 | } 114 | pre.mac_classic .PreprocessorLine { 115 | color: #1A921C; 116 | } 117 | pre.mac_classic .Variable { 118 | color: #318495; 119 | } 120 | pre.mac_classic .Comment { 121 | color: #0066FF; 122 | font-style: italic; 123 | } 124 | -------------------------------------------------------------------------------- /layout/pdf_template.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |20 | 22 |23 | 24 | 21 |25 |27 | 28 |
26 |29 | #body 30 |31 | 32 |33 |37 | 38 | 46 | 49 | 50 |
34 |#nav35 |
36 |13 |17 | 18 |Git Community Book
14 | 15 |The open Git resource pulled together by the whole community
16 |19 |76 | 77 |Authors
20 | Thank these guys: 21 |22 | Alecs King (alecsk@gmail.com), 23 | Amos Waterland (apw@rossby.metr.ou.edu), 24 | Andrew Ruder (andy@aeruder.net), 25 | Andy Parkins (andyparkins@gmail.com), 26 | Arjen Laarhoven (arjen@yaph.org), 27 | Brian Hetro (whee@smaertness.net), 28 | Carl Worth (cworth@cworth.org), 29 | Christian Meder (chris@absolutegiganten.org), 30 | Dan McGee (dpmcgee@gmail.com), 31 | David Kastrup (dak@gnu.org), 32 | Dmitry V. Levin (ldv@altlinux.org), 33 | Francis Daly (francis@daoine.org), 34 | Gerrit Pape (pape@smarden.org), 35 | Greg Louis (glouis@dynamicro.ca), 36 | Gustaf Hendeby (hendeby@isy.liu.se), 37 | Horst H. von Brand (vonbrand@inf.utfsm.cl), 38 | J. Bruce Fields (bfields@fieldses.org), 39 | Jakub Narebski (jnareb@gmail.com), 40 | Jim Meyering (jim@meyering.net), 41 | Johan Herland (johan@herland.net), 42 | Johannes Schindelin (Johannes.Schindelin@gmx.de), 43 | Jon Loeliger (jdl@freescale.org), 44 | Josh Triplett (josh@freedesktop.org), 45 | Junio C Hamano (gitster@pobox.com), 46 | Linus Torvalds (torvalds@osdl.org), 47 | Lukas Sandström (lukass@etek.chalmers.se), 48 | Marcus Fritzsch (m@fritschy.de), 49 | Michael Coleman (tutufan@gmail.com), 50 | Michael Smith (msmith@cbnco.com), 51 | Mike Coleman (tutufan@gmail.com), 52 | Miklos Vajna (vmiklos@frugalware.org), 53 | Nicolas Pitre (nico@cam.org), 54 | Oliver Steele (steele@osteele.com), 55 | Paolo Ciarrocchi (paolo.ciarrocchi@gmail.com), 56 | Pavel Roskin (proski@gnu.org), 57 | Ralf Wildenhues (Ralf.Wildenhues@gmx.de), 58 | Robin Rosenberg (robin.rosenberg.lists@dewire.com), 59 | Santi Béjar (sbejar@gmail.com), 60 | Scott Chacon (schacon@gmail.com), 61 | Sergei Organov (osv@javad.com), 62 | Shawn Bohrer (shawn.bohrer@gmail.com), 63 | Shawn O. Pearce (spearce@spearce.org), 64 | Steffen Prohaska (prohaska@zib.de), 65 | Tom Prince (tom.prince@ualberta.net), 66 | William Pursell (bill.pursell@gmail.com), 67 | Yasushi SHOJI (yashi@atmark-techno.com) 68 |
69 | 70 |Maintainer / Editor
71 | Bug this guy: 72 |73 | Scott Chacon (schacon@gmail.com) 74 |
75 |78 | #body 79 |80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /output/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/output/.gitignore -------------------------------------------------------------------------------- /script/html.rb: -------------------------------------------------------------------------------- 1 | require 'fileutils' 2 | require 'pp' 3 | require 'rubygems' 4 | require 'builder' 5 | require 'rdiscount' 6 | require "uv" 7 | 8 | #MIN_SIZE = 1200 9 | MIN_SIZE = 800 10 | 11 | def do_replacements(html, type = :html) 12 | 13 | # highlight code 14 | html = html.gsub /ruby.*?<\/code><\/pre>/m do |code| 15 | code = code.gsub('
', '').gsub('<', '<').gsub('>', '>').gsub('&', '&') 16 | Uv.parse(code, "xhtml", "ruby", false, "mac_classic") 17 | end 18 | 19 | # replace gitlinks 20 | html.gsub! /linkgit:(.*?)\[\d\]/ do |code, waa| 21 | "#{$1.gsub('git-', 'git ')}" 22 | end 23 | 24 | # replace figures 25 | html.gsub! /\[fig:(.*?)\]/, 'ruby', '').gsub('
' 26 | 27 | # fix images in pdf 28 | html.gsub!('src="images', 'src="assets/images') 29 | 30 | # replace/remove gitcasts 31 | 32 | html = html.gsub /\[gitcast:.*?\]\(.*?\)/ do |code| 33 | if type == :html 34 | puts code 35 | if match = /gitcast:(.*?)\]\((.*?)\)/.match(code) 36 | cast = match[1].gsub('_', '%2D') 37 | code = '38 | 39 |' 41 | end 42 | else 43 | code = '' 44 | end 45 | code 46 | end 47 | 48 | html 49 | end 50 | 51 | desc 'Create the HTML version' 52 | task :html => :merge do 53 | 54 | if File.exists?('output/full_book.markdown') 55 | output = File.new('output/full_book.markdown').read 56 | output = RDiscount.new(output).to_html 57 | 58 | ## pdf version ## 59 | 60 | # code highlighting 61 | File.open('output/index.html', 'w') do |f| 62 | body = do_replacements(output, :pdf) 63 | 64 | html_template = File.new("layout/pdf_template.html").read 65 | html_template.gsub!("#body", body) 66 | 67 | 68 | f.puts html_template 69 | end 70 | 71 | ## html version ## 72 | 73 | html_dir = 'output/book' 74 | FileUtils.rm_r(html_dir) rescue nil 75 | Dir.mkdir(html_dir) 76 | 77 | # html chapters 78 | links = [] 79 | chapter_files = [] 80 | 81 | count = 0 82 | sections = output.split('
' + match[2] + ' 40 |') 83 | sections.each do |section| 84 | # extract title 85 | title, section = section.split('
') 86 | next if !section 87 | count += 1 88 | title = count.to_s + '. ' + title.strip 89 | puts title 90 | 91 | chlinks = [] 92 | chapters = section.split('') 93 | chapters.shift 94 | chapters.each do |chapter| 95 | chtitle, chapter = chapter.split('
') 96 | next if !chapter 97 | # extract chapter title 98 | puts "\t" + chtitle.strip 99 | filename = count.to_s + '_' + chtitle.strip.downcase.gsub(' ', '_') + '.html' 100 | body = "#{chtitle}
" + chapter 101 | body = do_replacements(body, :html) 102 | chlinks << [chtitle.strip, filename, body.size] 103 | chapter_files << [chtitle.strip, filename, body] 104 | end 105 | links << [title.strip, chlinks] 106 | end 107 | 108 | # writing out the chapter files 109 | chapter_files.each_with_index do |arr, index| 110 | chapter_title, chapter_file, body = arr 111 | File.open(File.join(html_dir, chapter_file), 'w') do |f| 112 | nav = '' 113 | if (cf = chapter_files[index - 1]) && index != 0 114 | nav += "Prev " 115 | end 116 | if cf = chapter_files[index + 1] 117 | nav += " Next" 118 | end 119 | html_template = File.new("layout/chapter_template.html").read 120 | html_template.gsub!("#title", chapter_title) 121 | html_template.gsub!("#body", body) 122 | html_template.gsub!("#nav", nav) 123 | f.puts html_template 124 | end 125 | end 126 | 127 | toc = Builder::XmlMarkup.new(:indent => 1) 128 | toc.table { toc.tr { 129 | toc.td(:valign => "top") { 130 | links[0,4].each do |section_title, section_array| 131 | toc.h3(:class => 'title') { toc << section_title } 132 | toc.table do 133 | section_array.each do |chapter_title, chapter_file, chsize| 134 | toc.tr { toc.td { 135 | (chsize > MIN_SIZE) ? extra = 'done' : extra = 'todo' 136 | toc.a(:href => chapter_file, :class => "chapter-link #{extra}") << chapter_title 137 | }} 138 | end 139 | end 140 | end 141 | } 142 | toc.td(:valign => "top") { 143 | links[4,3].each do |section_title, section_array| 144 | toc.h3(:class => 'title') { toc << section_title } 145 | toc.table do 146 | section_array.each do |chapter_title, chapter_file, chsize| 147 | toc.tr { toc.td { 148 | (chsize > MIN_SIZE) ? extra = 'done' : extra = 'todo' 149 | toc.a(:href => chapter_file, :class => "chapter-link #{extra}") << chapter_title 150 | }} 151 | end 152 | end 153 | end 154 | } 155 | }} 156 | File.open('output/book/index.html', 'w') do |f| 157 | html_template = File.new("layout/book_index_template.html").read 158 | html_template.gsub!("#body", toc.to_s) 159 | f.puts html_template 160 | end 161 | 162 | `cp -Rf assets output/book/` 163 | `cp output/book.pdf output/book/` 164 | 165 | end 166 | end 167 | 168 | -------------------------------------------------------------------------------- /script/local.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'mongrel' 3 | 4 | h = Mongrel::HttpServer.new("0.0.0.0", "4001") 5 | h.register("/", Mongrel::DirHandler.new("output/book")) 6 | h.run.join 7 | -------------------------------------------------------------------------------- /script/merge.rb: -------------------------------------------------------------------------------- 1 | desc 'Merge all of the texttile output into a single file for pdf conversion' 2 | 3 | task :merge do 4 | File.open('output/full_book.markdown', 'w+') do |f| 5 | Dir["text/**/*.markdown"].sort.each do |path| 6 | f << File.new(path).read + "\r\n" 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /script/pdf.rb: -------------------------------------------------------------------------------- 1 | desc 'Cria um arquivo pdf à partir do html gerado' 2 | task :pdf => :html do 3 | prince = Prince.new() 4 | html_string = File.new("output/index.html").read 5 | prince.add_style_sheets 'layout/second.css', 'layout/mac_classic.css' 6 | 7 | File.open('output/book.pdf', 'w') do |f| 8 | f.puts prince.pdf_from_string(html_string) 9 | end 10 | 11 | `open output/book.pdf` 12 | end 13 | -------------------------------------------------------------------------------- /script/prince.rb: -------------------------------------------------------------------------------- 1 | class Prince 2 | 3 | attr_accessor :exe_path, :style_sheets, :log_file 4 | 5 | # Initialize method 6 | # 7 | def initialize() 8 | # Finds where the application lives, so we can call it. 9 | @exe_path = `which prince`.chomp 10 | @style_sheets = '' 11 | @log_file = "log/prince.log" 12 | end 13 | 14 | # Sets stylesheets... 15 | # Can pass in multiple paths for css files. 16 | # 17 | def add_style_sheets(*sheets) 18 | for sheet in sheets do 19 | @style_sheets << " -s #{sheet} " 20 | end 21 | end 22 | 23 | # Returns fully formed executable path with any command line switches 24 | # we've set based on our variables. 25 | # 26 | def exe_path 27 | # Add any standard cmd line arguments we need to pass 28 | @exe_path << " --input=html --server --log=#{@log_file} " 29 | @exe_path << @style_sheets 30 | return @exe_path 31 | end 32 | 33 | # Makes a pdf from a passed in string. 34 | # 35 | # Returns PDF as a stream, so we can use send_data to shoot 36 | # it down the pipe using Rails. 37 | # 38 | def pdf_from_string(string) 39 | puts `pwd` 40 | path = self.exe_path() 41 | # Don't spew errors to the standard out...and set up to take IO 42 | # as input and output 43 | path << ' - -o -' 44 | 45 | # Show the command used... 46 | #logger.info "\n\nPRINCE XML PDF COMMAND" 47 | #logger.info path 48 | #logger.info '' 49 | 50 | # Actually call the prince command, and pass the entire data stream back. 51 | pdf = IO.popen(path, "w+") 52 | pdf.puts(string) 53 | pdf.close_write 54 | output = pdf.gets(nil) 55 | pdf.close_read 56 | return output 57 | end 58 | end -------------------------------------------------------------------------------- /script/publish.rb: -------------------------------------------------------------------------------- 1 | task :publish do 2 | File.open("output/book/CNAME", 'w+') do |f| 3 | f.puts("book.git-scm.com") 4 | end 5 | 6 | ENV['GIT_DIR'] = File.expand_path(`git rev-parse --git-dir`.chomp) 7 | old_sha = `git rev-parse refs/remotes/origin/gh-pages`.chomp 8 | Dir.chdir('output/book') do 9 | ENV['GIT_INDEX_FILE'] = gif = '/tmp/dev.gb.i' 10 | ENV['GIT_WORK_TREE'] = Dir.pwd 11 | File.unlink(gif) if File.file?(gif) 12 | `git add -A` 13 | tsha = `git write-tree`.strip 14 | puts "Created tree #{tsha}" 15 | if old_sha.size == 40 16 | csha = `echo 'boom' | git commit-tree #{tsha} -p #{old_sha}`.strip 17 | else 18 | csha = `echo 'boom' | git commit-tree #{tsha}`.strip 19 | end 20 | puts "Created commit #{csha}" 21 | puts `git show #{csha} --stat` 22 | puts "Updating gh-pages from #{old_sha}" 23 | `git update-ref refs/heads/gh-pages #{csha}` 24 | `git push origin gh-pages` 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /script/upload.sh: -------------------------------------------------------------------------------- 1 | # this script moves the generated book files to my server 2 | #scp -r output/book/* git-scm.com:/var/www/ 3 | rsync -e ssh -av output/book/* git-scm.com:/var/www 4 | -------------------------------------------------------------------------------- /text/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schacon/gitbook/86d1d3061f32e07b56851833c6673e66a04fdbba/text/.DS_Store -------------------------------------------------------------------------------- /text/01_Introduction/00_Section_Introduction.markdown: -------------------------------------------------------------------------------- 1 | #Introduction -------------------------------------------------------------------------------- /text/01_Introduction/0_ Introduction.markdown: -------------------------------------------------------------------------------- 1 | ## Welcome to Git ## 2 | 3 | Welcome to Git - the fast, distributed version control system. 4 | 5 | This book is meant to be a starting point for people new to Git to learn it 6 | as quickly and easily as possible. 7 | 8 | 9 | This book will start out by introducing you to the way Git stores data, to 10 | give you the context for why it is different than other VCS tools. 11 | This is meant to take you about 20 minutes. 12 | 13 | Next we will cover **Basic Git Usage** - the commands you will be using 90% of 14 | the time. These should give you a good basis to use Git comfortably for most 15 | of what you're going to use it for. This section should take you about 30 16 | minutes to read through. 17 | 18 | Next we will go over **Intermediate Git Usage** - things that are slightly more 19 | complex, but may replace some of the basic commands you learned in the first 20 | section. This will mostly be tricks and commands that will feel more 21 | comfortable after you know the basic commands. 22 | 23 | After you have all of that mastered, we will cover **Advanced Git** - commands 24 | that most people probably don't use very often, but can be very helpful in 25 | certain situations. Learning these commands should round out your day-to-day 26 | git knowledge; you will be a master of the Git! 27 | 28 | Now that you know Git, we will then cover **Working with Git**. Here we will go 29 | over how to use Git in scripts, with deployment tools, with editors and more. 30 | These sections are meant to help you integrate Git into your environment. 31 | 32 | Lastly, we will have a series of articles on **low-level documentation** that may 33 | help the Git hackers who want to learn how the actual internals and protocols 34 | work in Git. 35 | 36 | ### Feedback and Contributing ### 37 | 38 | At any point, if you see a mistake or want to contribute to the book, you can 39 | send me an email at [schacon@gmail.com](mailto:schacon@gmail.com), or you 40 | can clone the source of this book at 41 | [http://github.com/schacon/gitbook](http://github.com/schacon/gitbook) 42 | and send me a patch or a pull-request. 43 | 44 | ### References ### 45 | 46 | Much of this book is pulled together from different sources and then added to. 47 | If you would like to read some of the original articles or resources, please 48 | visit them and thank the authors: 49 | 50 | * [Git User Manual](http://www.kernel.org/pub/software/scm/git/docs/user-manual.html) 51 | * [The Git Tutorial](http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html) 52 | * [The Git Tutorial pt 2](http://www.kernel.org/pub/software/scm/git/docs/gittutorial-2.html) 53 | * ["My Git Workflow" blog post](http://osteele.com/archives/2008/05/my-git-workflow) 54 | 55 | -------------------------------------------------------------------------------- /text/02_Git_Object_Db_Basics/0_ Git_Object_Db_Basics.markdown: -------------------------------------------------------------------------------- 1 | ## The Git Object Model ## 2 | 3 | ### The SHA ### 4 | 5 | All the information needed to represent the history of a 6 | project is stored in files referenced by a 40-digit "object name" that 7 | looks something like this: 8 | 9 | 6ff87c4664981e4397625791c8ea3bbb5f2279a3 10 | 11 | You will see these 40-character strings all over the place in Git. 12 | In each case the name is calculated by taking the SHA1 hash of the 13 | contents of the object. The SHA1 hash is a cryptographic hash function. 14 | What that means to us is that it is virtually impossible to find two different 15 | objects with the same name. This has a number of advantages; among 16 | others: 17 | 18 | - Git can quickly determine whether two objects are identical or not, 19 | just by comparing names. 20 | - Since object names are computed the same way in every repository, the 21 | same content stored in two repositories will always be stored under 22 | the same name. 23 | - Git can detect errors when it reads an object, by checking that the 24 | object's name is still the SHA1 hash of its contents. 25 | 26 | ### The Objects ### 27 | 28 | Every object consists of three things - a **type**, a **size** and **content**. 29 | The _size_ is simply the size of the contents, the contents depend on what 30 | type of object it is, and there are four different types of objects: 31 | "blob", "tree", "commit", and "tag". 32 | 33 | - A **"blob"** is used to store file data - it is generally a file. 34 | - A **"tree"** is basically like a directory - it references a bunch of 35 | other trees and/or blobs (i.e. files and sub-directories) 36 | - A **"commit"** points to a single tree, marking it as what the project 37 | looked like at a certain point in time. It contains meta-information 38 | about that point in time, such as a timestamp, the author of the changes 39 | since the last commit, a pointer to the previous commit(s), etc. 40 | - A **"tag"** is a way to mark a specific commit as special in some way. It 41 | is normally used to tag certain commits as specific releases or something 42 | along those lines. 43 | 44 | Almost all of Git is built around manipulating this simple structure of four 45 | different object types. It is sort of its own little filesystem that sits 46 | on top of your machine's filesystem. 47 | 48 | ### Different from SVN ### 49 | 50 | It is important to note that this is very different from most SCM systems 51 | that you may be familiar with. Subversion, CVS, Perforce, Mercurial and the 52 | like all use _Delta Storage_ systems - they store the differences between one 53 | commit and the next. Git does not do this - it stores a snapshot of what all 54 | the files in your project look like in this tree structure each time you 55 | commit. This is a very important concept to understand when using Git. 56 | -------------------------------------------------------------------------------- /text/02_Git_Object_Db_Basics/1_Trees_and_Blobs.markdown: -------------------------------------------------------------------------------- 1 | ### Blob Object ### 2 | 3 | A blob generally stores the contents of a file. 4 | 5 | [fig:object-blob] 6 | 7 | You can use linkgit:git-show[1] to examine the contents of any blob. 8 | Assuming we have the SHA for a blob, we can examine its contents like this: 9 | 10 | $ git show 6ff87c4664 11 | 12 | Note that the only valid version of the GPL as far as this project 13 | is concerned is _this_ particular version of the license (ie v2, not 14 | v2.2 or v3.x or whatever), unless explicitly otherwise stated. 15 | ... 16 | 17 | A "blob" object is nothing but a chunk of binary data. It doesn't refer 18 | to anything else or have attributes of any kind, not even a file name. 19 | 20 | Since the blob is entirely defined by its data, if two files in a 21 | directory tree (or in multiple different versions of the repository) 22 | have the same contents, they will share the same blob object. The object 23 | is totally independent of its location in the directory tree, and 24 | renaming a file does not change the object that file is associated with. 25 | 26 | ### Tree Object ### 27 | 28 | A tree is a simple object that has a bunch of pointers to blobs and other 29 | trees - it generally represents the contents of a directory or subdirectory. 30 | 31 | [fig:object-tree] 32 | 33 | The ever-versatile linkgit:git-show[1] command can also be used to 34 | examine tree objects, but linkgit:git-ls-tree[1] will give you more 35 | details. Assuming we have the SHA for a tree, we can examine it like this: 36 | 37 | $ git ls-tree fb3a8bdd0ce 38 | 100644 blob 63c918c667fa005ff12ad89437f2fdc80926e21c .gitignore 39 | 100644 blob 5529b198e8d14decbe4ad99db3f7fb632de0439d .mailmap 40 | 100644 blob 6ff87c4664981e4397625791c8ea3bbb5f2279a3 COPYING 41 | 040000 tree 2fb783e477100ce076f6bf57e4a6f026013dc745 Documentation 42 | 100755 blob 3c0032cec592a765692234f1cba47dfdcc3a9200 GIT-VERSION-GEN 43 | 100644 blob 289b046a443c0647624607d471289b2c7dcd470b INSTALL 44 | 100644 blob 4eb463797adc693dc168b926b6932ff53f17d0b1 Makefile 45 | 100644 blob 548142c327a6790ff8821d67c2ee1eff7a656b52 README 46 | ... 47 | 48 | As you can see, a tree object contains a list of entries, each with a 49 | mode, object type, SHA1 name, and name, sorted by name. It represents 50 | the contents of a single directory tree. 51 | 52 | An object referenced by a tree may be blob, representing the contents of a 53 | file, or another tree, representing the contents of a subdirectory. Since 54 | trees and blobs, like all other objects, are named by the SHA1 hash of their 55 | contents, two trees have the same SHA1 name if and only if their contents 56 | (including, recursively, the contents of all subdirectories) are identical. 57 | This allows git to quickly determine the differences between two related tree 58 | objects, since it can ignore any entries with identical object names. 59 | 60 | (Note: in the presence of submodules, trees may also have commits as 61 | entries. See the **Submodules** section.) 62 | 63 | Note that the files all have mode 644 or 755: git actually only pays 64 | attention to the executable bit. 65 | 66 | -------------------------------------------------------------------------------- /text/02_Git_Object_Db_Basics/2_Commits.markdown: -------------------------------------------------------------------------------- 1 | ### Commit Object ### 2 | 3 | The "commit" object links a physical state of a tree with a description 4 | of how we got there and why. 5 | 6 | [fig:object-commit] 7 | 8 | You can use the --pretty=raw option to 9 | linkgit:git-show[1] or linkgit:git-log[1] to examine your favorite 10 | commit: 11 | 12 | $ git show -s --pretty=raw 2be7fcb476 13 | commit 2be7fcb4764f2dbcee52635b91fedb1b3dcf7ab4 14 | tree fb3a8bdd0ceddd019615af4d57a53f43d8cee2bf 15 | parent 257a84d9d02e90447b149af58b271c19405edb6a 16 | author Dave Watson1187576872 -0400 17 | committer Junio C Hamano 1187591163 -0700 18 | 19 | Fix misspelling of 'suppress' in docs 20 | 21 | Signed-off-by: Junio C Hamano 22 | 23 | As you can see, a commit is defined by: 24 | 25 | - a **tree**: The SHA1 name of a tree object (as defined below), representing 26 | the contents of a directory at a certain point in time. 27 | - **parent(s)**: The SHA1 name of some number of commits which represent the 28 | immediately previous step(s) in the history of the project. The 29 | example above has one parent; merge commits may have more than 30 | one. A commit with no parents is called a "root" commit, and 31 | represents the initial revision of a project. Each project must have 32 | at least one root. A project can also have multiple roots, though 33 | that isn't common (or necessarily a good idea). 34 | - an **author**: The name of the person responsible for this change, together 35 | with its date. 36 | - a **committer**: The name of the person who actually created the commit, 37 | with the date it was done. This may be different from the author; for 38 | example, if the author wrote a patch and emailed it to another person who 39 | used the patch to create the commit. 40 | - a **comment** describing this commit. 41 | 42 | Note that a commit does not itself contain any information about what 43 | actually changed; all changes are calculated by comparing the contents 44 | of the tree referred to by this commit with the trees associated with 45 | its parents. In particular, git does not attempt to record file renames 46 | explicitly, though it can identify cases where the existence of the same 47 | file data at changing paths suggests a rename. (See, for example, the 48 | -M option to linkgit:git-diff[1]). 49 | 50 | A commit is usually created by linkgit:git-commit[1], which creates a 51 | commit whose parent is normally the current HEAD, and whose tree is 52 | taken from the content currently stored in the index. 53 | 54 | ### The Object Model ### 55 | 56 | So, now that we've looked at the 3 main object types (blob, tree and commit), 57 | let's take a quick look at how they all fit together. 58 | 59 | If we had a simple project with the following directory structure: 60 | 61 | $>tree 62 | . 63 | |-- README 64 | `-- lib 65 | |-- inc 66 | | `-- tricks.rb 67 | `-- mylib.rb 68 | 69 | 2 directories, 3 files 70 | 71 | And we committed this to a Git repository, it would be represented like this: 72 | 73 | [fig:objects-example] 74 | 75 | You can see that we have created a **tree** object for each directory (including the root) 76 | and a **blob** object for each file. Then we have a **commit** object to point 77 | to the root, so we can track what our project looked like when it was committed. -------------------------------------------------------------------------------- /text/02_Git_Object_Db_Basics/3_Trust_and_Tags.markdown: -------------------------------------------------------------------------------- 1 | 2 | ### Tag Object ### 3 | 4 | [fig:object-tag] 5 | 6 | A tag object contains an object name (called simply 'object'), object type, 7 | tag name, the name of the person ("tagger") who created the tag, and a 8 | message, which may contain a signature, as can be seen using 9 | linkgit:git-cat-file[1]: 10 | 11 | $ git cat-file tag v1.5.0 12 | object 437b1b20df4b356c9342dac8d38849f24ef44f27 13 | type commit 14 | tag v1.5.0 15 | tagger Junio C Hamano 1171411200 +0000 16 | 17 | GIT 1.5.0 18 | -----BEGIN PGP SIGNATURE----- 19 | Version: GnuPG v1.4.6 (GNU/Linux) 20 | 21 | iD8DBQBF0lGqwMbZpPMRm5oRAuRiAJ9ohBLd7s2kqjkKlq1qqC57SbnmzQCdG4ui 22 | nLE/L9aUXdWeTFPron96DLA= 23 | =2E+0 24 | -----END PGP SIGNATURE----- 25 | 26 | See the linkgit:git-tag[1] command to learn how to create and verify tag 27 | objects. (Note that linkgit:git-tag[1] can also be used to create 28 | "lightweight tags", which are not tag objects at all, but just simple 29 | references whose names begin with "refs/tags/"). 30 | -------------------------------------------------------------------------------- /text/02a_Git_Directory_and_Working_Directory/0_ Git_Directory_and_Working_Directory.markdown: -------------------------------------------------------------------------------- 1 | ## Git Directory and Working Directory ## 2 | 3 | ### The Git Directory ### 4 | 5 | The 'git directory' is the directory that stores all Git's history and meta 6 | information for your project - including all of the objects (commits, trees, 7 | blobs, tags), all of the pointers to where different branches are and more. 8 | 9 | There is only one Git Directory per project (as opposed to one per 10 | subdirectory like with SVN or CVS), and that directory is (by default, though 11 | not necessarily) '.git' in the root of your project. If you look at the 12 | contents of that directory, you can see all of your important files: 13 | 14 | $>tree -L 1 15 | . 16 | |-- HEAD # pointer to your current branch 17 | |-- config # your configuration preferences 18 | |-- description # description of your project 19 | |-- hooks/ # pre/post action hooks 20 | |-- index # index file (see next section) 21 | |-- logs/ # a history of where your branches have been 22 | |-- objects/ # your objects (commits, trees, blobs, tags) 23 | `-- refs/ # pointers to your branches 24 | 25 | (there may be some other files/directories in there as well, but they are not important for now) 26 | 27 | ### The Working Directory ### 28 | 29 | The Git 'working directory' is the directory that holds the current checkout 30 | of the files you are working on. Files in this directory are often removed 31 | or replaced by Git as you switch branches - this is normal. All your history 32 | is stored in the Git Directory; the working directory is simply a temporary 33 | checkout place where you can modify the files until your next commit. 34 | 35 | -------------------------------------------------------------------------------- /text/03_The_Git_Index/0_ The_Git_Index.markdown: -------------------------------------------------------------------------------- 1 | ## The Git Index ## 2 | 3 | The Git index is used as a staging area between your working directory 4 | and your repository. You can use the index to build up a set of changes 5 | that you want to commit together. When you create a commit, what is committed 6 | is what is currently in the index, not what is in your working directory. 7 | 8 | ### Looking at the Index ### 9 | 10 | The easiest way to see what is in the index is with the linkgit:git-status[1] 11 | command. When you run git status, you can see which files are staged 12 | (currently in your index), which are modified but not yet staged, and which 13 | are completely untracked. 14 | 15 | $>git status 16 | # On branch master 17 | # Your branch is behind 'origin/master' by 11 commits, and can be fast-forwarded. 18 | # 19 | # Changes to be committed: 20 | # (use "git reset HEAD ..." to unstage) 21 | # 22 | # modified: daemon.c 23 | # 24 | # Changed but not updated: 25 | # (use "git add ..." to update what will be committed) 26 | # 27 | # modified: grep.c 28 | # modified: grep.h 29 | # 30 | # Untracked files: 31 | # (use "git add ..." to include in what will be committed) 32 | # 33 | # blametree 34 | # blametree-init 35 | # git-gui/git-citool 36 | 37 | If you blow the index away entirely, you generally haven't lost any 38 | information as long as you have the name of the tree that it described. 39 | 40 | And with that, you should have a pretty good understanding of the basics of 41 | what Git is doing behind the scenes, and why it is a bit different than most 42 | other SCM systems. Don't worry if you don't totally understand it all right 43 | now; we'll revisit all of these topics in the next sections. Now we're ready 44 | to move on to installing, configuring and using Git. -------------------------------------------------------------------------------- /text/05_Installing_Git/00_Section.markdown: -------------------------------------------------------------------------------- 1 | #First Time -------------------------------------------------------------------------------- /text/05_Installing_Git/0_Installing_Git.markdown: -------------------------------------------------------------------------------- 1 | ## Installing Git ## 2 | 3 | 4 | -------------------------------------------------------------------------------- /text/05_Installing_Git/0_Source.markdown: -------------------------------------------------------------------------------- 1 | ### Installing from Source ### 2 | 3 | In short, on a Unix-based system, you can download the Git source code from the 4 | [Git Download Page](http://git-scm.com/download), and then run something 5 | along the lines of : 6 | 7 | $ make prefix=/usr all ;# as yourself 8 | $ make prefix=/usr install ;# as root 9 | 10 | You will need the [expat](http://expat.sourceforge.net/), 11 | [curl](http://curl.linux-mirror.org), 12 | [zlib](http://www.zlib.net), and [openssl](http://www.openssl.org) libraries 13 | installed - though with the possible exception of *expat*, these will normally already 14 | be there. -------------------------------------------------------------------------------- /text/05_Installing_Git/1_Linux.markdown: -------------------------------------------------------------------------------- 1 | ### Linux ### 2 | 3 | If you are running Linux, you can likely install Git easily via your native 4 | package management system: 5 | 6 | $ yum install git-core 7 | 8 | $ apt-get install git-core 9 | 10 | If that doesn't work, you can download the .deb or .rpm packages from here: 11 | 12 | [RPM Packages](http://kernel.org/pub/software/scm/git/RPMS/) 13 | 14 | [Stable Debs](http://www.backports.org/debian/pool/main/g/git-core/) 15 | 16 | If you prefer to install from source on a Linux system, this article may be 17 | helpful: 18 | 19 | [Article: Installing Git on Ubuntu](http://chrisolsen.org/2008/03/10/installing-git-on-ubuntu/) -------------------------------------------------------------------------------- /text/05_Installing_Git/2_Mac_104.markdown: -------------------------------------------------------------------------------- 1 | ### Mac 10.4 ### 2 | 3 | In both Mac 10.4 and 10.5, you can install Git via [MacPorts](http://www.macports.org/), 4 | if you have that installed. If not, you can install it from [here](http://www.macports.org/install.php). 5 | 6 | Once MacPorts is installed, all you should have to do is: 7 | 8 | $ sudo port install git-core 9 | 10 | If you prefer to install from source, these articles may be helpful: 11 | 12 | [Article: Installing Git on Tiger](http://rails.wincent.com/wiki/Installing_Git_1.5.2.3_on_Mac_OS_X_Tiger) 13 | 14 | [Article: Installing Git and git-svn on Tiger from source](http://larrytheliquid.com/2007/12/29/compiling-git-and-git-svn-on-osx-tiger/) -------------------------------------------------------------------------------- /text/05_Installing_Git/3_Mac_105.markdown: -------------------------------------------------------------------------------- 1 | ### Mac 10.5 ### 2 | 3 | With Leopard, you can also install via MacPorts, but here you have the 4 | additional option of using a nice installer, which you can download from here: 5 | [Git OSX 6 | Installer](http://code.google.com/p/git-osx-installer/downloads/list?can=3) 7 | 8 | If you prefer to install it from source, these guides may be particularly helpful to you : 9 | 10 | [Article: Installing Git on OSX Leopard](http://solutions.treypiepmeier.com/2008/02/25/installing-git-on-os-x-leopard/) 11 | 12 | [Article: Installing Git on OS 10.5](http://dysinger.net/2007/12/30/installing-git-on-mac-os-x-105-leopard/) 13 | -------------------------------------------------------------------------------- /text/05_Installing_Git/4_Windows.markdown: -------------------------------------------------------------------------------- 1 | ### Windows ### 2 | 3 | On Windows, installing Git is pretty easy. Simply download and install the 4 | [msysGit](http://code.google.com/p/msysgit/downloads/list) package. 5 | 6 | See the *Git on Windows* chapter for a screencast demonstrating installing 7 | and using Git on Windows. 8 | 9 | -------------------------------------------------------------------------------- /text/06_Setup_and_Initialization/0_ Setup_and_Initialization.markdown: -------------------------------------------------------------------------------- 1 | ## Setup and Initialization ## 2 | 3 | -------------------------------------------------------------------------------- /text/06_Setup_and_Initialization/1_Git_Config.markdown: -------------------------------------------------------------------------------- 1 | ### Git Config ### 2 | 3 | The first thing you're going to want to do is set up your name and email 4 | address for Git to use to sign your commits. 5 | 6 | $ git config --global user.name "Scott Chacon" 7 | $ git config --global user.email "schacon@gmail.com" 8 | 9 | That will set up a file in your home directory which may be used by any of 10 | your projects. By default that file is *~/.gitconfig* and the contents will 11 | look like this: 12 | 13 | [user] 14 | name = Scott Chacon 15 | email = schacon@gmail.com 16 | 17 | If you want to override those values for a specific project (to use a work 18 | email address, for example), you can run the *git config* command without the 19 | *--global* option while in that project. This will add a [user] section like 20 | the one shown above to the *.git/config* file in your project's root 21 | directory. 22 | -------------------------------------------------------------------------------- /text/06a_Getting_A_Repo/00_Section_Basic_Usage.markdown: -------------------------------------------------------------------------------- 1 | # Basic Usage # 2 | 3 | -------------------------------------------------------------------------------- /text/06a_Getting_A_Repo/1_Getting_a_Git_Repo.markdown: -------------------------------------------------------------------------------- 1 | ## Getting a Git Repository ## 2 | 3 | So now that we're all set up, we need a Git repository. We can do this one of 4 | two ways - we can *clone* one that already exists, or we can *initialize* one 5 | either from existing files that aren't in source control yet, or from an empty 6 | directory. 7 | 8 | ### Cloning a Repository ### 9 | 10 | In order to get a copy of a project, you will need to know the project's Git 11 | URL - the location of the repository. Git can operate over many different 12 | protocols, so it may begin with ssh://, http(s)://, git://, or just a username 13 | (in which case git will assume ssh). Some repositories may be accessed over 14 | more than one protocol. For example, the source code to Git itself can be 15 | cloned either over the git:// protocol: 16 | 17 | git clone git://git.kernel.org/pub/scm/git/git.git 18 | 19 | or over http: 20 | 21 | git clone http://www.kernel.org/pub/scm/git/git.git 22 | 23 | The git:// protocol is faster and more efficient, but sometimes it is 24 | necessary to use http when behind corporate firewalls or what have you. In 25 | either case you should then have a new directory named 'git' that contains all 26 | the Git source code and history - it is basically a complete copy of what was 27 | on the server. 28 | 29 | By default, Git will name the new directory it has checked out your cloned 30 | code into after whatever comes directly before the '.git' in the path of the 31 | cloned project. (ie. *git clone 32 | http://git.kernel.org/linux/kernel/git/torvalds/linux-2.6.git* will result in 33 | a new directory named 'linux-2.6') 34 | 35 | ### Initializing a New Repository ### 36 | 37 | Assume you have a tarball named project.tar.gz with your initial work. You can 38 | place it under git revision control as follows. 39 | 40 | $ tar xzf project.tar.gz 41 | $ cd project 42 | $ git init 43 | 44 | Git will reply 45 | 46 | Initialized empty Git repository in .git/ 47 | 48 | You've now initialized the working directory--you may notice a new 49 | directory created, named ".git". 50 | 51 | [gitcast:c1_init](GitCast #1 - setup, init and cloning) 52 | -------------------------------------------------------------------------------- /text/07_Normal_Workflow/0_ Normal_Workflow.markdown: -------------------------------------------------------------------------------- 1 | ## Normal Workflow ## 2 | 3 | Modify some files, then add their updated contents to the index: 4 | 5 | $ git add file1 file2 file3 6 | 7 | You are now ready to commit. You can see what is about to be committed 8 | using linkgit:git-diff[1] with the --cached option: 9 | 10 | $ git diff --cached 11 | 12 | (Without --cached, linkgit:git-diff[1] will show you any changes that 13 | you've made but not yet added to the index.) You can also get a brief 14 | summary of the situation with linkgit:git-status[1]: 15 | 16 | $ git status 17 | # On branch master 18 | # Changes to be committed: 19 | # (use "git reset HEAD ..." to unstage) 20 | # 21 | # modified: file1 22 | # modified: file2 23 | # modified: file3 24 | # 25 | 26 | If you need to make any further adjustments, do so now, and then add any 27 | newly modified content to the index. Finally, commit your changes with: 28 | 29 | $ git commit 30 | 31 | This will again prompt you for a message describing the change, and then 32 | record a new version of the project. 33 | 34 | Alternatively, instead of running `git add` beforehand, you can use 35 | 36 | $ git commit -a 37 | 38 | which will automatically notice any modified (but not new) files, add 39 | them to the index, and commit, all in one step. 40 | 41 | A note on commit messages: Though not required, it's a good idea to 42 | begin the commit message with a single short (less than 50 character) 43 | line summarizing the change, followed by a blank line and then a more 44 | thorough description. Tools that turn commits into email, for 45 | example, use the first line on the Subject: line and the rest of the 46 | commit message in the body. 47 | 48 | 49 | #### Git tracks content not files #### 50 | 51 | Many revision control systems provide an "add" command that tells the 52 | system to start tracking changes to a new file. Git's "add" command 53 | does something simpler and more powerful: `git add` is used both for new 54 | and newly modified files, and in both cases it takes a snapshot of the 55 | given files and stages that content in the index, ready for inclusion in 56 | the next commit. 57 | 58 | [gitcast:c2_normal_workflow]("GitCast #2: Normal Workflow") -------------------------------------------------------------------------------- /text/08_Basic_Branching_and_Merging/0_ Basic_Branching_and_Merging.markdown: -------------------------------------------------------------------------------- 1 | ## Basic Branching and Merging ## 2 | 3 | A single git repository can maintain multiple branches of 4 | development. To create a new branch named "experimental", use 5 | 6 | $ git branch experimental 7 | 8 | If you now run 9 | 10 | $ git branch 11 | 12 | you'll get a list of all existing branches: 13 | 14 | experimental 15 | * master 16 | 17 | The "experimental" branch is the one you just created, and the 18 | "master" branch is a default branch that was created for you 19 | automatically. The asterisk marks the branch you are currently on; 20 | type 21 | 22 | $ git checkout experimental 23 | 24 | to switch to the experimental branch. Now edit a file, commit the 25 | change, and switch back to the master branch: 26 | 27 | (edit file) 28 | $ git commit -a 29 | $ git checkout master 30 | 31 | Check that the change you made is no longer visible, since it was 32 | made on the experimental branch and you're back on the master branch. 33 | 34 | You can make a different change on the master branch: 35 | 36 | (edit file) 37 | $ git commit -a 38 | 39 | at this point the two branches have diverged, with different changes 40 | made in each. To merge the changes made in experimental into master, run 41 | 42 | $ git merge experimental 43 | 44 | If the changes don't conflict, you're done. If there are conflicts, 45 | markers will be left in the problematic files showing the conflict; 46 | 47 | $ git diff 48 | 49 | will show this. Once you've edited the files to resolve the 50 | conflicts, 51 | 52 | $ git commit -a 53 | 54 | will commit the result of the merge. Finally, 55 | 56 | $ gitk 57 | 58 | will show a nice graphical representation of the resulting history. 59 | 60 | At this point you could delete the experimental branch with 61 | 62 | $ git branch -d experimental 63 | 64 | This command ensures that the changes in the experimental branch are 65 | already in the current branch. 66 | 67 | If you develop on a branch crazy-idea, then regret it, you can always 68 | delete the branch with 69 | 70 | $ git branch -D crazy-idea 71 | 72 | Branches are cheap and easy, so this is a good way to try something 73 | out. 74 | 75 | ### How to merge ### 76 | 77 | You can rejoin two diverging branches of development using 78 | linkgit:git-merge[1]: 79 | 80 | $ git merge branchname 81 | 82 | merges the changes made in the branch "branchname" into the current 83 | branch. If there are conflicts--for example, if the same file is 84 | modified in two different ways in the remote branch and the local 85 | branch--then you are warned; the output may look something like this: 86 | 87 | $ git merge next 88 | 100% (4/4) done 89 | Auto-merged file.txt 90 | CONFLICT (content): Merge conflict in file.txt 91 | Automatic merge failed; fix conflicts and then commit the result. 92 | 93 | Conflict markers are left in the problematic files, and after 94 | you resolve the conflicts manually, you can update the index 95 | with the contents and run git commit, as you normally would when 96 | modifying a file. 97 | 98 | If you examine the resulting commit using gitk, you will see that it 99 | has two parents: one pointing to the top of the current branch, and 100 | one to the top of the other branch. 101 | 102 | ### Resolving a merge ### 103 | 104 | When a merge isn't resolved automatically, git leaves the index and 105 | the working tree in a special state that gives you all the 106 | information you need to help resolve the merge. 107 | 108 | Files with conflicts are marked specially in the index, so until you 109 | resolve the problem and update the index, linkgit:git-commit[1] will 110 | fail: 111 | 112 | $ git commit 113 | file.txt: needs merge 114 | 115 | Also, linkgit:git-status[1] will list those files as "unmerged", and the 116 | files with conflicts will have conflict markers added, like this: 117 | 118 | <<<<<<< HEAD:file.txt 119 | Hello world 120 | ======= 121 | Goodbye 122 | >>>>>>> 77976da35a11db4580b80ae27e8d65caf5208086:file.txt 123 | 124 | All you need to do is edit the files to resolve the conflicts, and then 125 | 126 | $ git add file.txt 127 | $ git commit 128 | 129 | Note that the commit message will already be filled in for you with 130 | some information about the merge. Normally you can just use this 131 | default message unchanged, but you may add additional commentary of 132 | your own if desired. 133 | 134 | The above is all you need to know to resolve a simple merge. But git 135 | also provides more information to help resolve conflicts: 136 | 137 | ### Undoing a merge ### 138 | 139 | If you get stuck and decide to just give up and throw the whole mess 140 | away, you can always return to the pre-merge state with 141 | 142 | $ git reset --hard HEAD 143 | 144 | Or, if you've already committed the merge that you want to throw away, 145 | 146 | $ git reset --hard ORIG_HEAD 147 | 148 | However, this last command can be dangerous in some cases--never throw away a 149 | commit if that commit may itself have been merged into another branch, as 150 | doing so may confuse further merges. 151 | 152 | ### Fast-forward merges ### 153 | 154 | There is one special case not mentioned above, which is treated differently. 155 | Normally, a merge results in a merge commit with two parents, one for each of 156 | the two lines of development that were merged. 157 | 158 | However, if the current branch has not diverged from the other--so every 159 | commit present in the current branch is already contained in the other--then 160 | git just performs a "fast forward"; the head of the current branch is moved 161 | forward to point at the head of the merged-in branch, without any new commits 162 | being created. 163 | 164 | [gitcast:c6-branch-merge]("GitCast #6: Branching and Merging") 165 | -------------------------------------------------------------------------------- /text/10_Comparing_Commits_Git_Diff/0_ Comparing_Commits_Git_Diff.markdown: -------------------------------------------------------------------------------- 1 | ## Comparing Commits - Git Diff ## 2 | 3 | You can generate diffs between any two versions of your project using 4 | linkgit:git-diff[1]: 5 | 6 | $ git diff master..test 7 | 8 | That will produce the diff between the tips of the two branches. If 9 | you'd prefer to find the diff from their common ancestor to test, you 10 | can use three dots instead of two: 11 | 12 | $ git diff master...test 13 | 14 | linkgit:git-diff[1] is an incredibly useful tool for figuring out what has 15 | changed between any two points in your project's history, or to see what 16 | people are trying to introduce in new branches, etc. 17 | 18 | ### What you will commit ### 19 | 20 | You will commonly use linkgit:git-diff[1] for figuring out differences between 21 | your last commit, your index, and your current working directory. 22 | A common use is to simply run 23 | 24 | $ git diff 25 | 26 | which will show you changes in the working directory that are not yet 27 | staged for the next commit. 28 | If you want to see what _is_ staged for the next commit, you can run 29 | 30 | $ git diff --cached 31 | 32 | which will show you the difference between the index and your last commit; 33 | what you would be committing if you run "git commit" without the "-a" option. 34 | Lastly, you can run 35 | 36 | $ git diff HEAD 37 | 38 | which shows changes in the working directory since your last commit; 39 | what you would be committing if you run "git commit -a". 40 | 41 | ### More Diff Options ### 42 | 43 | If you want to see how your current working directory differs from the state of 44 | the project in another branch, you can run something like 45 | 46 | $ git diff test 47 | 48 | This will show you what is different between your current working directory 49 | and the snapshot on the 'test' branch. You can also limit the comparison to a 50 | specific file or subdirectory by adding a *path limiter*: 51 | 52 | $ git diff HEAD -- ./lib 53 | 54 | That command will show the changes between your current working directory and 55 | the last commit (or, more accurately, the tip of the current branch), limiting 56 | the comparison to files in the 'lib' subdirectory. 57 | 58 | If you don't want to see the whole patch, you can add the '--stat' option, 59 | which will limit the output to the files that have changed along with a little 60 | text graph depicting how many lines changed in each file. 61 | 62 | $>git diff --stat 63 | layout/book_index_template.html | 8 ++- 64 | text/05_Installing_Git/0_Source.markdown | 14 ++++++ 65 | text/05_Installing_Git/1_Linux.markdown | 17 +++++++ 66 | text/05_Installing_Git/2_Mac_104.markdown | 11 +++++ 67 | text/05_Installing_Git/3_Mac_105.markdown | 8 ++++ 68 | text/05_Installing_Git/4_Windows.markdown | 7 +++ 69 | .../1_Getting_a_Git_Repo.markdown | 7 +++- 70 | .../0_ Comparing_Commits_Git_Diff.markdown | 45 +++++++++++++++++++- 71 | .../0_ Hosting_Git_gitweb_repoorcz_github.markdown | 4 +- 72 | 9 files changed, 115 insertions(+), 6 deletions(-) 73 | 74 | Sometimes that makes it easier to see overall what has changed, to jog your memory. 75 | -------------------------------------------------------------------------------- /text/11_Distributed_Workflows_Clone_Fetch_Push/0_ Distributed_Workflows_Clone_Fetch_Push.markdown: -------------------------------------------------------------------------------- 1 | ## Distributed Workflows ## 2 | 3 | Suppose that Alice has started a new project with a git repository in 4 | /home/alice/project, and that Bob, who has a home directory on the 5 | same machine, wants to contribute. 6 | 7 | Bob begins with: 8 | 9 | $ git clone /home/alice/project myrepo 10 | 11 | This creates a new directory "myrepo" containing a clone of Alice's 12 | repository. The clone is on an equal footing with the original 13 | project, possessing its own copy of the original project's history. 14 | 15 | Bob then makes some changes and commits them: 16 | 17 | 18 | (edit files) 19 | $ git commit -a 20 | (repeat as necessary) 21 | 22 | When he's ready, he tells Alice to pull changes from the repository 23 | at /home/bob/myrepo. She does this with: 24 | 25 | $ cd /home/alice/project 26 | $ git pull /home/bob/myrepo master 27 | 28 | This merges the changes from Bob's "master" branch into Alice's 29 | current branch. If Alice has made her own changes in the meantime, 30 | then she may need to manually fix any conflicts. (Note that the 31 | "master" argument in the above command is actually unnecessary, as it 32 | is the default.) 33 | 34 | The "pull" command thus performs two operations: it fetches changes 35 | from a remote branch, then merges them into the current branch. 36 | 37 | When you are working in a small closely knit group, it is not 38 | unusual to interact with the same repository over and over 39 | again. By defining 'remote' repository shorthand, you can make 40 | it easier: 41 | 42 | $ git remote add bob /home/bob/myrepo 43 | 44 | With this, Alice can perform the first operation alone using the 45 | "git fetch" command without merging them with her own branch, 46 | using: 47 | 48 | $ git fetch bob 49 | 50 | Unlike the longhand form, when Alice fetches from Bob using a 51 | remote repository shorthand set up with `git remote`, what was 52 | fetched is stored in a remote tracking branch, in this case 53 | `bob/master`. So after this: 54 | 55 | $ git log -p master..bob/master 56 | 57 | shows a list of all the changes that Bob made since he branched from 58 | Alice's master branch. 59 | 60 | After examining those changes, Alice 61 | could merge the changes into her master branch: 62 | 63 | $ git merge bob/master 64 | 65 | This `merge` can also be done by 'pulling from her own remote 66 | tracking branch', like this: 67 | 68 | $ git pull . remotes/bob/master 69 | 70 | Note that git pull always merges into the current branch, 71 | regardless of what else is given on the command line. 72 | 73 | Later, Bob can update his repo with Alice's latest changes using 74 | 75 | $ git pull 76 | 77 | Note that he doesn't need to give the path to Alice's repository; 78 | when Bob cloned Alice's repository, git stored the location of her 79 | repository in the repository configuration, and that location is 80 | used for pulls: 81 | 82 | $ git config --get remote.origin.url 83 | /home/alice/project 84 | 85 | (The complete configuration created by git-clone is visible using 86 | "git config -l", and the linkgit:git-config[1] man page 87 | explains the meaning of each option.) 88 | 89 | Git also keeps a pristine copy of Alice's master branch under the 90 | name "origin/master": 91 | 92 | $ git branch -r 93 | origin/master 94 | 95 | If Bob later decides to work from a different host, he can still 96 | perform clones and pulls using the ssh protocol: 97 | 98 | $ git clone alice.org:/home/alice/project myrepo 99 | 100 | Alternatively, git has a native protocol, or can use rsync or http; 101 | see linkgit:git-pull[1] for details. 102 | 103 | Git can also be used in a CVS-like mode, with a central repository 104 | that various users push changes to; see linkgit:git-push[1] and 105 | linkgit:gitcvs-migration[1]. 106 | 107 | 108 | ### Public git repositories ### 109 | 110 | Another way to submit changes to a project is to tell the maintainer 111 | of that project to pull the changes from your repository using 112 | linkgit:git-pull[1]. This is a way to get 113 | updates from the "main" repository, but it works just as well in the 114 | other direction. 115 | 116 | If you and the maintainer both have accounts on the same machine, then 117 | you can just pull changes from each other's repositories directly; 118 | commands that accept repository URLs as arguments will also accept a 119 | local directory name: 120 | 121 | $ git clone /path/to/repository 122 | $ git pull /path/to/other/repository 123 | 124 | or an ssh URL: 125 | 126 | $ git clone ssh://yourhost/~you/repository 127 | 128 | For projects with few developers, or for synchronizing a few private 129 | repositories, this may be all you need. 130 | 131 | However, the more common way to do this is to maintain a separate public 132 | repository (usually on a different host) for others to pull changes 133 | from. This is usually more convenient, and allows you to cleanly 134 | separate private work in progress from publicly visible work. 135 | 136 | You will continue to do your day-to-day work in your personal 137 | repository, but periodically "push" changes from your personal 138 | repository into your public repository, allowing other developers to 139 | pull from that repository. So the flow of changes, in a situation 140 | where there is one other developer with a public repository, looks 141 | like this: 142 | 143 | you push 144 | your personal repo ------------------> your public repo 145 | ^ | 146 | | | 147 | | you pull | they pull 148 | | | 149 | | | 150 | | they push V 151 | their public repo <------------------- their repo 152 | 153 | 154 | 155 | ### Pushing changes to a public repository ### 156 | 157 | Note that exporting via http or git allow other 158 | maintainers to fetch your latest changes, but they do not allow write 159 | access. For this, you will need to update the public repository with the 160 | latest changes created in your private repository. 161 | 162 | The simplest way to do this is using linkgit:git-push[1] and ssh; to 163 | update the remote branch named "master" with the latest state of your 164 | branch named "master", run 165 | 166 | $ git push ssh://yourserver.com/~you/proj.git master:master 167 | 168 | or just 169 | 170 | $ git push ssh://yourserver.com/~you/proj.git master 171 | 172 | As with git-fetch, git-push will complain if this does not result in a 173 | fast forward; see the following section for details on 174 | handling this case. 175 | 176 | Note that the target of a "push" is normally a bare repository. You can also push to a 177 | repository that has a checked-out working tree, but the working tree 178 | will not be updated by the push. This may lead to unexpected results if 179 | the branch you push to is the currently checked-out branch! 180 | 181 | As with git-fetch, you may also set up configuration options to 182 | save typing; so, for example, after 183 | 184 | $ cat >>.git/config < .url, branch. .remote, 194 | and remote. .push options in linkgit:git-config[1] for 195 | details. 196 | 197 | ### What to do when a push fails ### 198 | 199 | If a push would not result in a fast forward of the 200 | remote branch, then it will fail with an error like: 201 | 202 | error: remote 'refs/heads/master' is not an ancestor of 203 | local 'refs/heads/master'. 204 | Maybe you are not up-to-date and need to pull first? 205 | error: failed to push to 'ssh://yourserver.com/~you/proj.git' 206 | 207 | This can happen, for example, if you: 208 | 209 | - use `git-reset --hard` to remove already-published commits, or 210 | - use `git-commit --amend` to replace already-published commits, or 211 | - use `git-rebase` to rebase any already-published commits. 212 | 213 | You may force git-push to perform the update anyway by preceding the 214 | branch name with a plus sign: 215 | 216 | $ git push ssh://yourserver.com/~you/proj.git +master 217 | 218 | Normally whenever a branch head in a public repository is modified, it 219 | is modified to point to a descendant of the commit that it pointed to 220 | before. By forcing a push in this situation, you break that convention. 221 | 222 | Nevertheless, this is a common practice for people that need a simple 223 | way to publish a work-in-progress patch series, and it is an acceptable 224 | compromise as long as you warn other developers that this is how you 225 | intend to manage the branch. 226 | 227 | It's also possible for a push to fail in this way when other people have 228 | the right to push to the same repository. In that case, the correct 229 | solution is to retry the push after first updating your work: either by a 230 | pull, or by a fetch followed by a rebase; see the next section and 231 | linkgit:gitcvs-migration[7] for more. 232 | 233 | [gitcast:c8-dist-workflow]("GitCast #8: Distributed Workflow") 234 | -------------------------------------------------------------------------------- /text/12_Git_Tag/0_ Git_Tag.markdown: -------------------------------------------------------------------------------- 1 | ## Git Tag ## 2 | 3 | ### Lightweight Tags ### 4 | 5 | We can create a tag to refer to a particular commit by running linkgit:git-tag[1] 6 | with no arguments. 7 | 8 | $ git tag stable-1 1b2e1d63ff 9 | 10 | After that, we can use stable-1 to refer to the commit 1b2e1d63ff. 11 | 12 | This creates a "lightweight" tag, basically a branch that never moves. 13 | If you would also like to include a comment with the tag, 14 | and possibly sign it cryptographically, then we can create a *tag object* instead. 15 | 16 | ### Tag Objects ### 17 | 18 | If one of **-a**, **-s**, or **-u ** is passed, the command creates a tag object, 19 | and requires the tag message. Unless -m or -F is given, an editor 20 | is started for the user to type in the tag message. 21 | 22 | When this happens, a new object is added to the Git object database and the 23 | tag ref points to that _tag object_, rather than the commit itself. The strength 24 | of this is that you can sign the tag, so you can verify that it is the correct 25 | commit later. You can create a tag object like this: 26 | 27 | $ git tag -a stable-1 1b2e1d63ff 28 | 29 | It is actually possible to tag any object, but tagging commit objects is the 30 | most common. (In the Linux kernel source, the first tag object 31 | references a tree, rather than a commit) 32 | 33 | ### Signed Tags ### 34 | 35 | If you have a GPG key setup, you can create signed tags fairly easily. First, 36 | you will probably want to setup your key id in your _.git/config_ or _~.gitconfig_ 37 | file. 38 | 39 | [user] 40 | signingkey = 41 | 42 | You can also set that with 43 | 44 | $ git config (--global) user.signingkey 45 | 46 | Now you can create a signed tag simply by replacing the **-a** with a **-s**. 47 | 48 | $ git tag -s stable-1 1b2e1d63ff 49 | 50 | If you don't have your GPG key in your config file, you can accomplish the same 51 | thing this way: 52 | 53 | $ git tag -u stable-1 1b2e1d63ff -------------------------------------------------------------------------------- /text/12a_Ignoring_Files/00_Section_Intermediate_Usage.markdown: -------------------------------------------------------------------------------- 1 | #Intermediate Usage 2 | -------------------------------------------------------------------------------- /text/12a_Ignoring_Files/0_Ignoring_Files.markdown: -------------------------------------------------------------------------------- 1 | ## Ignoring files ## 2 | 3 | A project will often generate files that you do 'not' want to track with git. 4 | This typically includes files generated by a build process or temporary 5 | backup files made by your editor. Of course, 'not' tracking files with git 6 | is just a matter of 'not' calling "`git-add`" on them. But it quickly becomes 7 | annoying to have these untracked files lying around; e.g. they make 8 | "`git add .`" and "`git commit -a`" practically useless, and they keep 9 | showing up in the output of "`git status`". 10 | 11 | You can tell git to ignore certain files by creating a file called .gitignore 12 | in the top level of your working directory, with contents such as: 13 | 14 | # Lines starting with '#' are considered comments. 15 | # Ignore any file named foo.txt. 16 | foo.txt 17 | # Ignore (generated) html files, 18 | *.html 19 | # except foo.html which is maintained by hand. 20 | !foo.html 21 | # Ignore objects and archives. 22 | *.[oa] 23 | 24 | See linkgit:gitignore[5] for a detailed explanation of the syntax. You can 25 | also place .gitignore files in other directories in your working tree, and they 26 | will apply to those directories and their subdirectories. The `.gitignore` 27 | files can be added to your repository like any other files 28 | (just run `git add .gitignore` and `git commit`, as usual), which is convenient when the exclude 29 | patterns (such as patterns matching build output files) would also make sense 30 | for other users who clone your repository. 31 | 32 | If you wish the exclude patterns to affect only certain repositories 33 | (instead of every repository for a given project), you may instead put 34 | them in a file in your repository named .git/info/exclude, or in any file 35 | specified by the `core.excludesfile` configuration variable. Some git 36 | commands can also take exclude patterns directly on the command line. 37 | See linkgit:gitignore[5] for the details. -------------------------------------------------------------------------------- /text/13_Rebasing/0_ Rebasing.markdown: -------------------------------------------------------------------------------- 1 | ## Rebasing ## 2 | 3 | Suppose that you create a branch "mywork" on a remote-tracking branch 4 | "origin". 5 | 6 | $ git checkout -b mywork origin 7 | 8 | [fig:rebase0] 9 | 10 | Now you do some work, creating two new commits. 11 | 12 | $ vi file.txt 13 | $ git commit 14 | $ vi otherfile.txt 15 | $ git commit 16 | ... 17 | 18 | Meanwhile, someone else does some work creating two new commits on the origin 19 | branch too. This means both 'origin' and 'mywork' has advanced, which means 20 | the work has diverged. 21 | 22 | [fig:rebase1] 23 | 24 | At this point, you could use "pull" to merge your changes back in; 25 | the result would create a new merge commit, like this: 26 | 27 | [fig:rebase2] 28 | 29 | However, if you prefer to keep the history in mywork a simple series of 30 | commits without any merges, you may instead choose to use 31 | linkgit:git-rebase[1]: 32 | 33 | $ git checkout mywork 34 | $ git rebase origin 35 | 36 | This will remove each of your commits from mywork, temporarily saving 37 | them as patches (in a directory named ".git/rebase"), update mywork to 38 | point at the latest version of origin, then apply each of the saved 39 | patches to the new mywork. 40 | 41 | [fig:rebase3] 42 | 43 | Once the ref ('mywork') is updated to point to the newly created commit 44 | objects, your older commits will be abandoned. They will likely be 45 | removed if you run a pruning garbage collection. (see linkgit:git-gc[1]) 46 | 47 | [fig:rebase4] 48 | 49 | So now we can look at the difference in our history between running a merge 50 | and running a rebase: 51 | 52 | [fig:rebase5] 53 | 54 | In the process of the rebase, it may discover conflicts. In that case it will stop 55 | and allow you to fix the conflicts; after fixing conflicts, use "git-add" 56 | to update the index with those contents, and then, instead of 57 | running git-commit, just run 58 | 59 | $ git rebase --continue 60 | 61 | and git will continue applying the rest of the patches. 62 | 63 | At any point you may use the `--abort` option to abort this process and 64 | return mywork to the state it had before you started the rebase: 65 | 66 | $ git rebase --abort 67 | 68 | 69 | [gitcast:c7-rebase]("GitCast #7: Rebasing") 70 | -------------------------------------------------------------------------------- /text/14_Interactive_Rebasing/0_ Interactive_Rebasing.markdown: -------------------------------------------------------------------------------- 1 | ## Interactive Rebasing ## 2 | 3 | You can also rebase interactively. This is often used to re-write your 4 | own commit objects before pusing them somewhere. It is an easy way to 5 | split, merge or re-order commits before sharing them with others. You 6 | can also use it to clean up commits you've pulled from someone when 7 | applying them locally. 8 | 9 | If you have a number of commits that you would like to somehow modify 10 | during the rebase, you can invoke interactive mode by passing a '-i' or 11 | '--interactive' to the 'git rebase' command. 12 | 13 | $ git rebase -i origin/master 14 | 15 | This will invoke interactive rebase mode on all the commits you have made 16 | since the last time you have pushed (or merged from the origin repository). 17 | 18 | To see what commits those are beforehand, you can run log this way: 19 | 20 | $ git log github/master.. 21 | 22 | Once you run the 'rebase -i' command, you will be thrown into your editor 23 | of choice with something that looks like this: 24 | 25 | pick fc62e55 added file_size 26 | pick 9824bf4 fixed little thing 27 | pick 21d80a5 added number to log 28 | pick 76b9da6 added the apply command 29 | pick c264051 Revert "added file_size" - not implemented correctly 30 | 31 | # Rebase f408319..b04dc3d onto f408319 32 | # 33 | # Commands: 34 | # p, pick = use commit 35 | # e, edit = use commit, but stop for amending 36 | # s, squash = use commit, but meld into previous commit 37 | # 38 | # If you remove a line here THAT COMMIT WILL BE LOST. 39 | # However, if you remove everything, the rebase will be aborted. 40 | # 41 | 42 | This means that there are 5 commits since you last pushed and it gives you 43 | one line per commit with the following format: 44 | 45 | (action) (partial-sha) (short commit message) 46 | 47 | Now, you can change the action (which is by default 'pick') to either 'edit' 48 | or 'squash', or just leave it as 'pick'. You can also reorder the commits 49 | just by moving the lines around however you want. Then, when you exit the 50 | editor, git will try to apply the commits however they are now arranged and 51 | do the action specified. 52 | 53 | If 'pick' is specified, it will simply try to apply the patch and save the 54 | commit with the same message as before. 55 | 56 | If 'squash' is specified, it will combine that commit with the previous one 57 | to create a new commit. This will drop you into your editor again to merge 58 | the commit messages of the two commits it is now squashing together. So, 59 | if you exit the editor with this: 60 | 61 | pick fc62e55 added file_size 62 | squash 9824bf4 fixed little thing 63 | squash 21d80a5 added number to log 64 | squash 76b9da6 added the apply command 65 | squash c264051 Revert "added file_size" - not implemented correctly 66 | 67 | Then you will have to create a single commit message from this: 68 | 69 | # This is a combination of 5 commits. 70 | # The first commit's message is: 71 | added file_size 72 | 73 | # This is the 2nd commit message: 74 | 75 | fixed little thing 76 | 77 | # This is the 3rd commit message: 78 | 79 | added number to log 80 | 81 | # This is the 4th commit message: 82 | 83 | added the apply command 84 | 85 | # This is the 5th commit message: 86 | 87 | Revert "added file_size" - not implemented correctly 88 | 89 | This reverts commit fc62e5543b195f18391886b9f663d5a7eca38e84. 90 | 91 | Once you have edited that down into once commit message and exit the editor, 92 | the commit will be saved with your new message. 93 | 94 | If 'edit' is specified, it will do the same thing, but then pause before 95 | moving on to the next one and drop you into the command line so you can 96 | amend the commit, or change the commit contents somehow. 97 | 98 | If you wanted to split a commit, for instance, you would specify 'edit' for 99 | that commit: 100 | 101 | pick fc62e55 added file_size 102 | pick 9824bf4 fixed little thing 103 | edit 21d80a5 added number to log 104 | pick 76b9da6 added the apply command 105 | pick c264051 Revert "added file_size" - not implemented correctly 106 | 107 | And then when you get to the command line, you revert that commit and create 108 | two (or more) new ones. Lets say 21d80a5 modified two files, file1 and file2, 109 | and you wanted to split them into seperate commits. You could do this after 110 | the rebase dropped you to the command line : 111 | 112 | $ git reset HEAD^ 113 | $ git add file1 114 | $ git commit 'first part of split commit' 115 | $ git add file2 116 | $ git commit 'second part of split commit' 117 | $ git rebase --continue 118 | 119 | And now instead of 5 commits, you would have 6. 120 | 121 | The last useful thing that interactive rebase can do is drop commits for you. 122 | If instead of choosing 'pick', 'squash' or 'edit' for the commit line, you 123 | simply remove the line, it will remove the commit from the history. -------------------------------------------------------------------------------- /text/15_Interactive_Adding/0_ Interactive_Adding.markdown: -------------------------------------------------------------------------------- 1 | ## Interactive Adding ## 2 | 3 | Interactive Adding is a really nice way of working with and visualizing 4 | the Git index. To start it up, simply type 'git add -i'. Git will show 5 | you all the modified files you have and their status. 6 | 7 | $>git add -i 8 | staged unstaged path 9 | 1: unchanged +4/-0 assets/stylesheets/style.css 10 | 2: unchanged +23/-11 layout/book_index_template.html 11 | 3: unchanged +7/-7 layout/chapter_template.html 12 | 4: unchanged +3/-3 script/pdf.rb 13 | 5: unchanged +121/-0 text/14_Interactive_Rebasing/0_ Interactive_Rebasing.markdown 14 | 15 | *** Commands *** 16 | 1: status 2: update 3: revert 4: add untracked 17 | 5: patch 6: diff 7: quit 8: help 18 | What now> 19 | 20 | In this case, we can see that there are 5 modified files that have not been 21 | added to our index yet (unstaged), and even how many lines have been added to 22 | or removed from each. It then shows us an interactive menu of what we can 23 | do in this mode. 24 | 25 | If we want to stage the files, we can type '2' or 'u' for the update mode. 26 | Then I can specify which files I want to stage (add to the index) by typing 27 | in the numbers of the files (in this case, 1-4) 28 | 29 | What now> 2 30 | staged unstaged path 31 | 1: unchanged +4/-0 assets/stylesheets/style.css 32 | 2: unchanged +23/-11 layout/book_index_template.html 33 | 3: unchanged +7/-7 layout/chapter_template.html 34 | 4: unchanged +3/-3 script/pdf.rb 35 | 5: unchanged +121/-0 text/14_Interactive_Rebasing/0_ Interactive_Rebasing.markdown 36 | Update>> 1-4 37 | staged unstaged path 38 | * 1: unchanged +4/-0 assets/stylesheets/style.css 39 | * 2: unchanged +23/-11 layout/book_index_template.html 40 | * 3: unchanged +7/-7 layout/chapter_template.html 41 | * 4: unchanged +3/-3 script/pdf.rb 42 | 5: unchanged +121/-0 text/14_Interactive_Rebasing/0_ Interactive_Rebasing.markdown 43 | Update>> 44 | 45 | If I hit enter, I will be taken back to the main menu where I can see that 46 | the file status has changed: 47 | 48 | What now> status 49 | staged unstaged path 50 | 1: +4/-0 nothing assets/stylesheets/style.css 51 | 2: +23/-11 nothing layout/book_index_template.html 52 | 3: +7/-7 nothing layout/chapter_template.html 53 | 4: +3/-3 nothing script/pdf.rb 54 | 5: unchanged +121/-0 text/14_Interactive_Rebasing/0_ Interactive_Rebasing.markdown 55 | 56 | Now we can see the first four files are staged and the last one is still not. 57 | This is basically a compressed way to see the same information we see when 58 | we run 'git status' from the command line: 59 | 60 | $ git status 61 | # On branch master 62 | # Changes to be committed: 63 | # (use "git reset HEAD ..." to unstage) 64 | # 65 | # modified: assets/stylesheets/style.css 66 | # modified: layout/book_index_template.html 67 | # modified: layout/chapter_template.html 68 | # modified: script/pdf.rb 69 | # 70 | # Changed but not updated: 71 | # (use "git add ..." to update what will be committed) 72 | # 73 | # modified: text/14_Interactive_Rebasing/0_ Interactive_Rebasing.markdown 74 | # 75 | 76 | There are a number of useful things we can do, including unstaging files (3: revert), 77 | adding untracked files (4: add untracked), and viewing diffs (6: diff). Those 78 | are all pretty straightforward. However, there is one command that is pretty 79 | cool here, which is staging patches (5: patch). 80 | 81 | If you type '5' or 'p' in the menu, git will show you your diff patch by patch 82 | (or hunk by hunk) and ask if you want to stage each one. That way you can 83 | actually stage for a commit a part of a file edit. If you've edited a file 84 | and want to only commit part of it and not an unfinished part, or commit 85 | documentation or whitespace changes seperate from substantive changes, you can 86 | use 'git add -i' to do so relatively easily. 87 | 88 | Here I've staged some changes to the book_index_template.html file, but not all 89 | of them: 90 | 91 | staged unstaged path 92 | 1: +4/-0 nothing assets/stylesheets/style.css 93 | 2: +20/-7 +3/-4 layout/book_index_template.html 94 | 3: +7/-7 nothing layout/chapter_template.html 95 | 4: +3/-3 nothing script/pdf.rb 96 | 5: unchanged +121/-0 text/14_Interactive_Rebasing/0_ Interactive_Rebasing.markdown 97 | 6: unchanged +85/-0 text/15_Interactive_Adding/0_ Interactive_Adding.markdown 98 | 99 | When you are done making changes to your index through 'git add -i', you simply 100 | quit (7: quit) and then run 'git commit' to commit the staged changes. Remember 101 | **not** to run 'git commit -a', which will blow away all the careful changes 102 | you've just made and simply commit everything. 103 | 104 | [gitcast:c3_add_interactive]("GitCast #3: Interactive Adding") 105 | -------------------------------------------------------------------------------- /text/16_Stashing/0_ Stashing.markdown: -------------------------------------------------------------------------------- 1 | ## Stashing ## 2 | 3 | While you are in the middle of working on something complicated, you 4 | find an unrelated but obvious and trivial bug. You would like to fix it 5 | before continuing. You can use linkgit:git-stash[1] to save the current 6 | state of your work, and after fixing the bug (or, optionally after doing 7 | so on a different branch and then coming back), unstash the 8 | work-in-progress changes. 9 | 10 | $ git stash save "work in progress for foo feature" 11 | 12 | This command will save your changes away to the `stash`, and 13 | reset your working tree and the index to match the tip of your 14 | current branch. Then you can make your fix as usual. 15 | 16 | ... edit and test ... 17 | $ git commit -a -m "blorpl: typofix" 18 | 19 | After that, you can go back to what you were working on with 20 | `git stash apply`: 21 | 22 | $ git stash apply 23 | 24 | 25 | ### Stash Queue ### 26 | 27 | You can also use stashing to queue up stashed changes. 28 | If you run 'git stash list' you can see which stashes you have saved: 29 | 30 | $>git stash list 31 | stash@{0}: WIP on book: 51bea1d... fixed images 32 | stash@{1}: WIP on master: 9705ae6... changed the browse code to the official repo 33 | 34 | Then you can apply them individually with 'git stash apply stash@{1}'. You 35 | can clear out the list with 'git stash clear'. -------------------------------------------------------------------------------- /text/17_Git_Treeishes/0_ Git_Treeishes.markdown: -------------------------------------------------------------------------------- 1 | ## Git Treeishes ## 2 | 3 | There are a number of ways to refer to a particular commit or tree other 4 | than spelling out the entire 40-character sha. In Git, these are referred 5 | to as a 'treeish'. 6 | 7 | ### Partial Sha ### 8 | 9 | If your commit sha is ' 980e3ccdaac54a0d4de358f3fe5d718027d96aae
', git will 10 | recognize any of the following identically: 11 | 12 | 980e3ccdaac54a0d4de358f3fe5d718027d96aae 13 | 980e3ccdaac54a0d4 14 | 980e3cc 15 | 16 | As long as the partial sha is unique - it can't be confused with another 17 | (which is incredibly unlikely if you use at least 5 characters), git will 18 | expand a partial sha for you. 19 | 20 | ### Branch, Remote or Tag Name ### 21 | 22 | You can always use a branch, remote or tag name instead of a sha, since they 23 | are simply pointers anyhow. If your master branch is on the 980e3 commit and 24 | you've pushed it to origin and have tagged it 'v1.0', then all of the following 25 | are equivalent: 26 | 27 | 980e3ccdaac54a0d4de358f3fe5d718027d96aae 28 | origin/master 29 | refs/remotes/origin/master 30 | master 31 | refs/heads/master 32 | v1.0 33 | refs/tags/v1.0 34 | 35 | Which means the following will give you identical output: 36 | 37 | $ git log master 38 | 39 | $ git log refs/tags/v1.0 40 | 41 | ### Date Spec ### 42 | 43 | The Ref Log that git keeps will allow you to do some relative stuff locally, 44 | such as: 45 | 46 | master@{yesterday} 47 | 48 | master@{1 month ago} 49 | 50 | Which is shorthand for 'where the master branch head was yesterday', etc. Note 51 | that this format can result in different shas on different computers, even if 52 | the master branch is currently pointing to the same place. 53 | 54 | ### Ordinal Spec ### 55 | 56 | This format will give you the Nth previous value of a particular reference. 57 | For example: 58 | 59 | master@{5} 60 | 61 | will give you the 5th prior value of the master head ref. 62 | 63 | ### Carrot Parent ### 64 | 65 | This will give you the Nth parent of a particular commit. This format is only 66 | useful on merge commits - commit objects that have more than one direct parent. 67 | 68 | master^2 69 | 70 | 71 | ### Tilde Spec ### 72 | 73 | The tilde spec will give you the Nth grandparent of a commit object. For example, 74 | 75 | master~2 76 | 77 | will give us the first parent of the first parent of the commit that master 78 | points to. It is equivalent to: 79 | 80 | master^^ 81 | 82 | You can keep doing this, too. The following specs will point to the same commit: 83 | 84 | master^^^^^^ 85 | master~3^~2 86 | master~6 87 | 88 | ### Tree Pointer ### 89 | 90 | This disambiguates a commit from the tree that it points to. If you want the 91 | sha that a commit points to, you can add the '^{tree}' spec to the end of it. 92 | 93 | master^{tree} 94 | 95 | ### Blob Spec ### 96 | 97 | If you want the sha of a particular blob, you can add the blob path at the 98 | end of the treeish, like so: 99 | 100 | master:/path/to/file 101 | 102 | ### Range ### 103 | 104 | Finally, you can specify a range of commits with the range spec. This will 105 | give you all the commits between 7b593b5 and 51bea1 (where 51bea1 is most recent), 106 | excluding 7b593b5 but including 51bea1: 107 | 108 | 7b593b5..51bea1 109 | 110 | This will include every commit *since* 7b593b: 111 | 112 | 7b593b.. 113 | 114 | -------------------------------------------------------------------------------- /text/18_Tracking_Branches/0_ Tracking_Branches.markdown: -------------------------------------------------------------------------------- 1 | ## Tracking Branches ## 2 | 3 | A 'tracking branch' in Git is a local branch that is connected to a remote 4 | branch. When you push and pull on that branch, it automatically pushes and 5 | pulls to the remote branch that it is connected with. 6 | 7 | Use this if you always pull from the same upstream branch into the new 8 | branch, and if you don't want to use "git pull" 9 | explicitly. 10 | 11 | The 'git clone' command automatically sets up a 'master' branch that is 12 | a tracking branch for 'origin/master' - the master branch on the cloned 13 | repository. 14 | 15 | You can create a tracking branch manually by adding the '--track' option 16 | to the 'branch' command in Git. 17 | 18 | git branch --track experimental origin/experimental 19 | 20 | Then when you run: 21 | 22 | $ git pull experimental 23 | 24 | It will automatically fetch from 'origin' and merge 'origin/experimental' 25 | into your local 'experimental' branch. 26 | 27 | Likewise, when you push to origin, it will push what your 'experimental' points to 28 | to origins 'experimental', without having to specify it. -------------------------------------------------------------------------------- /text/19_Finding_in_Git_Grep/0_ Finding_in_Git_Grep.markdown: -------------------------------------------------------------------------------- 1 | ## Finding with Git Grep ## 2 | 3 | Finding files with words or phrases in Git is really easy with the 4 | linkgit:git-grep[1] command. It is possible to do this with the normal 5 | unix 'grep' command, but with 'git grep' you can also search through 6 | previous versions of the project without having to check them out. 7 | 8 | For example, if I wanted to see every place that used the 'xmmap' call in 9 | my git.git repository, I could run this: 10 | 11 | $ git grep xmmap 12 | config.c: contents = xmmap(NULL, contents_sz, PROT_READ, 13 | diff.c: s->data = xmmap(NULL, s->size, PROT_READ, MAP_PRIVATE, fd, 0); 14 | git-compat-util.h:extern void *xmmap(void *start, size_t length, int prot, int fla 15 | read-cache.c: mmap = xmmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, 16 | refs.c: log_mapped = xmmap(NULL, mapsz, PROT_READ, MAP_PRIVATE, logfd, 0); 17 | sha1_file.c: map = xmmap(NULL, mapsz, PROT_READ, MAP_PRIVATE, fd, 0); 18 | sha1_file.c: idx_map = xmmap(NULL, idx_size, PROT_READ, MAP_PRIVATE, fd, 0); 19 | sha1_file.c: win->base = xmmap(NULL, win->len, 20 | sha1_file.c: map = xmmap(NULL, *size, PROT_READ, MAP_PRIVATE, f 21 | sha1_file.c: buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); 22 | wrapper.c:void *xmmap(void *start, size_t length, 23 | 24 | If I wanted to see the line number of each match as well, I can add the '-n' 25 | option: 26 | 27 | $>git grep -n xmmap 28 | config.c:1016: contents = xmmap(NULL, contents_sz, PROT_READ, 29 | diff.c:1833: s->data = xmmap(NULL, s->size, PROT_READ, MAP_PRIVATE, fd, 30 | git-compat-util.h:291:extern void *xmmap(void *start, size_t length, int prot, int 31 | read-cache.c:1178: mmap = xmmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_ 32 | refs.c:1345: log_mapped = xmmap(NULL, mapsz, PROT_READ, MAP_PRIVATE, logfd, 0); 33 | sha1_file.c:377: map = xmmap(NULL, mapsz, PROT_READ, MAP_PRIVATE, fd, 0); 34 | sha1_file.c:479: idx_map = xmmap(NULL, idx_size, PROT_READ, MAP_PRIVATE, fd 35 | sha1_file.c:780: win->base = xmmap(NULL, win->len, 36 | sha1_file.c:1076: map = xmmap(NULL, *size, PROT_READ, MAP_PR 37 | sha1_file.c:2393: buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd 38 | wrapper.c:89:void *xmmap(void *start, size_t length, 39 | 40 | If we're only interested in the filename, we can pass the '--name-only' option: 41 | 42 | $>git grep --name-only xmmap 43 | config.c 44 | diff.c 45 | git-compat-util.h 46 | read-cache.c 47 | refs.c 48 | sha1_file.c 49 | wrapper.c 50 | 51 | We could also see how many line matches we have in each file with the '-c' 52 | option: 53 | 54 | $>git grep -c xmmap 55 | config.c:1 56 | diff.c:1 57 | git-compat-util.h:1 58 | read-cache.c:1 59 | refs.c:1 60 | sha1_file.c:5 61 | wrapper.c:1 62 | 63 | Now, if I wanted to see where that was used in a specific version of git, I 64 | could add the tag reference to the end, like this: 65 | 66 | $ git grep xmmap v1.5.0 67 | v1.5.0:config.c: contents = xmmap(NULL, st.st_size, PROT_READ, 68 | v1.5.0:diff.c: s->data = xmmap(NULL, s->size, PROT_READ, MAP_PRIVATE, fd, 69 | v1.5.0:git-compat-util.h:static inline void *xmmap(void *start, size_t length, 70 | v1.5.0:read-cache.c: cache_mmap = xmmap(NULL, cache_mmap_size, 71 | v1.5.0:refs.c: log_mapped = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, logfd 72 | v1.5.0:sha1_file.c: map = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 73 | v1.5.0:sha1_file.c: idx_map = xmmap(NULL, idx_size, PROT_READ, MAP_PRIVATE, fd 74 | v1.5.0:sha1_file.c: win->base = xmmap(NULL, win->len, 75 | v1.5.0:sha1_file.c: map = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 76 | v1.5.0:sha1_file.c: buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd 77 | 78 | We can see that there are some differences between the current lines and these 79 | lines in version 1.5.0, one of which is that xmmap is now used in wrapper.c where 80 | it was not back in v1.5.0. 81 | 82 | We can also combine search terms in grep. Say we wanted to search for where 83 | SORT_DIRENT is defined in our repository: 84 | 85 | $ git grep -e '#define' --and -e SORT_DIRENT 86 | builtin-fsck.c:#define SORT_DIRENT 0 87 | builtin-fsck.c:#define SORT_DIRENT 1 88 | 89 | We can also search for every file that has *both* search terms, but display 90 | each line that has *either* of the terms in those files: 91 | 92 | $ git grep --all-match -e '#define' -e SORT_DIRENT 93 | builtin-fsck.c:#define REACHABLE 0x0001 94 | builtin-fsck.c:#define SEEN 0x0002 95 | builtin-fsck.c:#define ERROR_OBJECT 01 96 | builtin-fsck.c:#define ERROR_REACHABLE 02 97 | builtin-fsck.c:#define SORT_DIRENT 0 98 | builtin-fsck.c:#define DIRENT_SORT_HINT(de) 0 99 | builtin-fsck.c:#define SORT_DIRENT 1 100 | builtin-fsck.c:#define DIRENT_SORT_HINT(de) ((de)->d_ino) 101 | builtin-fsck.c:#define MAX_SHA1_ENTRIES (1024) 102 | builtin-fsck.c: if (SORT_DIRENT) 103 | 104 | We can also search for lines that have one term and either of two other terms, 105 | for example, if we wanted to see where we defined constants that had either 106 | PATH or MAX in the name: 107 | 108 | $ git grep -e '#define' --and \( -e PATH -e MAX \) 109 | abspath.c:#define MAXDEPTH 5 110 | builtin-blame.c:#define MORE_THAN_ONE_PATH (1u<<13) 111 | builtin-blame.c:#define MAXSG 16 112 | builtin-describe.c:#define MAX_TAGS (FLAG_BITS - 1) 113 | builtin-fetch-pack.c:#define MAX_IN_VAIN 256 114 | builtin-fsck.c:#define MAX_SHA1_ENTRIES (1024) 115 | ... 116 | 117 | 118 | -------------------------------------------------------------------------------- /text/21_Redoing_Git_Reset_and_Revert/0_ Redoing_Git_Reset_and_Revert.markdown: -------------------------------------------------------------------------------- 1 | ## Undoing in Git - Reset, Checkout and Revert ## 2 | 3 | Git provides multiple methods for fixing up mistakes as you 4 | are developing. Selecting an appropriate method depends on whether 5 | or not you have committed the mistake, and if you have committed the 6 | mistake, whether you have shared the erroneous commit with anyone else. 7 | 8 | ### Fixing un-committed mistakes ### 9 | 10 | If you've messed up the working tree, but haven't yet committed your 11 | mistake, you can return the entire working tree to the last committed 12 | state with 13 | 14 | $ git reset --hard HEAD 15 | 16 | This will throw away any changes you may have added to the git index 17 | and as well as any outstanding changes you have in your working tree. 18 | In other words, it causes the results of "git diff" and "git diff --cached" 19 | to both be empty. 20 | 21 | If you just want to restore just one file, say your hello.rb, use 22 | linkgit:git-checkout[1] instead 23 | 24 | $ git checkout -- hello.rb 25 | $ git checkout HEAD hello.rb 26 | 27 | The first command restores hello.rb to the version in the index, 28 | so that "git diff hello.rb" returns no differences. The second command 29 | will restore hello.rb to the version in the HEAD revision, so 30 | that both "git diff hello.rb" and "git diff --cached hello.rb" 31 | return no differences. 32 | 33 | ### Fixing committed mistakes ### 34 | 35 | If you make a commit that you later wish you hadn't, there are two 36 | fundamentally different ways to fix the problem: 37 | 38 | 1. You can create a new commit that undoes whatever was done 39 | by the old commit. This is the correct thing if your 40 | mistake has already been made public. 41 | 42 | 2. You can go back and modify the old commit. You should 43 | never do this if you have already made the history public; 44 | git does not normally expect the "history" of a project to 45 | change, and cannot correctly perform repeated merges from 46 | a branch that has had its history changed. 47 | 48 | #### Fixing a mistake with a new commit #### 49 | 50 | Creating a new commit that reverts an earlier change is very easy; 51 | just pass the linkgit:git-revert[1] command a reference to the bad 52 | commit; for example, to revert the most recent commit: 53 | 54 | $ git revert HEAD 55 | 56 | This will create a new commit which undoes the change in HEAD. You 57 | will be given a chance to edit the commit message for the new commit. 58 | 59 | You can also revert an earlier change, for example, the next-to-last: 60 | 61 | $ git revert HEAD^ 62 | 63 | In this case git will attempt to undo the old change while leaving 64 | intact any changes made since then. If more recent changes overlap 65 | with the changes to be reverted, then you will be asked to fix 66 | conflicts manually, just as in the case of resolving a merge. 67 | 68 | #### Fixing a mistake by modifying a commit #### 69 | 70 | If you have just committed something but realize you need to fix 71 | up that commit, recent versions of linkgit:git-commit[1] support an 72 | **--amend** flag which instructs git to replace the HEAD commit 73 | with a new one, based on the current contents of the index. This 74 | gives you an opportunity to add files that you forgot to add or 75 | correct typos in a commit message, prior to pushing the change 76 | out for the world to see. 77 | 78 | If you find a mistake in an older commit, but still one that you 79 | have not yet published to the world, you use linkgit:git-rebase[1] 80 | in interactive mode, with "git rebase -i" marking the change 81 | that requires correction with **edit**. This will allow you 82 | to amend the commit during the rebasing process. 83 | -------------------------------------------------------------------------------- /text/22_Maintaining_Git_Gc_Prune_Fsck/0_ Maintaining_Git_Gc_Prune_Fsck.markdown: -------------------------------------------------------------------------------- 1 | ## Maintaining Git ## 2 | 3 | ### Ensuring good performance ### 4 | 5 | On large repositories, git depends on compression to keep the history 6 | information from taking up too much space on disk or in memory. 7 | 8 | This compression is not performed automatically. Therefore you 9 | should occasionally run linkgit:git-gc[1]: 10 | 11 | $ git gc 12 | 13 | to recompress the archive. This can be very time-consuming, so 14 | you may prefer to run git-gc when you are not doing other work. 15 | 16 | 17 | ### Ensuring reliability ### 18 | 19 | The linkgit:git-fsck[1] command runs a number of self-consistency checks 20 | on the repository, and reports on any problems. This may take some 21 | time. The most common warning by far is about "dangling" objects: 22 | 23 | $ git fsck 24 | dangling commit 7281251ddd2a61e38657c827739c57015671a6b3 25 | dangling commit 2706a059f258c6b245f298dc4ff2ccd30ec21a63 26 | dangling commit 13472b7c4b80851a1bc551779171dcb03655e9b5 27 | dangling blob 218761f9d90712d37a9c5e36f406f92202db07eb 28 | dangling commit bf093535a34a4d35731aa2bd90fe6b176302f14f 29 | dangling commit 8e4bec7f2ddaa268bef999853c25755452100f8e 30 | dangling tree d50bb86186bf27b681d25af89d3b5b68382e4085 31 | dangling tree b24c2473f1fd3d91352a624795be026d64c8841f 32 | ... 33 | 34 | Dangling objects are not a problem. At worst they may take up a little 35 | extra disk space. They can sometimes provide a last-resort method for 36 | recovering lost work. 37 | -------------------------------------------------------------------------------- /text/230_Setting_Up_A_Public_Repo_Git_Http_Ssh_Gitosis/0_ Setting_Up_A_Public_Repo.markdown: -------------------------------------------------------------------------------- 1 | ## Setting Up A Public Repository ## 2 | 3 | Assume your personal repository is in the directory ~/proj. We 4 | first create a new clone of the repository and tell git-daemon that it 5 | is meant to be public: 6 | 7 | $ git clone --bare ~/proj proj.git 8 | $ touch proj.git/git-daemon-export-ok 9 | 10 | The resulting directory proj.git contains a "bare" git repository--it is 11 | just the contents of the ".git" directory, without any files checked out 12 | around it. 13 | 14 | Next, copy proj.git to the server where you plan to host the 15 | public repository. You can use scp, rsync, or whatever is most 16 | convenient. 17 | 18 | ### Exporting a git repository via the git protocol ### 19 | 20 | This is the preferred method. 21 | 22 | If someone else administers the server, they should tell you what 23 | directory to put the repository in, and what git:// URL it will appear 24 | at. 25 | 26 | Otherwise, all you need to do is start linkgit:git-daemon[1]; it will 27 | listen on port 9418. By default, it will allow access to any directory 28 | that looks like a git directory and contains the magic file 29 | git-daemon-export-ok. Passing some directory paths as git-daemon 30 | arguments will further restrict the exports to those paths. 31 | 32 | You can also run git-daemon as an inetd service; see the 33 | linkgit:git-daemon[1] man page for details. (See especially the 34 | examples section.) 35 | 36 | ### Exporting a git repository via http ### 37 | 38 | The git protocol gives better performance and reliability, but on a 39 | host with a web server set up, http exports may be simpler to set up. 40 | 41 | All you need to do is place the newly created bare git repository in 42 | a directory that is exported by the web server, and make some 43 | adjustments to give web clients some extra information they need: 44 | 45 | $ mv proj.git /home/you/public_html/proj.git 46 | $ cd proj.git 47 | $ git --bare update-server-info 48 | $ chmod a+x hooks/post-update 49 | 50 | (For an explanation of the last two lines, see 51 | linkgit:git-update-server-info[1] and linkgit:githooks[5].) 52 | 53 | Advertise the URL of proj.git. Anybody else should then be able to 54 | clone or pull from that URL, for example with a command line like: 55 | 56 | $ git clone http://yourserver.com/~you/proj.git 57 | -------------------------------------------------------------------------------- /text/23A_Setting_Up_Private_Repo/0_Setting_Up_Private_Repo.markdown: -------------------------------------------------------------------------------- 1 | ## Setting Up a Private Repository ## 2 | 3 | If you need to setup a private repository and want to do so locally, 4 | rather than using a hosted solution, you have a number of options. 5 | 6 | ### Repo Access over SSH ### 7 | 8 | Generally, the easiest solution is to simply use Git over SSH. If users 9 | already have ssh accounts on a machine, you can put the git repository 10 | anywhere on the box that they have access to and let them access it over 11 | normal ssh logins. For example, say you have a repository you want to 12 | host. You can export it as a bare repo and then scp it onto your server 13 | like so: 14 | 15 | $ git clone --bare /home/user/myrepo/.git /tmp/myrepo.git 16 | $ scp -r /tmp/myrepo.git myserver.com:/opt/git/myrepo.git 17 | 18 | Then someone else with an ssh account on myserver.com can clone via: 19 | 20 | $ git clone myserver.com:/opt/git/myrepo.git 21 | 22 | Which will simply prompt them for thier ssh password or use thier public key, 23 | however they have ssh authentication setup. 24 | 25 | ### Multiple User Access using Gitosis ### 26 | 27 | If you don't want to setup seperate accounts for every user, you can use 28 | a tool called Gitosis. In gitosis, there is an authorized_keys file that 29 | contains the public keys of everyone authorized to access the repository, 30 | and then everyone uses the 'git' user to do pushes and pulls. 31 | 32 | [Installing and Setting up Gitosis](http://www.urbanpuddle.com/articles/2008/07/11/installing-git-on-a-server-ubuntu-or-debian) -------------------------------------------------------------------------------- /text/24_Creating_New_Empty_Branches/00_Section_Advanced_Git.markdown: -------------------------------------------------------------------------------- 1 | # Advanced Git # 2 | 3 | -------------------------------------------------------------------------------- /text/24_Creating_New_Empty_Branches/0_ Creating_New_Empty_Branches.markdown: -------------------------------------------------------------------------------- 1 | ## Creating New Empty Branches ## 2 | 3 | Ocasionally, you may want to keep branches in your repository that do not 4 | share an ancestor with your normal code. Some examples of this might be 5 | generated documentation or something along those lines. If you want to 6 | create a new branch head that does not use your current codebase as a 7 | parent, you can create an empty branch like this: 8 | 9 | git symbolic-ref HEAD refs/heads/newbranch 10 | rm .git/index 11 | git clean -fdx 12 | 13 | git add your files 14 | git commit -m 'Initial commit' 15 | 16 | [gitcast:c9-empty-branch]("GitCast #7: Creating Empty Branches") 17 | -------------------------------------------------------------------------------- /text/25_Changing_Your_History/0_Changing_History.markdown: -------------------------------------------------------------------------------- 1 | ## Modifying your History ## 2 | 3 | Interactive rebasing is a good way to modify individual commits. 4 | 5 | linkgit:git-filter-branch[1] is a good way to edit commits en masse. 6 | 7 | -------------------------------------------------------------------------------- /text/26_Advanced_Branching_And_Merging/0_Advanced_Branching_And_Merging.markdown: -------------------------------------------------------------------------------- 1 | ## Advanced Branching And Merging ## 2 | 3 | ### Getting conflict-resolution help during a merge ### 4 | 5 | All of the changes that git was able to merge automatically are 6 | already added to the index file, so linkgit:git-diff[1] shows only 7 | the conflicts. It uses an unusual syntax: 8 | 9 | $ git diff 10 | diff --cc file.txt 11 | index 802992c,2b60207..0000000 12 | --- a/file.txt 13 | +++ b/file.txt 14 | @@@ -1,1 -1,1 +1,5 @@@ 15 | ++<<<<<<< HEAD:file.txt 16 | +Hello world 17 | ++======= 18 | + Goodbye 19 | ++>>>>>>> 77976da35a11db4580b80ae27e8d65caf5208086:file.txt 20 | 21 | Recall that the commit which will be committed after we resolve this 22 | conflict will have two parents instead of the usual one: one parent 23 | will be HEAD, the tip of the current branch; the other will be the 24 | tip of the other branch, which is stored temporarily in MERGE_HEAD. 25 | 26 | During the merge, the index holds three versions of each file. Each of 27 | these three "file stages" represents a different version of the file: 28 | 29 | $ git show :1:file.txt # the file in a common ancestor of both branches 30 | $ git show :2:file.txt # the version from HEAD. 31 | $ git show :3:file.txt # the version from MERGE_HEAD. 32 | 33 | When you ask linkgit:git-diff[1] to show the conflicts, it runs a 34 | three-way diff between the conflicted merge results in the work tree with 35 | stages 2 and 3 to show only hunks whose contents come from both sides, 36 | mixed (in other words, when a hunk's merge results come only from stage 2, 37 | that part is not conflicting and is not shown. Same for stage 3). 38 | 39 | The diff above shows the differences between the working-tree version of 40 | file.txt and the stage 2 and stage 3 versions. So instead of preceding 41 | each line by a single "+" or "-", it now uses two columns: the first 42 | column is used for differences between the first parent and the working 43 | directory copy, and the second for differences between the second parent 44 | and the working directory copy. (See the "COMBINED DIFF FORMAT" section 45 | of linkgit:git-diff-files[1] for a details of the format.) 46 | 47 | After resolving the conflict in the obvious way (but before updating the 48 | index), the diff will look like: 49 | 50 | $ git diff 51 | diff --cc file.txt 52 | index 802992c,2b60207..0000000 53 | --- a/file.txt 54 | +++ b/file.txt 55 | @@@ -1,1 -1,1 +1,1 @@@ 56 | - Hello world 57 | -Goodbye 58 | ++Goodbye world 59 | 60 | This shows that our resolved version deleted "Hello world" from the 61 | first parent, deleted "Goodbye" from the second parent, and added 62 | "Goodbye world", which was previously absent from both. 63 | 64 | Some special diff options allow diffing the working directory against 65 | any of these stages: 66 | 67 | $ git diff -1 file.txt # diff against stage 1 68 | $ git diff --base file.txt # same as the above 69 | $ git diff -2 file.txt # diff against stage 2 70 | $ git diff --ours file.txt # same as the above 71 | $ git diff -3 file.txt # diff against stage 3 72 | $ git diff --theirs file.txt # same as the above. 73 | 74 | The linkgit:git-log[1] and linkgit:gitk[1] commands also provide special help 75 | for merges: 76 | 77 | $ git log --merge 78 | $ gitk --merge 79 | 80 | These will display all commits which exist only on HEAD or on 81 | MERGE_HEAD, and which touch an unmerged file. 82 | 83 | You may also use linkgit:git-mergetool[1], which lets you merge the 84 | unmerged files using external tools such as emacs or kdiff3. 85 | 86 | Each time you resolve the conflicts in a file and update the index: 87 | 88 | $ git add file.txt 89 | 90 | the different stages of that file will be "collapsed", after which 91 | git-diff will (by default) no longer show diffs for that file. -------------------------------------------------------------------------------- /text/26_Advanced_Branching_And_Merging/1_Advanced_Merging_Multiway_Merge_Subtree.markdown: -------------------------------------------------------------------------------- 1 | ### Multiway Merge ### 2 | 3 | You can merge several heads at one time by simply listing them on the same 4 | linkgit:git-merge[1] command. For instance, 5 | 6 | $ git merge scott/master rick/master tom/master 7 | 8 | is the equivalent of: 9 | 10 | $ git merge scott/master 11 | $ git merge rick/master 12 | $ git merge tom/master 13 | 14 | ### Subtree ### 15 | 16 | There are situations where you want to include contents in your project from 17 | an independently developed project. You can just pull from the other project 18 | as long as there are no conflicting paths. 19 | 20 | The problematic case is when there are conflicting files. Potential 21 | candidates are Makefiles and other standard filenames. You could merge 22 | these files but probably you do not want to. A better solution for this 23 | problem can be to merge the project as its own subdirectory. This is not 24 | supported by the recursive merge strategy, so just pulling won't work. 25 | 26 | What you want is the subtree merge strategy, which helps you in such a situation. 27 | 28 | In this example, let's say you have the repository at /path/to/B 29 | (but it can be an URL as well, if you want). You want to merge the master 30 | branch of that repository to the dir-B subdirectory in your current branch. 31 | 32 | Here is the command sequence you need: 33 | 34 | $ git remote add -f Bproject /path/to/B (1) 35 | $ git merge -s ours --no-commit Bproject/master (2) 36 | $ git read-tree --prefix=dir-B/ -u Bproject/master (3) 37 | $ git commit -m "Merge B project as our subdirectory" (4) 38 | $ git pull -s subtree Bproject master (5) 39 | 40 | 41 | The benefit of using subtree merge is that it requires less administrative 42 | burden from the users of your repository. It works with older 43 | (before Git v1.5.2) clients and you have the code right after clone. 44 | 45 | However if you use submodules then you can choose not to transfer the 46 | submodule objects. This may be a problem with the subtree merge. 47 | 48 | Also, in case you make changes to the other project, it is easier to 49 | submit changes if you just use submodules. 50 | 51 | (from [Using Subtree Merge](http://www.kernel.org/pub/software/scm/git/docs/howto/using-merge-subtree.html)) 52 | 53 | 54 | -------------------------------------------------------------------------------- /text/27_Finding_Issues_Git_Bisect/0_ Finding_Issues_Git_Bisect.markdown: -------------------------------------------------------------------------------- 1 | ## Finding Issues - Git Bisect ## 2 | 3 | Suppose version 2.6.18 of your project worked, but the version at 4 | "master" crashes. Sometimes the best way to find the cause of such a 5 | regression is to perform a brute-force search through the project's 6 | history to find the particular commit that caused the problem. The 7 | linkgit:git-bisect[1] command can help you do this: 8 | 9 | $ git bisect start 10 | $ git bisect good v2.6.18 11 | $ git bisect bad master 12 | Bisecting: 3537 revisions left to test after this 13 | [65934a9a028b88e83e2b0f8b36618fe503349f8e] BLOCK: Make USB storage depend on SCSI rather than selecting it [try #6] 14 | 15 | If you run "git branch" at this point, you'll see that git has 16 | temporarily moved you to a new branch named "bisect". This branch 17 | points to a commit (with commit id 65934...) that is reachable from 18 | "master" but not from v2.6.18. Compile and test it, and see whether 19 | it crashes. Assume it does crash. Then: 20 | 21 | $ git bisect bad 22 | Bisecting: 1769 revisions left to test after this 23 | [7eff82c8b1511017ae605f0c99ac275a7e21b867] i2c-core: Drop useless bitmaskings 24 | 25 | checks out an older version. Continue like this, telling git at each 26 | stage whether the version it gives you is good or bad, and notice 27 | that the number of revisions left to test is cut approximately in 28 | half each time. 29 | 30 | After about 13 tests (in this case), it will output the commit id of 31 | the guilty commit. You can then examine the commit with 32 | linkgit:git-show[1], find out who wrote it, and mail them your bug 33 | report with the commit id. Finally, run 34 | 35 | $ git bisect reset 36 | 37 | to return you to the branch you were on before and delete the 38 | temporary "bisect" branch. 39 | 40 | Note that the version which git-bisect checks out for you at each 41 | point is just a suggestion, and you're free to try a different 42 | version if you think it would be a good idea. For example, 43 | occasionally you may land on a commit that broke something unrelated; 44 | run 45 | 46 | $ git bisect visualize 47 | 48 | which will run gitk and label the commit it chose with a marker that 49 | says "bisect". Choose a safe-looking commit nearby, note its commit 50 | id, and check it out with: 51 | 52 | $ git reset --hard fb47ddb2db... 53 | 54 | then test, run "bisect good" or "bisect bad" as appropriate, and 55 | continue. -------------------------------------------------------------------------------- /text/28_Finding_Issues_Git_Blame/0_ Finding_Issues_Git_Blame.markdown: -------------------------------------------------------------------------------- 1 | ## Finding Issues - Git Blame ## 2 | 3 | The linkgit:git-blame[1] command is really helpful for figuring out who changed 4 | which sections of a file. If you simple run 'git blame [filename]' you'll get 5 | an output of the entire file with the last commit sha, date and author for every 6 | line in the file. 7 | 8 | $ git blame sha1_file.c 9 | ... 10 | 0fcfd160 (Linus Torvalds 2005-04-18 13:04:43 -0700 8) */ 11 | 0fcfd160 (Linus Torvalds 2005-04-18 13:04:43 -0700 9) #include "cache.h" 12 | 1f688557 (Junio C Hamano 2005-06-27 03:35:33 -0700 10) #include "delta.h" 13 | a733cb60 (Linus Torvalds 2005-06-28 14:21:02 -0700 11) #include "pack.h" 14 | 8e440259 (Peter Eriksen 2006-04-02 14:44:09 +0200 12) #include "blob.h" 15 | 8e440259 (Peter Eriksen 2006-04-02 14:44:09 +0200 13) #include "commit.h" 16 | 8e440259 (Peter Eriksen 2006-04-02 14:44:09 +0200 14) #include "tag.h" 17 | 8e440259 (Peter Eriksen 2006-04-02 14:44:09 +0200 15) #include "tree.h" 18 | f35a6d3b (Linus Torvalds 2007-04-09 21:20:29 -0700 16) #include "refs.h" 19 | 70f5d5d3 (Nicolas Pitre 2008-02-28 00:25:19 -0500 17) #include "pack-revindex.h"628522ec (Junio C Hamano 2007-12-29 02:05:47 -0800 18) #include "sha1-lookup.h" 20 | ... 21 | 22 | This is often helpful if a file had a line reverted or a mistake that broke 23 | the build to help you see who changed that line last. 24 | 25 | You can also specify a start and end line for the blame: 26 | 27 | $>git blame -L 160,+10 sha1_file.c 28 | ace1534d (Junio C Hamano 2005-05-07 00:38:04 -0700 160)} 29 | ace1534d (Junio C Hamano 2005-05-07 00:38:04 -0700 161) 30 | 0fcfd160 (Linus Torvalds 2005-04-18 13:04:43 -0700 162)/* 31 | 0fcfd160 (Linus Torvalds 2005-04-18 13:04:43 -0700 163) * NOTE! This returns a statically allocate 32 | 790296fd (Jim Meyering 2008-01-03 15:18:07 +0100 164) * careful about using it. Do an "xstrdup() 33 | 0fcfd160 (Linus Torvalds 2005-04-18 13:04:43 -0700 165) * filename. 34 | ace1534d (Junio C Hamano 2005-05-07 00:38:04 -0700 166) * 35 | ace1534d (Junio C Hamano 2005-05-07 00:38:04 -0700 167) * Also note that this returns the location 36 | ace1534d (Junio C Hamano 2005-05-07 00:38:04 -0700 168) * SHA1 file can happen from any alternate 37 | d19938ab (Junio C Hamano 2005-05-09 17:57:56 -0700 169) * DB_ENVIRONMENT environment variable if i 38 | 39 | -------------------------------------------------------------------------------- /text/29_Git_and_Email_Am_Format_Patch/0_ Git_and_Email_Am_Format.markdown: -------------------------------------------------------------------------------- 1 | ## Git and Email ## 2 | 3 | ### Submitting patches to a project ### 4 | 5 | If you just have a few changes, the simplest way to submit them may 6 | just be to send them as patches in email: 7 | 8 | First, use linkgit:git-format-patch[1]; for example: 9 | 10 | $ git format-patch origin 11 | 12 | will produce a numbered series of files in the current directory, one 13 | for each patch in the current branch but not in origin/HEAD. 14 | 15 | You can then import these into your mail client and send them by 16 | hand. However, if you have a lot to send at once, you may prefer to 17 | use the linkgit:git-send-email[1] script to automate the process. 18 | Consult the mailing list for your project first to determine how they 19 | prefer such patches be handled. 20 | 21 | 22 | ### Importing patches to a project ### 23 | 24 | Git also provides a tool called linkgit:git-am[1] (am stands for 25 | "apply mailbox"), for importing such an emailed series of patches. 26 | Just save all of the patch-containing messages, in order, into a 27 | single mailbox file, say "patches.mbox", then run 28 | 29 | $ git am -3 patches.mbox 30 | 31 | Git will apply each patch in order; if any conflicts are found, it 32 | will stop, and you can manually fix the conflicts and 33 | resolve the merge. (The "-3" option tells 34 | git to perform a merge; if you would prefer it just to abort and 35 | leave your tree and index untouched, you may omit that option.) 36 | 37 | Once the index is updated with the results of the conflict 38 | resolution, instead of creating a new commit, just run 39 | 40 | $ git am --resolved 41 | 42 | and git will create the commit for you and continue applying the 43 | remaining patches from the mailbox. 44 | 45 | The final result will be a series of commits, one for each patch in 46 | the original mailbox, with authorship and commit log message each 47 | taken from the message containing each patch. 48 | -------------------------------------------------------------------------------- /text/30_Customizing_Git_Git_Config/0_ Customizing_Git_Git_Config.markdown: -------------------------------------------------------------------------------- 1 | ## Customizing Git ## 2 | 3 | linkgit:git-config[1] 4 | 5 | ### Changing your Editor ### 6 | 7 | $ git config --global core.editor emacs 8 | 9 | ### Adding Aliases ### 10 | 11 | $ git config --global alias.last 'cat-file commit HEAD' 12 | 13 | $ git last 14 | tree c85fbd1996b8e7e5eda1288b56042c0cdb91836b 15 | parent cdc9a0a28173b6ba4aca00eb34f5aabb39980735 16 | author Scott Chacon 1220473867 -0700 17 | committer Scott Chacon 1220473867 -0700 18 | 19 | fixed a weird formatting problem 20 | 21 | $ git cat-file commit HEAD 22 | tree c85fbd1996b8e7e5eda1288b56042c0cdb91836b 23 | parent cdc9a0a28173b6ba4aca00eb34f5aabb39980735 24 | author Scott Chacon 1220473867 -0700 25 | committer Scott Chacon 1220473867 -0700 26 | 27 | fixed a weird formatting problem 28 | 29 | ### Adding Color ### 30 | 31 | See all color.* options in the linkgit:git-config[1] docs 32 | 33 | $ git config color.branch auto 34 | $ git config color.diff auto 35 | $ git config color.interactive auto 36 | $ git config color.status auto 37 | 38 | Or, you can set all of them on with the color.ui option: 39 | 40 | $ git config color.ui true 41 | 42 | ### Commit Template ### 43 | 44 | $ git config commit.template '/etc/git-commit-template' 45 | 46 | ### Log Format ### 47 | 48 | $ git config format.pretty oneline 49 | 50 | 51 | ### Other Config Options ### 52 | 53 | There are also a number of interesting options for packing, gc-ing, merging, 54 | remotes, branches, http transport, diffs, paging, whitespace and more. If you 55 | want to tweak these, check out the linkgit:git-config[1] docs. -------------------------------------------------------------------------------- /text/32_Git_Recovery_Corrupted_Objects/0_ Git_Recovery_Corrupted_Objects.markdown: -------------------------------------------------------------------------------- 1 | ## Recovering Corrupted Objects ## 2 | 3 | [Recovering Lost Commits Blog Post](http://programblings.com/2008/06/07/the-illustrated-guide-to-recovering-lost-commits-with-git) 4 | 5 | [Recovering Corrupted Blobs by Linus](http://www.kernel.org/pub/software/scm/git/docs/howto/recover-corrupted-blob-object.txt) 6 | -------------------------------------------------------------------------------- /text/34_Git_Submodules/1_Submodules.markdown: -------------------------------------------------------------------------------- 1 | ## Submodules ## 2 | 3 | Large projects are often composed of smaller, self-contained modules. For 4 | example, an embedded Linux distribution's source tree would include every 5 | piece of software in the distribution with some local modifications; a movie 6 | player might need to build against a specific, known-working version of a 7 | decompression library; several independent programs might all share the same 8 | build scripts. 9 | 10 | With centralized revision control systems this is often accomplished by 11 | including every module in one single repository. Developers can check out 12 | all modules or only the modules they need to work with. They can even modify 13 | files across several modules in a single commit while moving things around 14 | or updating APIs and translations. 15 | 16 | Git does not allow partial checkouts, so duplicating this approach in Git 17 | would force developers to keep a local copy of modules they are not 18 | interested in touching. Commits in an enormous checkout would be slower 19 | than you'd expect as Git would have to scan every directory for changes. 20 | If modules have a lot of local history, clones would take forever. 21 | 22 | On the plus side, distributed revision control systems can much better 23 | integrate with external sources. In a centralized model, a single arbitrary 24 | snapshot of the external project is exported from its own revision control 25 | and then imported into the local revision control on a vendor branch. All 26 | the history is hidden. With distributed revision control you can clone the 27 | entire external history and much more easily follow development and re-merge 28 | local changes. 29 | 30 | Git's submodule support allows a repository to contain, as a subdirectory, a 31 | checkout of an external project. Submodules maintain their own identity; 32 | the submodule support just stores the submodule repository location and 33 | commit ID, so other developers who clone the containing project 34 | ("superproject") can easily clone all the submodules at the same revision. 35 | Partial checkouts of the superproject are possible: you can tell Git to 36 | clone none, some or all of the submodules. 37 | 38 | The linkgit:git-submodule[1] command is available since Git 1.5.3. Users 39 | with Git 1.5.2 can look up the submodule commits in the repository and 40 | manually check them out; earlier versions won't recognize the submodules at 41 | all. 42 | 43 | To see how submodule support works, create (for example) four example 44 | repositories that can be used later as a submodule: 45 | 46 | $ mkdir ~/git 47 | $ cd ~/git 48 | $ for i in a b c d 49 | do 50 | mkdir $i 51 | cd $i 52 | git init 53 | echo "module $i" > $i.txt 54 | git add $i.txt 55 | git commit -m "Initial commit, submodule $i" 56 | cd .. 57 | done 58 | 59 | Now create the superproject and add all the submodules: 60 | 61 | $ mkdir super 62 | $ cd super 63 | $ git init 64 | $ for i in a b c d 65 | do 66 | git submodule add ~/git/$i $i 67 | done 68 | 69 | NOTE: Do not use local URLs here if you plan to publish your superproject! 70 | 71 | See what files `git-submodule` created: 72 | 73 | $ ls -a 74 | . .. .git .gitmodules a b c d 75 | 76 | The `git-submodule add` command does a couple of things: 77 | 78 | - It clones the submodule under the current directory and by default checks out 79 | the master branch. 80 | - It adds the submodule's clone path to the linkgit:gitmodules[5] file and 81 | adds this file to the index, ready to be committed. 82 | - It adds the submodule's current commit ID to the index, ready to be 83 | committed. 84 | 85 | Commit the superproject: 86 | 87 | 88 | $ git commit -m "Add submodules a, b, c and d." 89 | 90 | Now clone the superproject: 91 | 92 | $ cd .. 93 | $ git clone super cloned 94 | $ cd cloned 95 | 96 | The submodule directories are there, but they're empty: 97 | 98 | $ ls -a a 99 | . .. 100 | $ git submodule status 101 | -d266b9873ad50488163457f025db7cdd9683d88b a 102 | -e81d457da15309b4fef4249aba9b50187999670d b 103 | -c1536a972b9affea0f16e0680ba87332dc059146 c 104 | -d96249ff5d57de5de093e6baff9e0aafa5276a74 d 105 | 106 | NOTE: The commit object names shown above would be different for you, but they 107 | should match the HEAD commit object names of your repositories. You can check 108 | it by running `git ls-remote ../git/a`. 109 | 110 | Pulling down the submodules is a two-step process. First run `git submodule 111 | init` to add the submodule repository URLs to `.git/config`: 112 | 113 | $ git submodule init 114 | 115 | Now use `git-submodule update` to clone the repositories and check out the 116 | commits specified in the superproject: 117 | 118 | $ git submodule update 119 | $ cd a 120 | $ ls -a 121 | . .. .git a.txt 122 | 123 | One major difference between `git-submodule update` and `git-submodule add` is 124 | that `git-submodule update` checks out a specific commit, rather than the tip 125 | of a branch. It's like checking out a tag: the head is detached, so you're not 126 | working on a branch. 127 | 128 | $ git branch 129 | * (no branch) 130 | master 131 | 132 | If you want to make a change within a submodule and you have a detached head, 133 | then you should create or checkout a branch, make your changes, publish the 134 | change within the submodule, and then update the superproject to reference the 135 | new commit: 136 | 137 | $ git checkout master 138 | 139 | or 140 | 141 | $ git checkout -b fix-up 142 | 143 | then 144 | 145 | $ echo "adding a line again" >> a.txt 146 | $ git commit -a -m "Updated the submodule from within the superproject." 147 | $ git push 148 | $ cd .. 149 | $ git diff 150 | diff --git a/a b/a 151 | index d266b98..261dfac 160000 152 | --- a/a 153 | +++ b/a 154 | @@ -1 +1 @@ 155 | -Subproject commit d266b9873ad50488163457f025db7cdd9683d88b 156 | +Subproject commit 261dfac35cb99d380eb966e102c1197139f7fa24 157 | $ git add a 158 | $ git commit -m "Updated submodule a." 159 | $ git push 160 | 161 | You have to run `git submodule update` after `git pull` if you want to update 162 | submodules, too. 163 | 164 | ###Pitfalls with submodules 165 | 166 | Always publish the submodule change before publishing the change to the 167 | superproject that references it. If you forget to publish the submodule change, 168 | others won't be able to clone the repository: 169 | 170 | $ cd ~/git/super/a 171 | $ echo i added another line to this file >> a.txt 172 | $ git commit -a -m "doing it wrong this time" 173 | $ cd .. 174 | $ git add a 175 | $ git commit -m "Updated submodule a again." 176 | $ git push 177 | $ cd ~/git/cloned 178 | $ git pull 179 | $ git submodule update 180 | error: pathspec '261dfac35cb99d380eb966e102c1197139f7fa24' did not match any file(s) known to git. 181 | Did you forget to 'git add'? 182 | Unable to checkout '261dfac35cb99d380eb966e102c1197139f7fa24' in submodule path 'a' 183 | 184 | If you are staging an updated submodule for commit manually, be careful to not 185 | add a trailing slash when specifying the path. With the slash appended, Git 186 | will assume you are removing the submodule and checking that directory's 187 | contents into the containing repository. 188 | 189 | $ cd ~/git/super/a 190 | $ echo i added another line to this file >> a.txt 191 | $ git commit -a -m "doing it wrong this time" 192 | $ cd .. 193 | $ git add a/ 194 | $ git status 195 | # On branch master 196 | # Changes to be committed: 197 | # (use "git reset HEAD ..." to unstage) 198 | # 199 | # deleted: a 200 | # new file: a/a.txt 201 | # 202 | # Modified submodules: 203 | # 204 | # * a aa5c351...0000000 (1): 205 | # < Initial commit, submodule a 206 | # 207 | 208 | To fix the index after performing this operation, reset the changes and then 209 | add the submodule without the trailing slash. 210 | 211 | $ git reset HEAD A 212 | $ git add a 213 | $ git status 214 | # On branch master 215 | # Changes to be committed: 216 | # (use "git reset HEAD ..." to unstage) 217 | # 218 | # modified: a 219 | # 220 | # Modified submodules: 221 | # 222 | # * a aa5c351...8d3ba36 (1): 223 | # > doing it wrong this time 224 | # 225 | 226 | You also should not rewind branches in a submodule beyond commits that were 227 | ever recorded in any superproject. 228 | 229 | It's not safe to run `git submodule update` if you've made and committed 230 | changes within a submodule without checking out a branch first. They will be 231 | silently overwritten: 232 | 233 | $ cat a.txt 234 | module a 235 | $ echo line added from private2 >> a.txt 236 | $ git commit -a -m "line added inside private2" 237 | $ cd .. 238 | $ git submodule update 239 | Submodule path 'a': checked out 'd266b9873ad50488163457f025db7cdd9683d88b' 240 | $ cd a 241 | $ cat a.txt 242 | module a 243 | 244 | NOTE: The changes are still visible in the submodule's reflog. 245 | 246 | This is not the case if you did not commit your changes. 247 | 248 | [gitcast:c11-git-submodules]("GitCast #11: Git Submodules") 249 | -------------------------------------------------------------------------------- /text/35_Git_on_Windows/00_Section_Working_with_Git.markdown: -------------------------------------------------------------------------------- 1 | #Working with Git -------------------------------------------------------------------------------- /text/35_Git_on_Windows/0_ Git_on_Windows.markdown: -------------------------------------------------------------------------------- 1 | ## Git on Windows ## 2 | 3 | (mSysGit) 4 | 5 | [gitcast:c10-windows-git]("GitCast #10: Git on Windows") 6 | -------------------------------------------------------------------------------- /text/37_Deploying_with_Git/0_ Capistrano_and_Git.markdown: -------------------------------------------------------------------------------- 1 | ## Deploying with Git ## 2 | 3 | ### Capistrano and Git ### 4 | 5 | [GitHub Guide on Deploying with Cap](http://github.com/guides/deploying-with-capistrano) 6 | 7 | [Git and Capistrano Screencast](http://www.vimeo.com/369095) -------------------------------------------------------------------------------- /text/38_Subversion_Integration/0_ Subversion_Integration.markdown: -------------------------------------------------------------------------------- 1 | ##Subversion Integration -------------------------------------------------------------------------------- /text/39_SCM_Migration/0_Scm_Migration.markdown: -------------------------------------------------------------------------------- 1 | ## SCM Migration ## 2 | 3 | So you've made the decision to move away from your existing system 4 | and convert your whole project to Git. How can you do that easily? 5 | 6 | ### Importing Subversion ### 7 | 8 | Git comes with a script called git-svn that has a clone command that 9 | will import a subversion repository into a new git repository. There 10 | is also a free tool on the GitHub service that will do this for you. 11 | 12 | $ git-svn clone http://my-project.googlecode.com/svn/trunk new-project 13 | 14 | This will give you a new Git repository with all the history of the 15 | original Subversion repo. This takes a pretty good amount of time, generally, 16 | since it starts with version 1 and checks out and commits locally every 17 | single revision one by one. 18 | 19 | ### Importing Perforce ### 20 | 21 | In contrib/fast-import you will find the git-p4 script, which is a 22 | Python script that will import a Perforce repository for you. 23 | 24 | $ ~/git.git/contrib/fast-import/git-p4 clone //depot/project/main@all myproject 25 | 26 | 27 | ### Importing Others ### 28 | 29 | These are other SCMs that listed high on the Git Survey, should find import 30 | docs for them. !!TODO!! 31 | 32 | * CVS 33 | * Mercurial (hg) 34 | 35 | * Bazaar-NG 36 | * Darcs 37 | * ClearCase 38 | 39 | -------------------------------------------------------------------------------- /text/40_Graphical_Git_gitgui_gitk/0_ Graphical_Git_gitgui_gitk.markdown: -------------------------------------------------------------------------------- 1 | ## Graphical Git ## 2 | 3 | Git has a couple of fairly popular Graphial User Interfaces that can 4 | read and/or maniplulate Git repositories. 5 | 6 | ### Bundled GUIs ### 7 | 8 | Git comes with two major GUI programs written in Tcl/Tk. Gitk is a 9 | repository browser and commit history visualization tool. 10 | 11 | [gitk](http://www.kernel.org/pub/software/scm/git/docs/gitk.html) 12 | 13 | linkgit:git-gui[1] is a tool that helps you visualize the index operations, 14 | like add, remove and commit. It won't do everything you can do on the 15 | command line, but for many of the basic operations, it's pretty good. 16 | 17 | [git gui](http://www.kernel.org/pub/software/scm/git/docs/git-gui.html) 18 | 19 | ### Third Party Projects ### 20 | 21 | For Mac users, there are 22 | [GitX](http://gitx.frim.nl/) and [GitNub](http://github.com/Caged/gitnub/wikis) 23 | 24 | For Linux or other Qt users, there is 25 | [QGit](http://digilander.libero.it/mcostalba/) 26 | 27 | -------------------------------------------------------------------------------- /text/41_Hosting_Git_gitweb_repoorcz_github_gitorious/0_ Hosting_Git_gitweb_repoorcz_github.markdown: -------------------------------------------------------------------------------- 1 | ## Hosted Git ## 2 | 3 | github 4 | 5 | repoorcz 6 | 7 | -------------------------------------------------------------------------------- /text/42_Alternative_Uses_TicGit/0_ Alternative_Uses_ContentDistribution.markdown: -------------------------------------------------------------------------------- 1 | ## Alternative Uses ## 2 | 3 | ContentDistribution 4 | 5 | TicGit -------------------------------------------------------------------------------- /text/44_Scripting_and_Git/0_ Ruby_and_Git_grit.markdown: -------------------------------------------------------------------------------- 1 | ## Scripting and Git ## 2 | 3 | 4 | ### Ruby and Git ### 5 | 6 | grit 7 | 8 | jgit + jruby 9 | 10 | 11 | ### PHP and Git ### 12 | 13 | 14 | 15 | ### Python and Git ### 16 | 17 | pygit 18 | 19 | 20 | ### Perl and Git ### 21 | 22 | perlgit 23 | 24 | -------------------------------------------------------------------------------- /text/47_Git_and_Editors_tm_eclipse_nb/0_ Git_and_Editors_tm_eclipse.markdown: -------------------------------------------------------------------------------- 1 | ## Git and Editors ## 2 | 3 | textmate 4 | 5 | eclipse 6 | 7 | netbeans -------------------------------------------------------------------------------- /text/48_How_Git_Stores_Objects/00_Section_Internals_and_Plumbing.markdown: -------------------------------------------------------------------------------- 1 | # Internals and Plumbing # 2 | 3 | -------------------------------------------------------------------------------- /text/48_How_Git_Stores_Objects/0_ How_Git_Stores_Objects.markdown: -------------------------------------------------------------------------------- 1 | ## How Git Stores Objects ## 2 | 3 | This chapter goes into detail about how Git physically stores objects. 4 | 5 | All objects are stored as compressed contents by their sha values. They 6 | contain the object type, size and contents in a gzipped format. 7 | 8 | There are two formats that Git keeps objects in - loose objects and 9 | packed objects. 10 | 11 | ### Loose Objects ### 12 | 13 | Loose objects are the simpler format. It is simply the compressed data stored 14 | in a single file on disk. Every object written to a seperate file. 15 | 16 | If the sha of your object is ab04d884140f7b0cf8bbf86d6883869f16a46f65
, 17 | then the file will be stored in the following path: 18 | 19 | GIT_DIR/objects/ab/04d884140f7b0cf8bbf86d6883869f16a46f65 20 | 21 | It pulls the first two characters off and uses that as the subdirectory, so that 22 | there are never too many objects in one directory. The actual file name is 23 | the remaining 38 characters. 24 | 25 | The easiest way to describe exactly how the object data is stored is this Ruby 26 | implementation of object storage: 27 | 28 | ruby 29 | def put_raw_object(content, type) 30 | size = content.length.to_s 31 | 32 | header = "#{type} #{size}\\0" # type(space)size(null byte) 33 | store = header + content 34 | 35 | sha1 = Digest::SHA1.hexdigest(store) 36 | path = @git_dir + '/' + sha1[0...2] + '/' + sha1[2..40] 37 | 38 | if !File.exists?(path) 39 | content = Zlib::Deflate.deflate(store) 40 | 41 | FileUtils.mkdir_p(@directory+'/'+sha1[0...2]) 42 | File.open(path, 'w') do |f| 43 | f.write content 44 | end 45 | end 46 | return sha1 47 | end 48 | 49 | ### Packed Objects ### 50 | 51 | The other format for object storage is the packfile. Since Git stores each 52 | version of each file as a seperate object, it can get pretty inefficient. 53 | Imagine having a file several thousand lines long and changing a single line. 54 | Git will store the second file in it's entirety, which is a great big waste 55 | of space. 56 | 57 | In order to save that space, Git utilizes the packfile. This is a format 58 | where Git will only save the part that has changed in the second file, with 59 | a pointer to the file it is similar to. 60 | 61 | When objects are written to disk, it is often in the loose format, since 62 | that format is less expensive to access. However, eventually you'll want 63 | to save the space by packing up the objects - this is done with the 64 | linkgit:git-gc[1] command. It will use a rather complicated heuristic to 65 | determine which files are likely most similar and base the deltas off that 66 | analysis. There can be multiple packfiles, they can be repacked if neccesary 67 | (linkgit:git-repack[1]) or unpacked back into loose files 68 | (linkgit:git-unpack-objects[1]) relatively easily. 69 | 70 | Git will also write out an index file for each packfile that is much smaller 71 | and contains offsets into the packfile to more quickly find specific objects 72 | by sha. 73 | 74 | The actual details of the packfile implementation are found in the Packfile 75 | chapter a little later on. 76 | 77 | 78 | -------------------------------------------------------------------------------- /text/49_Browsing_Git_Objects/0_ Browsing_Git_Objects.markdown: -------------------------------------------------------------------------------- 1 | ## Browsing Git Objects ## 2 | 3 | We can ask git about particular objects with the cat-file 4 | command. Note that you can shorten the shas to only a few 5 | characters to save yourself typing all 40 hex digits: 6 | 7 | $ git-cat-file -t 54196cc2 8 | commit 9 | $ git-cat-file commit 54196cc2 10 | tree 92b8b694ffb1675e5975148e1121810081dbdffe 11 | author J. Bruce Fields1143414668 -0500 12 | committer J. Bruce Fields 1143414668 -0500 13 | 14 | initial commit 15 | 16 | A tree can refer to one or more "blob" objects, each corresponding to 17 | a file. In addition, a tree can also refer to other tree objects, 18 | thus creating a directory hierarchy. You can examine the contents of 19 | any tree using ls-tree (remember that a long enough initial portion 20 | of the SHA1 will also work): 21 | 22 | $ git ls-tree 92b8b694 23 | 100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad file.txt 24 | 25 | Thus we see that this tree has one file in it. The SHA1 hash is a 26 | reference to that file's data: 27 | 28 | $ git cat-file -t 3b18e512 29 | blob 30 | 31 | A "blob" is just file data, which we can also examine with cat-file: 32 | 33 | $ git cat-file blob 3b18e512 34 | hello world 35 | 36 | Note that this is the old file data; so the object that git named in 37 | its response to the initial tree was a tree with a snapshot of the 38 | directory state that was recorded by the first commit. 39 | 40 | All of these objects are stored under their SHA1 names inside the git 41 | directory: 42 | 43 | $ find .git/objects/ 44 | .git/objects/ 45 | .git/objects/pack 46 | .git/objects/info 47 | .git/objects/3b 48 | .git/objects/3b/18e512dba79e4c8300dd08aeb37f8e728b8dad 49 | .git/objects/92 50 | .git/objects/92/b8b694ffb1675e5975148e1121810081dbdffe 51 | .git/objects/54 52 | .git/objects/54/196cc2703dc165cbd373a65a4dcf22d50ae7f7 53 | .git/objects/a0 54 | .git/objects/a0/423896973644771497bdc03eb99d5281615b51 55 | .git/objects/d0 56 | .git/objects/d0/492b368b66bdabf2ac1fd8c92b39d3db916e59 57 | .git/objects/c4 58 | .git/objects/c4/d59f390b9cfd4318117afde11d601c1085f241 59 | 60 | and the contents of these files is just the compressed data plus a 61 | header identifying their length and their type. The type is either a 62 | blob, a tree, a commit, or a tag. 63 | 64 | The simplest commit to find is the HEAD commit, which we can find 65 | from .git/HEAD: 66 | 67 | $ cat .git/HEAD 68 | ref: refs/heads/master 69 | 70 | As you can see, this tells us which branch we're currently on, and it 71 | tells us this by naming a file under the .git directory, which itself 72 | contains a SHA1 name referring to a commit object, which we can 73 | examine with cat-file: 74 | 75 | $ cat .git/refs/heads/master 76 | c4d59f390b9cfd4318117afde11d601c1085f241 77 | $ git cat-file -t c4d59f39 78 | commit 79 | $ git cat-file commit c4d59f39 80 | tree d0492b368b66bdabf2ac1fd8c92b39d3db916e59 81 | parent 54196cc2703dc165cbd373a65a4dcf22d50ae7f7 82 | author J. Bruce Fields 1143418702 -0500 83 | committer J. Bruce Fields 1143418702 -0500 84 | 85 | add emphasis 86 | 87 | The "tree" object here refers to the new state of the tree: 88 | 89 | $ git ls-tree d0492b36 90 | 100644 blob a0423896973644771497bdc03eb99d5281615b51 file.txt 91 | $ git cat-file blob a0423896 92 | hello world! 93 | 94 | and the "parent" object refers to the previous commit: 95 | 96 | $ git-cat-file commit 54196cc2 97 | tree 92b8b694ffb1675e5975148e1121810081dbdffe 98 | author J. Bruce Fields 1143414668 -0500 99 | committer J. Bruce Fields 1143414668 -0500 100 | -------------------------------------------------------------------------------- /text/50_Git_References_updateref/0_ Git_References_updateref.markdown: -------------------------------------------------------------------------------- 1 | ## Git References ## 2 | 3 | Branches, remote-tracking branches, and tags are all references to 4 | commits. All references are named with a slash-separated path name 5 | starting with "refs"; the names we've been using so far are actually 6 | shorthand: 7 | 8 | - The branch "test" is short for "refs/heads/test". 9 | - The tag "v2.6.18" is short for "refs/tags/v2.6.18". 10 | - "origin/master" is short for "refs/remotes/origin/master". 11 | 12 | The full name is occasionally useful if, for example, there ever 13 | exists a tag and a branch with the same name. 14 | 15 | (Newly created refs are actually stored in the .git/refs directory, 16 | under the path given by their name. However, for efficiency reasons 17 | they may also be packed together in a single file; see 18 | linkgit:git-pack-refs[1]). 19 | 20 | As another useful shortcut, the "HEAD" of a repository can be referred 21 | to just using the name of that repository. So, for example, "origin" 22 | is usually a shortcut for the HEAD branch in the repository "origin". 23 | 24 | For the complete list of paths which git checks for references, and 25 | the order it uses to decide which to choose when there are multiple 26 | references with the same shorthand name, see the "SPECIFYING 27 | REVISIONS" section of linkgit:git-rev-parse[1]. 28 | 29 | 30 | ### Showing commits unique to a given branch ### 31 | 32 | Suppose you would like to see all the commits reachable from the branch 33 | head named "master" but not from any other head in your repository. 34 | 35 | We can list all the heads in this repository with 36 | linkgit:git-show-ref[1]: 37 | 38 | $ git show-ref --heads 39 | bf62196b5e363d73353a9dcf094c59595f3153b7 refs/heads/core-tutorial 40 | db768d5504c1bb46f63ee9d6e1772bd047e05bf9 refs/heads/maint 41 | a07157ac624b2524a059a3414e99f6f44bebc1e7 refs/heads/master 42 | 24dbc180ea14dc1aebe09f14c8ecf32010690627 refs/heads/tutorial-2 43 | 1e87486ae06626c2f31eaa63d26fc0fd646c8af2 refs/heads/tutorial-fixes 44 | 45 | We can get just the branch-head names, and remove "master", with 46 | the help of the standard utilities cut and grep: 47 | 48 | $ git show-ref --heads | cut -d' ' -f2 | grep -v '^refs/heads/master' 49 | refs/heads/core-tutorial 50 | refs/heads/maint 51 | refs/heads/tutorial-2 52 | refs/heads/tutorial-fixes 53 | 54 | And then we can ask to see all the commits reachable from master 55 | but not from these other heads: 56 | 57 | $ gitk master --not $( git show-ref --heads | cut -d' ' -f2 | 58 | grep -v '^refs/heads/master' ) 59 | 60 | Obviously, endless variations are possible; for example, to see all 61 | commits reachable from some head but not from any tag in the repository: 62 | 63 | $ gitk $( git show-ref --heads ) --not $( git show-ref --tags ) 64 | 65 | (See linkgit:git-rev-parse[1] for explanations of commit-selecting 66 | syntax such as `--not`.) 67 | 68 | (!!update-ref!!) 69 | -------------------------------------------------------------------------------- /text/51_The_Git_Index_lsfiles/0_ The_Git_Index_lsfiles.markdown: -------------------------------------------------------------------------------- 1 | ## The Git Index ## 2 | 3 | The index is a binary file (generally kept in .git/index) containing a 4 | sorted list of path names, each with permissions and the SHA1 of a blob 5 | object; linkgit:git-ls-files[1] can show you the contents of the index: 6 | 7 | $ git ls-files --stage 8 | 100644 63c918c667fa005ff12ad89437f2fdc80926e21c 0 .gitignore 9 | 100644 5529b198e8d14decbe4ad99db3f7fb632de0439d 0 .mailmap 10 | 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0 COPYING 11 | 100644 a37b2152bd26be2c2289e1f57a292534a51a93c7 0 Documentation/.gitignore 12 | 100644 fbefe9a45b00a54b58d94d06eca48b03d40a50e0 0 Documentation/Makefile 13 | ... 14 | 100644 2511aef8d89ab52be5ec6a5e46236b4b6bcd07ea 0 xdiff/xtypes.h 15 | 100644 2ade97b2574a9f77e7ae4002a4e07a6a38e46d07 0 xdiff/xutils.c 16 | 100644 d5de8292e05e7c36c4b68857c1cf9855e3d2f70a 0 xdiff/xutils.h 17 | 18 | Note that in older documentation you may see the index called the 19 | "current directory cache" or just the "cache". It has three important 20 | properties: 21 | 22 | 1. The index contains all the information necessary to generate a single 23 | (uniquely determined) tree object. 24 | 25 | For example, running linkgit:git-commit[1] generates this tree object 26 | from the index, stores it in the object database, and uses it as the 27 | tree object associated with the new commit. 28 | 29 | 2. The index enables fast comparisons between the tree object it defines 30 | and the working tree. 31 | 32 | It does this by storing some additional data for each entry (such as 33 | the last modified time). This data is not displayed above, and is not 34 | stored in the created tree object, but it can be used to determine 35 | quickly which files in the working directory differ from what was 36 | stored in the index, and thus save git from having to read all of the 37 | data from such files to look for changes. 38 | 39 | 3. It can efficiently represent information about merge conflicts 40 | between different tree objects, allowing each pathname to be 41 | associated with sufficient information about the trees involved that 42 | you can create a three-way merge between them. 43 | 44 | During a merge, the index can 45 | store multiple versions of a single file (called "stages"). The third 46 | column in the linkgit:git-ls-files[1] output above is the stage 47 | number, and will take on values other than 0 for files with merge 48 | conflicts. 49 | 50 | The index is thus a sort of temporary staging area, which is filled with 51 | a tree which you are in the process of working on. 52 | -------------------------------------------------------------------------------- /text/52_The_Packfile/0_The_Packfile.markdown: -------------------------------------------------------------------------------- 1 | ## The Packfile ## 2 | 3 | This chapter explains in detail, down to the bits, how the packfile and 4 | pack index files are formatted. 5 | 6 | ### The Packfile Index ### 7 | 8 | First off, we have the packfile index, which is basically just a series of 9 | bookmarks into a packfile. 10 | 11 | There are two versions of the packfile index - version one, which is the default 12 | in versions of Git earlier than 1.6, and version two, which is the default 13 | from 1.6 forward, but which can be read by Git versions going back to 1.5.2, and 14 | has been further backported to 1.4.4.5 if you are still on the 1.4 series. 15 | 16 | Version 2 also includes a CRC checksum of each object so compressed data 17 | can be copied directly from pack to pack during repacking without 18 | undetected data corruption. Version 2 indexes can also handle packfiles 19 | larger than 4 Gb. 20 | 21 | [fig:packfile-index] 22 | 23 | In both formats, the fanout table is simply a way to find the offset of a 24 | particular sha faster within the index file. The offset/sha1[] 25 | tables are sorted by sha1[] values (this is to allow binary search of this 26 | table), and fanout[] table points at the offset/sha1[] table in a specific 27 | way (so that part of the latter table that covers all hashes that start 28 | with a given byte can be found to avoid 8 iterations of the binary 29 | search). 30 | 31 | In version 1, the offsets and shas are in the same space, where in version two, 32 | there are seperate tables 33 | for the shas, crc checksums and offsets. At the end of both files are 34 | checksum shas for both the index file and the packfile it references. 35 | 36 | Importantly, packfile indexes are *not* neccesary to extract objects from 37 | a packfile, they are simply used to *quickly* retrieve individual objects from 38 | a pack. The packfile format is used in upload-pack and receieve-pack programs 39 | (push and fetch protocols) to transfer objects and there is no index used then 40 | - it can be built after the fact by scanning the packfile. 41 | 42 | ### The Packfile Format ### 43 | 44 | The packfile itself is a very simple format. There is a header, a series of 45 | packed objects (each with it's own header and body) and then a checksum trailer. 46 | The first four bytes is the string 'PACK', which is sort of used to make sure 47 | you're getting the start of the packfile correctly. This is followed by a 4-byte 48 | packfile version number and then a 4-byte number of entries in that file. In 49 | Ruby, you might read the header data like this: 50 | 51 | ruby 52 | def read_pack_header 53 | sig = @session.recv(4) 54 | ver = @session.recv(4).unpack("N")[0] 55 | entries = @session.recv(4).unpack("N")[0] 56 | [sig, ver, entries] 57 | end 58 | 59 | After that, you get a series of packed objects, in order of thier SHAs 60 | which each consist of an object header and object contents. At the end 61 | of the packfile is a 20-byte SHA1 sum of all the shas (in sorted order) in that 62 | packfile. 63 | 64 | [fig:packfile-format] 65 | 66 | The object header is a series of one or more 1 byte (8 bit) hunks that 67 | specify the type of object the following data is, and the size of the data 68 | when expanded. Each byte is really 7 bits of data, with the first bit being 69 | used to say if that hunk is the last one or not before the data starts. If 70 | the first bit is a 1, you will read another byte, otherwise the data starts 71 | next. The first 3 bits in the first byte specifies the type of data, 72 | according to the table below. 73 | 74 | (Currently, of the 8 values that can be expressed 75 | with 3 bits (0-7), 0 (000) is 'undefined' and 5 (101) is not yet used.) 76 | 77 | Here, we can see an example of a header of two bytes, where the first 78 | specifies that the following data is a commit, and the remainder of the first 79 | and the last 7 bits of the second specifies that the data will be 144 bytes 80 | when expanded. 81 | 82 | [fig:packfile-logic] 83 | 84 | It is important to note that the size specified in the header data is not 85 | the size of the data that actually follows, but the size of that data *when 86 | expanded*. This is why the offsets in the packfile index are so useful, 87 | otherwise you have to expand every object just to tell when the next header 88 | starts. 89 | 90 | The data part is just zlib stream for non-delta object types; for the two 91 | delta object representations, the data portion contains something that 92 | identifies which base object this delta representation depends on, and the 93 | delta to apply on the base object to resurrect this object. ref-delta
94 | uses 20-byte hash of the base object at the beginning of data, while 95 |ofs-delta
stores an offset within the same packfile to identify the base 96 | object. In either case, two important constraints a reimplementor must 97 | adhere to are: 98 | 99 | * delta representation must be based on some other object within the same 100 | packfile; 101 | 102 | * the base object must be of the same underlying type (blob, tree, commit 103 | or tag); -------------------------------------------------------------------------------- /text/53_Raw_Git_readtree_writetree_committree/0_ Raw_Git_readtree_writetree_committree.markdown: -------------------------------------------------------------------------------- 1 | ## Raw Git ## 2 | 3 | Here we will take a look at how to manipulate git at a more raw level, in 4 | case you would like to write a tool that generates new blobs, trees or commits 5 | in a more artificial way. If you want to write a script that uses more low-level 6 | git plumbing to do something new, here are some of the tools you'll need. 7 | 8 | ### Creating Blobs ### 9 | 10 | Creating a blob in your Git repository and getting a SHA back is pretty easy. 11 | The linkgit:git-hash-object[1] command is all you'll need. To create a blob 12 | object from an existing file, just run it with the '-w' option (which tells it 13 | to write the blob, not just compute the SHA). 14 | 15 | $ git hash-object -w myfile.txt 16 | 6ff87c4664981e4397625791c8ea3bbb5f2279a3 17 | 18 | $ git hash-object -w myfile2.txt 19 | 3bb0e8592a41ae3185ee32266c860714980dbed7 20 | 21 | The STDOUT output of the command will the the SHA of the blob that was created. 22 | 23 | ### Creating Trees ### 24 | 25 | Now lets say you want to create a tree from your new objects. 26 | The linkgit:git-mktree[1] command makes it pretty simple to generate new 27 | tree objects from linkgit:git-ls-tree[1] formatted output. For example, if 28 | you write the following to a file named '/tmp/tree.txt' : 29 | 30 | 100644 blob 6ff87c4664981e4397625791c8ea3bbb5f2279a3 file1 31 | 100644 blob 3bb0e8592a41ae3185ee32266c860714980dbed7 file2 32 | 33 | and then piped that through the linkgit:git-mktree[1] command, Git will 34 | write a new tree to the object database and give you back the new sha of that 35 | tree. 36 | 37 | $ cat /tmp/tree.txt | git mk-tree 38 | f66a66ab6a7bfe86d52a66516ace212efa00fe1f 39 | 40 | Then, we can take that and make it a subdirectory of yet another tree, and so 41 | on. If we wanted to create a new tree with that one as a subtree, we just 42 | create a new file (/tmp/newtree.txt) with our new SHA as a tree in it: 43 | 44 | 100644 blob 6ff87c4664981e4397625791c8ea3bbb5f2279a3 file1-copy 45 | 040000 tree f66a66ab6a7bfe86d52a66516ace212efa00fe1f our_files 46 | 47 | and then use linkgit:git-mk-tree[1] again: 48 | 49 | $ cat /tmp/newtree.txt | git mk-tree 50 | 5bac6559179bd543a024d6d187692343e2d8ae83 51 | 52 | And we now have an artificial directory structure in Git that looks like this: 53 | 54 | . 55 | |-- file1-copy 56 | `-- our_files 57 | |-- file1 58 | `-- file2 59 | 60 | 1 directory, 3 files 61 | 62 | without that structure ever having actually existed on disk. Plus, we have 63 | a SHA (5bac6559
) that points to it. 64 | 65 | ### Rearranging Trees ### 66 | 67 | We can also do tree manipulation by combining trees into new structures using 68 | the index file. As a simple example, let's take the tree we just created and 69 | make a new tree that has two copies of our5bac6559
tree in it 70 | using a temporary index file. (You can do this by resetting the GIT_INDEX_FILE 71 | environment variable or on the command line) 72 | 73 | First, we read the tree into our index file under a new prefix using the 74 | linkgit:git-read-tree[1] command, and then write the index contents as 75 | a tree using the linkgit:git-write-tree[1] command: 76 | 77 | $ export GIT_INDEX_FILE=/tmp/index 78 | $ git read-tree --prefix=copy1/ 5bac6559 79 | $ git read-tree --prefix=copy2/ 5bac6559 80 | $ git write-tree 81 | bb2fa6de7625322322382215d9ea78cfe76508c1 82 | 83 | $>git ls-tree bb2fa 84 | 040000 tree 5bac6559179bd543a024d6d187692343e2d8ae83 copy1 85 | 040000 tree 5bac6559179bd543a024d6d187692343e2d8ae83 copy2 86 | 87 | So now we can see that we've created a new tree just from index manipulation. 88 | You can also do interesting merge operations and such in a temporary index 89 | this way - see the linkgit:git-read-tree[1] docs for more information. 90 | 91 | ### Creating Commits ### 92 | 93 | Now that we have a tree SHA, we can create a commit object that points to it. 94 | We can do this using the linkgit:git-commit-tree[1] command. Most of the data 95 | that goes into the commit has to be set as environment variables, so you'll want 96 | to set the following: 97 | 98 | GIT_AUTHOR_NAME 99 | GIT_AUTHOR_EMAIL 100 | GIT_AUTHOR_DATE 101 | GIT_COMMITTER_NAME 102 | GIT_COMMITTER_EMAIL 103 | GIT_COMMITTER_DATE 104 | 105 | Then you will need to write your commit message to a file or somehow pipe it 106 | into the command through STDIN. Then, you can create your commit object 107 | based on the tree sha we have. 108 | 109 | $ git commit-tree bb2fa < /tmp/message 110 | a5f85ba5875917319471dfd98dfc636c1dc65650 111 | 112 | If you want to specify one or more parent commits, simply add the shas on the 113 | command line with a '-p' option before each. The SHA of the new commit object 114 | will be returned via STDOUT. 115 | 116 | ### Updating a Branch Ref ### 117 | 118 | Now that we have a new commit object SHA, we can update a branch to point to 119 | it if we want to. Lets say we want to update our 'master' branch to point to 120 | the new commit we just created - we would use the linkgit:git-update-ref[1] 121 | command: 122 | 123 | $ git update-ref refs/heads/master a5f85ba5875917319471dfd98dfc636c1dc65650 124 | 125 | -------------------------------------------------------------------------------- /text/54_Transfer_Protocols/0_Transfer_Protocols.markdown: -------------------------------------------------------------------------------- 1 | ## Transfer Protocols ## 2 | 3 | Here we will go over how clients and servers talk to each other to 4 | transfer Git data around. 5 | 6 | ### Fetching Data over HTTP ### 7 | 8 | Fetching over an http/s URL will make Git use a slightly dumber protocol. 9 | In this case, all of the logic is entirely on the client side. The server 10 | requires no special setup - any static webserver will work fine if the 11 | git directory you are fetching from is in the webserver path. 12 | 13 | In order for this to work, you do need to run a single command on the 14 | server repo everytime anything is updated, though - linkgit:git-update-server-info[0], 15 | which updates the objects/info/packs and info/refs files to list which refs 16 | and packfiles are available, since you can't do a listing over http. When 17 | that command is run, the objects/info/packs file looks something like this: 18 | 19 | P pack-ce2bd34abc3d8ebc5922dc81b2e1f30bf17c10cc.pack 20 | P pack-7ad5f5d05f5e20025898c95296fe4b9c861246d8.pack 21 | 22 | So that if the fetch can't find a loose file, it can try these packfiles. The 23 | info/refs file will look something like this: 24 | 25 | 184063c9b594f8968d61a686b2f6052779551613 refs/heads/development 26 | 32aae7aef7a412d62192f710f2130302997ec883 refs/heads/master 27 | 28 | Then when you fetch from this repo, it will start with these refs and walk the 29 | commit objects until the client has all the objects that it needs. 30 | 31 | For instance, if you ask to fetch the master branch, it will see that master is 32 | pointing to32aae7ae
and that your master is pointing toab04d88
, 33 | so you need32aae7ae
. You fetch that object 34 | 35 | CONNECT http://myserver.com 36 | GET /git/myproject.git/objects/32/aae7aef7a412d62192f710f2130302997ec883 - 200 37 | 38 | and it looks like this: 39 | 40 | tree aa176fb83a47d00386be237b450fb9dfb5be251a 41 | parent bd71cad2d597d0f1827d4a3f67bb96a646f02889 42 | author Scott Chacon1220463037 -0700 43 | committer Scott Chacon 1220463037 -0700 44 | 45 | added chapters on private repo setup, scm migration, raw git 46 | 47 | So now it fetches the tree aa176fb8
: 48 | 49 | GET /git/myproject.git/objects/aa/176fb83a47d00386be237b450fb9dfb5be251a - 200 50 | 51 | which looks like this: 52 | 53 | 100644 blob 6ff87c4664981e4397625791c8ea3bbb5f2279a3 COPYING 54 | 100644 blob 97b51a6d3685b093cfb345c9e79516e5099a13fb README 55 | 100644 blob 9d1b23b8660817e4a74006f15fae86e2a508c573 Rakefile 56 | 57 | So then it fetches those objects: 58 | 59 | GET /git/myproject.git/objects/6f/f87c4664981e4397625791c8ea3bbb5f2279a3 - 200 60 | GET /git/myproject.git/objects/97/b51a6d3685b093cfb345c9e79516e5099a13fb - 200 61 | GET /git/myproject.git/objects/9d/1b23b8660817e4a74006f15fae86e2a508c573 - 200 62 | 63 | It actually does this with Curl, and can open up multiple parallel threads to 64 | speed up this process. When it's done recursing the tree pointed to by the 65 | commit, it fetches the next parent. 66 | 67 | GET /git/myproject.git/objects/bd/71cad2d597d0f1827d4a3f67bb96a646f02889 - 200 68 | 69 | Now in this case, the commit that comes back looks like this: 70 | 71 | tree b4cc00cf8546edd4fcf29defc3aec14de53e6cf8 72 | parent ab04d884140f7b0cf8bbf86d6883869f16a46f65 73 | author Scott Chacon1220421161 -0700 74 | committer Scott Chacon 1220421161 -0700 75 | 76 | added chapters on the packfile and how git stores objects 77 | 78 | and we can see that the parent, ab04d88
is where our master branch 79 | is currently pointing. So, we recursively fetch this tree and then stop, since 80 | we know we have everything before this point. You can force Git to double check 81 | that we have everything with the '--recover' option. See linkgit:git-http-fetch[1] 82 | for more information. 83 | 84 | If one of the loose object fetches fails, Git will download the packfile indexes 85 | looking for the sha that it needs, then download that packfile. 86 | 87 | It is important if you are running a git server that serves repos this way to 88 | implement a post-receive hook that runs the 'git update-server-info' command 89 | each time or there will be confusion. 90 | 91 | ### Fetching Data with Upload Pack ### 92 | 93 | For the smarter protocols, fetching objects is much more efficient. A socket 94 | is opened, either over ssh or over port 9418 (in the case of the git:// protocol), 95 | and the linkgit:git-fetch-pack[1] command on the client begins communicating with 96 | a forked linkgit:git-upload-pack[1] process on the server. 97 | 98 | Then the server will tell the client which SHAs it has for each ref, 99 | and the client figures out what it needs and responds with a list of SHAs it 100 | wants and already has. 101 | 102 | At this point, the server will generate a packfile with all the objects that 103 | the client needs and begin streaming it down to the client. 104 | 105 | Let's look at an example. 106 | 107 | The client connects and sends the request header. The clone command 108 | 109 | $ git clone git://myserver.com/project.git 110 | 111 | produces the following request: 112 | 113 | 0032git-upload-pack /project.git\\000host=myserver.com\\000 114 | 115 | The first four bytes contain the hex length of the line (including 4 byte line 116 | length and trailing newline if present). Following are the command and 117 | arguments. This is followed by a null byte and then the host information. The 118 | request is terminated by a null byte. 119 | 120 | The request is processed and turned into a call to git-upload-pack: 121 | 122 | $ git-upload-pack /path/to/repos/project.git 123 | 124 | This immediately returns information of the repo: 125 | 126 | 007c74730d410fcb6603ace96f1dc55ea6196122532d HEAD\\000multi_ack thin-pack side-band side-band-64k ofs-delta shallow no-progress 127 | 003e7d1665144a3a975c05f1f43902ddaf084e784dbe refs/heads/debug 128 | 003d5a3f6be755bbb7deae50065988cbfa1ffa9ab68a refs/heads/dist 129 | 003e7e47fe2bd8d01d481f44d7af0531bd93d3b21c01 refs/heads/local 130 | 003f74730d410fcb6603ace96f1dc55ea6196122532d refs/heads/master 131 | 0000 132 | 133 | Each line starts with a four byte line length declaration in hex. The section 134 | is terminated by a line length declaration of 0000. 135 | 136 | This is sent back to the client verbatim. The client responds with another 137 | request: 138 | 139 | 0054want 74730d410fcb6603ace96f1dc55ea6196122532d multi_ack side-band-64k ofs-delta 140 | 0032want 7d1665144a3a975c05f1f43902ddaf084e784dbe 141 | 0032want 5a3f6be755bbb7deae50065988cbfa1ffa9ab68a 142 | 0032want 7e47fe2bd8d01d481f44d7af0531bd93d3b21c01 143 | 0032want 74730d410fcb6603ace96f1dc55ea6196122532d 144 | 00000009done 145 | 146 | The is sent to the open git-upload-pack process which then streams out the 147 | final response: 148 | 149 | "0008NAK\n" 150 | "0023\\002Counting objects: 2797, done.\n" 151 | "002b\\002Compressing objects: 0% (1/1177) \r" 152 | "002c\\002Compressing objects: 1% (12/1177) \r" 153 | "002c\\002Compressing objects: 2% (24/1177) \r" 154 | "002c\\002Compressing objects: 3% (36/1177) \r" 155 | "002c\\002Compressing objects: 4% (48/1177) \r" 156 | "002c\\002Compressing objects: 5% (59/1177) \r" 157 | "002c\\002Compressing objects: 6% (71/1177) \r" 158 | "0053\\002Compressing objects: 7% (83/1177) \rCompressing objects: 8% (95/1177) \r" 159 | ... 160 | "005b\\002Compressing objects: 100% (1177/1177) \rCompressing objects: 100% (1177/1177), done.\n" 161 | "2004\\001PACK\\000\\000\\000\\002\\000\\000\n\\355\\225\\017x\\234\\235\\216K\n\\302"... 162 | "2005\\001\\360\\204{\\225\\376\\330\\345]z\226\273"... 163 | ... 164 | "0037\\002Total 2797 (delta 1799), reused 2360 (delta 1529)\n" 165 | ... 166 | "<\\276\\255L\\273s\\005\\001w0006\\001[0000" 167 | 168 | See the Packfile chapter previously for the actual format of the packfile data 169 | in the response. 170 | 171 | ### Pushing Data ### 172 | 173 | Pushing data over the git and ssh protocols is similar, but simpler. Basically 174 | what happens is the client requests a receive-pack instance, which is started 175 | up if the client has access, then the server returns all the ref head shas it 176 | has again and the client generates a packfile of everything the server needs 177 | (generally only if what is on the server is a direct ancestor of what it is 178 | pushing) and sends that packfile upstream, where the server either stores it 179 | on disk and builds an index for it, or unpacks it (if there aren't many objects 180 | in it) 181 | 182 | This entire process is accomplished through the linkgit:git-send-pack[1] command 183 | on the client, which is invoked by linkgit:git-push[1] and the 184 | linkgit:git-receive-pack[1] command on the server side, which is invoked by 185 | the ssh connect process or git daemon (if it's an open push server). 186 | 187 | 188 | --------------------------------------------------------------------------------