commonmarker 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of commonmarker might be problematic. Click here for more details.

Files changed (501) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -2
  3. data/README.md +67 -42
  4. data/Rakefile +22 -2
  5. data/commonmarker.gemspec +13 -9
  6. data/ext/commonmarker/cmark/api_test/main.c +35 -0
  7. data/ext/commonmarker/cmark/build/CMakeFiles/CMakeError.log +12 -12
  8. data/ext/commonmarker/cmark/build/CMakeFiles/CMakeOutput.log +141 -141
  9. data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/main.c.o +0 -0
  10. data/ext/commonmarker/cmark/build/api_test/api_test +0 -0
  11. data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/houdini_html_u.c.o +0 -0
  12. data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/iterator.c.o +0 -0
  13. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/houdini_html_u.c.o +0 -0
  14. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/iterator.c.o +0 -0
  15. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/houdini_html_u.c.o +0 -0
  16. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/iterator.c.o +0 -0
  17. data/ext/commonmarker/cmark/build/src/cmark +0 -0
  18. data/ext/commonmarker/cmark/build/src/libcmark.0.19.0.dylib +0 -0
  19. data/ext/commonmarker/cmark/build/src/libcmark.a +0 -0
  20. data/ext/commonmarker/cmark/build/src/libcmark.dylib +0 -0
  21. data/ext/commonmarker/cmark/src/houdini_html_u.c +26 -13
  22. data/ext/commonmarker/cmark/src/iterator.c +2 -2
  23. data/ext/commonmarker/cmark/test/__pycache__/cmark.cpython-34.pyc +0 -0
  24. data/ext/commonmarker/cmark/test/__pycache__/normalize.cpython-34.pyc +0 -0
  25. data/ext/commonmarker/cmark/test/cmark.pyc +0 -0
  26. data/ext/commonmarker/cmark/test/normalize.pyc +0 -0
  27. data/ext/commonmarker/commonmarker.c +276 -3
  28. data/ext/commonmarker/extconf.rb +3 -1
  29. data/lib/commonmarker.rb +70 -360
  30. data/lib/commonmarker/config.rb +1 -1
  31. data/lib/commonmarker/renderer.rb +91 -0
  32. data/lib/commonmarker/renderer/html_renderer.rb +149 -0
  33. data/lib/commonmarker/version.rb +1 -1
  34. data/test/benchinput.md +148414 -0
  35. data/test/benchmark.rb +13 -9
  36. data/test/progit/Gemfile +5 -0
  37. data/test/progit/README.md +9 -0
  38. data/test/progit/README.original.md +70 -0
  39. data/test/progit/Rakefile +285 -0
  40. data/test/progit/ar/01-introduction/01-chapter1.markdown +264 -0
  41. data/test/progit/ar/02-git-basics/01-chapter2.markdown +1124 -0
  42. data/test/progit/ar/NOTES +18 -0
  43. data/test/progit/ar/README +14 -0
  44. data/test/progit/az/01-introduction/01-chapter1.markdown +257 -0
  45. data/test/progit/az/02-git-basics/01-chapter2.markdown +1127 -0
  46. data/test/progit/az/03-git-branching/01-chapter3.markdown +598 -0
  47. data/test/progit/az/04-git-server/01-chapter4.markdown +861 -0
  48. data/test/progit/az/05-distributed-git/01-chapter5.markdown +897 -0
  49. data/test/progit/az/06-git-tools/01-chapter6.markdown +1126 -0
  50. data/test/progit/az/07-customizing-git/01-chapter7.markdown +937 -0
  51. data/test/progit/az/08-git-and-other-scms/01-chapter8.markdown +690 -0
  52. data/test/progit/az/09-git-internals/01-chapter9.markdown +977 -0
  53. data/test/progit/be/01-introduction/01-chapter1.markdown +257 -0
  54. data/test/progit/be/02-git-basics/01-chapter2.markdown +1126 -0
  55. data/test/progit/ca/01-introduction/01-chapter1.markdown +257 -0
  56. data/test/progit/ca/README.txt +1 -0
  57. data/test/progit/couchapp/Makefile +41 -0
  58. data/test/progit/couchapp/Readme.md +17 -0
  59. data/test/progit/couchapp/_id +1 -0
  60. data/test/progit/couchapp/shows/chapter.js +14 -0
  61. data/test/progit/couchapp/templates/foot.html +7 -0
  62. data/test/progit/couchapp/templates/head.html +51 -0
  63. data/test/progit/couchapp/vendor/markdown/showdown.js +420 -0
  64. data/test/progit/couchapp/vendor/mustache.js/mustache.js +302 -0
  65. data/test/progit/cs/01-introduction/01-chapter1.markdown +259 -0
  66. data/test/progit/cs/02-git-basics/01-chapter2.markdown +1225 -0
  67. data/test/progit/cs/03-git-branching/01-chapter3.markdown +606 -0
  68. data/test/progit/cs/04-git-server/01-chapter4.markdown +871 -0
  69. data/test/progit/cs/05-distributed-git/01-chapter5.markdown +914 -0
  70. data/test/progit/cs/06-git-tools/01-chapter6.markdown +1167 -0
  71. data/test/progit/cs/07-customizing-git/01-chapter7.markdown +940 -0
  72. data/test/progit/cs/08-git-and-other-scms/01-chapter8.markdown +700 -0
  73. data/test/progit/cs/09-git-internals/01-chapter9.markdown +1014 -0
  74. data/test/progit/de/01-introduction/01-chapter1.markdown +445 -0
  75. data/test/progit/de/02-git-basics/01-chapter2.markdown +1589 -0
  76. data/test/progit/de/03-git-branching/01-chapter3.markdown +964 -0
  77. data/test/progit/de/04-git-server/01-chapter4.markdown +1337 -0
  78. data/test/progit/de/05-distributed-git/01-chapter5.markdown +1329 -0
  79. data/test/progit/de/06-git-tools/01-chapter6.markdown +1502 -0
  80. data/test/progit/de/07-customizing-git/01-chapter7.markdown +1361 -0
  81. data/test/progit/de/08-git-and-other-scms/01-chapter8.markdown +919 -0
  82. data/test/progit/de/09-git-internals/01-chapter9.markdown +1361 -0
  83. data/test/progit/de/README.md +626 -0
  84. data/test/progit/ebooks/cover.png +0 -0
  85. data/test/progit/en/01-introduction/01-chapter1.markdown +263 -0
  86. data/test/progit/en/02-git-basics/01-chapter2.markdown +1228 -0
  87. data/test/progit/en/03-git-branching/01-chapter3.markdown +606 -0
  88. data/test/progit/en/04-git-server/01-chapter4.markdown +871 -0
  89. data/test/progit/en/05-distributed-git/01-chapter5.markdown +914 -0
  90. data/test/progit/en/06-git-tools/01-chapter6.markdown +1150 -0
  91. data/test/progit/en/07-customizing-git/01-chapter7.markdown +940 -0
  92. data/test/progit/en/08-git-and-other-scms/01-chapter8.markdown +700 -0
  93. data/test/progit/en/09-git-internals/01-chapter9.markdown +983 -0
  94. data/test/progit/eo/01-introduction/01-chapter1.markdown +257 -0
  95. data/test/progit/eo/02-git-basics/01-chapter2.markdown +1171 -0
  96. data/test/progit/epub/ProGit.css +28 -0
  97. data/test/progit/epub/title.png +0 -0
  98. data/test/progit/es-ni/01-introduction/01-chapter1.markdown +257 -0
  99. data/test/progit/es-ni/02-git-basics/01-chapter2.markdown +1127 -0
  100. data/test/progit/es/01-introduction/01-chapter1.markdown +262 -0
  101. data/test/progit/es/02-git-basics/01-chapter2.markdown +1165 -0
  102. data/test/progit/es/03-git-branching/01-chapter3.markdown +598 -0
  103. data/test/progit/es/04-git-server/01-chapter4.markdown +707 -0
  104. data/test/progit/es/05-distributed-git/01-chapter5.markdown +890 -0
  105. data/test/progit/es/06-git-tools/01-chapter6.markdown +1113 -0
  106. data/test/progit/es/07-customizing-git/01-chapter7.markdown +875 -0
  107. data/test/progit/es/08-git-and-other-scms/01-chapter8.markdown +686 -0
  108. data/test/progit/es/09-git-internals/01-chapter9.markdown +976 -0
  109. data/test/progit/es/NOTES +29 -0
  110. data/test/progit/es/README +3 -0
  111. data/test/progit/es/glosario-Benzirpi.txt +27 -0
  112. data/test/progit/es/omegat-Benzirpi.tmx +29075 -0
  113. data/test/progit/fa/01-introduction/01-chapter1.markdown +262 -0
  114. data/test/progit/fa/03-git-branching/01-chapter3.markdown +608 -0
  115. data/test/progit/fa/04-git-server/01-chapter4.markdown +872 -0
  116. data/test/progit/fa/NOTES.en-fa.md +143 -0
  117. data/test/progit/fa/README.md +7 -0
  118. data/test/progit/fi/01-introduction/01-chapter1.markdown +259 -0
  119. data/test/progit/fi/02-git-basics/01-chapter2.markdown +1171 -0
  120. data/test/progit/fi/NOTES +5 -0
  121. data/test/progit/figures-dia/fig0101.dia +617 -0
  122. data/test/progit/figures-dia/fig0102.dia +921 -0
  123. data/test/progit/figures-dia/fig0103.dia +1468 -0
  124. data/test/progit/figures-dia/fig0104.dia +1432 -0
  125. data/test/progit/figures-dia/fig0105.dia +1924 -0
  126. data/test/progit/figures-dia/fig0106.dia +562 -0
  127. data/test/progit/figures-dia/fig0201.dia +774 -0
  128. data/test/progit/figures-dia/fig0301.dia +2006 -0
  129. data/test/progit/figures-dia/fig0302.dia +2148 -0
  130. data/test/progit/figures-dia/fig0303.dia +719 -0
  131. data/test/progit/figures-dia/fig0304.dia +525 -0
  132. data/test/progit/figures-dia/fig0305.dia +622 -0
  133. data/test/progit/figures-dia/fig0306.dia +622 -0
  134. data/test/progit/figures-dia/fig0307.dia +719 -0
  135. data/test/progit/figures-dia/fig0308.dia +734 -0
  136. data/test/progit/figures-dia/fig0309.dia +831 -0
  137. data/test/progit/figures-dia/fig0310.dia +412 -0
  138. data/test/progit/figures-dia/fig0311.dia +493 -0
  139. data/test/progit/figures-dia/fig0312.dia +596 -0
  140. data/test/progit/figures-dia/fig0313.dia +774 -0
  141. data/test/progit/figures-dia/fig0314.dia +846 -0
  142. data/test/progit/figures-dia/fig0315.dia +787 -0
  143. data/test/progit/figures-dia/fig0316.dia +1078 -0
  144. data/test/progit/figures-dia/fig0317.dia +881 -0
  145. data/test/progit/figures-dia/fig0318.dia +968 -0
  146. data/test/progit/figures-dia/fig0319.dia +957 -0
  147. data/test/progit/figures-dia/fig0320.dia +1637 -0
  148. data/test/progit/figures-dia/fig0321.dia +1494 -0
  149. data/test/progit/figures-dia/fig0322.dia +1142 -0
  150. data/test/progit/figures-dia/fig0323.dia +1377 -0
  151. data/test/progit/figures-dia/fig0324.dia +1603 -0
  152. data/test/progit/figures-dia/fig0325.dia +2003 -0
  153. data/test/progit/figures-dia/fig0326.dia +2013 -0
  154. data/test/progit/figures-dia/fig0327.dia +687 -0
  155. data/test/progit/figures-dia/fig0328.dia +814 -0
  156. data/test/progit/figures-dia/fig0329.dia +793 -0
  157. data/test/progit/figures-dia/fig0330.dia +693 -0
  158. data/test/progit/figures-dia/fig0331.dia +1159 -0
  159. data/test/progit/figures-dia/fig0332.dia +1362 -0
  160. data/test/progit/figures-dia/fig0333.dia +1165 -0
  161. data/test/progit/figures-dia/fig0334.dia +1450 -0
  162. data/test/progit/figures-dia/fig0335.dia +994 -0
  163. data/test/progit/figures-dia/fig0336.dia +786 -0
  164. data/test/progit/figures-dia/fig0337.dia +1546 -0
  165. data/test/progit/figures-dia/fig0338.dia +1755 -0
  166. data/test/progit/figures-dia/fig0339.dia +1882 -0
  167. data/test/progit/figures-dia/fig0501.dia +456 -0
  168. data/test/progit/figures-dia/fig0502.dia +956 -0
  169. data/test/progit/figures-dia/fig0503.dia +915 -0
  170. data/test/progit/figures-dia/fig0504.dia +620 -0
  171. data/test/progit/figures-dia/fig0505.dia +744 -0
  172. data/test/progit/figures-dia/fig0506.dia +747 -0
  173. data/test/progit/figures-dia/fig0507.dia +895 -0
  174. data/test/progit/figures-dia/fig0508.dia +1122 -0
  175. data/test/progit/figures-dia/fig0509.dia +1243 -0
  176. data/test/progit/figures-dia/fig0510.dia +1240 -0
  177. data/test/progit/figures-dia/fig0511.dia +1201 -0
  178. data/test/progit/figures-dia/fig0512.dia +801 -0
  179. data/test/progit/figures-dia/fig0513.dia +1387 -0
  180. data/test/progit/figures-dia/fig0514.dia +1568 -0
  181. data/test/progit/figures-dia/fig0515.dia +1721 -0
  182. data/test/progit/figures-dia/fig0516.dia +997 -0
  183. data/test/progit/figures-dia/fig0517.dia +994 -0
  184. data/test/progit/figures-dia/fig0518.dia +1145 -0
  185. data/test/progit/figures-dia/fig0519.dia +992 -0
  186. data/test/progit/figures-dia/fig0520.dia +1240 -0
  187. data/test/progit/figures-dia/fig0521.dia +801 -0
  188. data/test/progit/figures-dia/fig0522.dia +922 -0
  189. data/test/progit/figures-dia/fig0523.dia +922 -0
  190. data/test/progit/figures-dia/fig0524.dia +1828 -0
  191. data/test/progit/figures-dia/fig0525.dia +2685 -0
  192. data/test/progit/figures-dia/fig0526.dia +717 -0
  193. data/test/progit/figures-dia/fig0527.dia +856 -0
  194. data/test/progit/figures-dia/fig0601.dia +790 -0
  195. data/test/progit/figures-dia/fig0702.dia +795 -0
  196. data/test/progit/figures-dia/fig0703.dia +795 -0
  197. data/test/progit/figures-dia/fig0901.dia +669 -0
  198. data/test/progit/figures-dia/fig0902.dia +834 -0
  199. data/test/progit/figures-dia/fig0903.dia +1483 -0
  200. data/test/progit/figures-dia/fig0904.dia +1728 -0
  201. data/test/progit/figures-dia/makeimages +25 -0
  202. data/test/progit/figures-source/progit.graffle +123108 -0
  203. data/test/progit/figures/18333fig0101-tn.png +0 -0
  204. data/test/progit/figures/18333fig0102-tn.png +0 -0
  205. data/test/progit/figures/18333fig0103-tn.png +0 -0
  206. data/test/progit/figures/18333fig0104-tn.png +0 -0
  207. data/test/progit/figures/18333fig0105-tn.png +0 -0
  208. data/test/progit/figures/18333fig0106-tn.png +0 -0
  209. data/test/progit/figures/18333fig0107-tn.png +0 -0
  210. data/test/progit/figures/18333fig0201-tn.png +0 -0
  211. data/test/progit/figures/18333fig0202-tn.png +0 -0
  212. data/test/progit/figures/18333fig0301-tn.png +0 -0
  213. data/test/progit/figures/18333fig0302-tn.png +0 -0
  214. data/test/progit/figures/18333fig0303-tn.png +0 -0
  215. data/test/progit/figures/18333fig0304-tn.png +0 -0
  216. data/test/progit/figures/18333fig0305-tn.png +0 -0
  217. data/test/progit/figures/18333fig0306-tn.png +0 -0
  218. data/test/progit/figures/18333fig0307-tn.png +0 -0
  219. data/test/progit/figures/18333fig0308-tn.png +0 -0
  220. data/test/progit/figures/18333fig0309-tn.png +0 -0
  221. data/test/progit/figures/18333fig0310-tn.png +0 -0
  222. data/test/progit/figures/18333fig0311-tn.png +0 -0
  223. data/test/progit/figures/18333fig0312-tn.png +0 -0
  224. data/test/progit/figures/18333fig0313-tn.png +0 -0
  225. data/test/progit/figures/18333fig0314-tn.png +0 -0
  226. data/test/progit/figures/18333fig0315-tn.png +0 -0
  227. data/test/progit/figures/18333fig0316-tn.png +0 -0
  228. data/test/progit/figures/18333fig0317-tn.png +0 -0
  229. data/test/progit/figures/18333fig0318-tn.png +0 -0
  230. data/test/progit/figures/18333fig0319-tn.png +0 -0
  231. data/test/progit/figures/18333fig0320-tn.png +0 -0
  232. data/test/progit/figures/18333fig0321-tn.png +0 -0
  233. data/test/progit/figures/18333fig0322-tn.png +0 -0
  234. data/test/progit/figures/18333fig0323-tn.png +0 -0
  235. data/test/progit/figures/18333fig0324-tn.png +0 -0
  236. data/test/progit/figures/18333fig0325-tn.png +0 -0
  237. data/test/progit/figures/18333fig0326-tn.png +0 -0
  238. data/test/progit/figures/18333fig0327-tn.png +0 -0
  239. data/test/progit/figures/18333fig0328-tn.png +0 -0
  240. data/test/progit/figures/18333fig0329-tn.png +0 -0
  241. data/test/progit/figures/18333fig0330-tn.png +0 -0
  242. data/test/progit/figures/18333fig0331-tn.png +0 -0
  243. data/test/progit/figures/18333fig0332-tn.png +0 -0
  244. data/test/progit/figures/18333fig0333-tn.png +0 -0
  245. data/test/progit/figures/18333fig0334-tn.png +0 -0
  246. data/test/progit/figures/18333fig0335-tn.png +0 -0
  247. data/test/progit/figures/18333fig0336-tn.png +0 -0
  248. data/test/progit/figures/18333fig0337-tn.png +0 -0
  249. data/test/progit/figures/18333fig0338-tn.png +0 -0
  250. data/test/progit/figures/18333fig0339-tn.png +0 -0
  251. data/test/progit/figures/18333fig0401-tn.png +0 -0
  252. data/test/progit/figures/18333fig0402-tn.png +0 -0
  253. data/test/progit/figures/18333fig0403-tn.png +0 -0
  254. data/test/progit/figures/18333fig0404-tn.png +0 -0
  255. data/test/progit/figures/18333fig0405-tn.png +0 -0
  256. data/test/progit/figures/18333fig0406-tn.png +0 -0
  257. data/test/progit/figures/18333fig0407-tn.png +0 -0
  258. data/test/progit/figures/18333fig0408-tn.png +0 -0
  259. data/test/progit/figures/18333fig0409-tn.png +0 -0
  260. data/test/progit/figures/18333fig0410-tn.png +0 -0
  261. data/test/progit/figures/18333fig0411-tn.png +0 -0
  262. data/test/progit/figures/18333fig0412-tn.png +0 -0
  263. data/test/progit/figures/18333fig0413-tn.png +0 -0
  264. data/test/progit/figures/18333fig0414-tn.png +0 -0
  265. data/test/progit/figures/18333fig0415-tn.png +0 -0
  266. data/test/progit/figures/18333fig0501-tn.png +0 -0
  267. data/test/progit/figures/18333fig0502-tn.png +0 -0
  268. data/test/progit/figures/18333fig0503-tn.png +0 -0
  269. data/test/progit/figures/18333fig0504-tn.png +0 -0
  270. data/test/progit/figures/18333fig0505-tn.png +0 -0
  271. data/test/progit/figures/18333fig0506-tn.png +0 -0
  272. data/test/progit/figures/18333fig0507-tn.png +0 -0
  273. data/test/progit/figures/18333fig0508-tn.png +0 -0
  274. data/test/progit/figures/18333fig0509-tn.png +0 -0
  275. data/test/progit/figures/18333fig0510-tn.png +0 -0
  276. data/test/progit/figures/18333fig0511-tn.png +0 -0
  277. data/test/progit/figures/18333fig0512-tn.png +0 -0
  278. data/test/progit/figures/18333fig0513-tn.png +0 -0
  279. data/test/progit/figures/18333fig0514-tn.png +0 -0
  280. data/test/progit/figures/18333fig0515-tn.png +0 -0
  281. data/test/progit/figures/18333fig0516-tn.png +0 -0
  282. data/test/progit/figures/18333fig0517-tn.png +0 -0
  283. data/test/progit/figures/18333fig0518-tn.png +0 -0
  284. data/test/progit/figures/18333fig0519-tn.png +0 -0
  285. data/test/progit/figures/18333fig0520-tn.png +0 -0
  286. data/test/progit/figures/18333fig0521-tn.png +0 -0
  287. data/test/progit/figures/18333fig0522-tn.png +0 -0
  288. data/test/progit/figures/18333fig0523-tn.png +0 -0
  289. data/test/progit/figures/18333fig0524-tn.png +0 -0
  290. data/test/progit/figures/18333fig0525-tn.png +0 -0
  291. data/test/progit/figures/18333fig0526-tn.png +0 -0
  292. data/test/progit/figures/18333fig0527-tn.png +0 -0
  293. data/test/progit/figures/18333fig0601-tn.png +0 -0
  294. data/test/progit/figures/18333fig0701-tn.png +0 -0
  295. data/test/progit/figures/18333fig0702-tn.png +0 -0
  296. data/test/progit/figures/18333fig0703-tn.png +0 -0
  297. data/test/progit/figures/18333fig0901-tn.png +0 -0
  298. data/test/progit/figures/18333fig0902-tn.png +0 -0
  299. data/test/progit/figures/18333fig0903-tn.png +0 -0
  300. data/test/progit/figures/18333fig0904-tn.png +0 -0
  301. data/test/progit/fr/01-introduction/01-chapter1.markdown +371 -0
  302. data/test/progit/fr/02-git-basics/01-chapter2.markdown +1378 -0
  303. data/test/progit/fr/03-git-branching/01-chapter3.markdown +781 -0
  304. data/test/progit/fr/04-git-server/01-chapter4.markdown +1141 -0
  305. data/test/progit/fr/05-distributed-git/01-chapter5.markdown +1163 -0
  306. data/test/progit/fr/06-git-tools/01-chapter6.markdown +1356 -0
  307. data/test/progit/fr/07-customizing-git/01-chapter7.markdown +1200 -0
  308. data/test/progit/fr/08-git-and-other-scms/01-chapter8.markdown +832 -0
  309. data/test/progit/fr/09-git-internals/01-chapter9.markdown +1228 -0
  310. data/test/progit/fr/NOTES.fr-fr.markdown +1 -0
  311. data/test/progit/fr/NOTES.fr-fr.md +127 -0
  312. data/test/progit/fr/README.md +43 -0
  313. data/test/progit/fr/glossaire-git.adoc +108 -0
  314. data/test/progit/hi/01-introduction/01-chapter1.markdown +7 -0
  315. data/test/progit/hu/01-introduction/01-chapter1.markdown +257 -0
  316. data/test/progit/id/01-introduction/01-chapter1.markdown +257 -0
  317. data/test/progit/id/02-git-basics/01-chapter2.markdown +1127 -0
  318. data/test/progit/id/03-git-branching/01-chapter3.markdown +598 -0
  319. data/test/progit/it/01-introduction/01-chapter1.markdown +263 -0
  320. data/test/progit/it/02-git-basics/01-chapter2.markdown +1227 -0
  321. data/test/progit/it/03-git-branching/01-chapter3.markdown +598 -0
  322. data/test/progit/it/04-git-server/01-chapter4.markdown +864 -0
  323. data/test/progit/it/05-distributed-git/01-chapter5.markdown +897 -0
  324. data/test/progit/it/06-git-tools/01-chapter6.markdown +1144 -0
  325. data/test/progit/it/07-customizing-git/01-chapter7.markdown +606 -0
  326. data/test/progit/it/08-git-and-other-scms/01-chapter8.markdown +707 -0
  327. data/test/progit/it/09-git-internals/01-chapter9.markdown +1000 -0
  328. data/test/progit/ja/01-introduction/01-chapter1.markdown +260 -0
  329. data/test/progit/ja/02-git-basics/01-chapter2.markdown +1221 -0
  330. data/test/progit/ja/03-git-branching/01-chapter3.markdown +604 -0
  331. data/test/progit/ja/04-git-server/01-chapter4.markdown +863 -0
  332. data/test/progit/ja/05-distributed-git/01-chapter5.markdown +908 -0
  333. data/test/progit/ja/06-git-tools/01-chapter6.markdown +1133 -0
  334. data/test/progit/ja/07-customizing-git/01-chapter7.markdown +936 -0
  335. data/test/progit/ja/08-git-and-other-scms/01-chapter8.markdown +690 -0
  336. data/test/progit/ja/09-git-internals/01-chapter9.markdown +984 -0
  337. data/test/progit/ja/README.md +58 -0
  338. data/test/progit/ja/translation glossaries.txt +33 -0
  339. data/test/progit/ko/01-introduction/01-chapter1.markdown +258 -0
  340. data/test/progit/ko/02-git-basics/01-chapter2.markdown +1181 -0
  341. data/test/progit/ko/03-git-branching/01-chapter3.markdown +612 -0
  342. data/test/progit/ko/04-git-server/01-chapter4.markdown +867 -0
  343. data/test/progit/ko/05-distributed-git/01-chapter5.markdown +913 -0
  344. data/test/progit/ko/06-git-tools/01-chapter6.markdown +1142 -0
  345. data/test/progit/ko/07-customizing-git/01-chapter7.markdown +935 -0
  346. data/test/progit/ko/08-git-and-other-scms/01-chapter8.markdown +688 -0
  347. data/test/progit/ko/09-git-internals/01-chapter9.markdown +976 -0
  348. data/test/progit/ko/README.md +75 -0
  349. data/test/progit/ko/translation_guide.txt +65 -0
  350. data/test/progit/latex/README +27 -0
  351. data/test/progit/latex/config.yml +144 -0
  352. data/test/progit/latex/makepdf +207 -0
  353. data/test/progit/latex/template.tex +155 -0
  354. data/test/progit/makeebooks +125 -0
  355. data/test/progit/makepdfs +47 -0
  356. data/test/progit/mk/01-introduction/01-chapter1.markdown +258 -0
  357. data/test/progit/mk/02-git-basics/01-chapter2.markdown +1125 -0
  358. data/test/progit/mk/03-git-branching/01-chapter3.markdown +598 -0
  359. data/test/progit/mk/05-distributed-git/01-chapter5.markdown +897 -0
  360. data/test/progit/nl/01-introduction/01-chapter1.markdown +296 -0
  361. data/test/progit/nl/02-git-basics/01-chapter2.markdown +1253 -0
  362. data/test/progit/nl/03-git-branching/01-chapter3.markdown +642 -0
  363. data/test/progit/nl/04-git-server/01-chapter4.markdown +902 -0
  364. data/test/progit/nl/05-distributed-git/01-chapter5.markdown +953 -0
  365. data/test/progit/nl/06-git-tools/01-chapter6.markdown +1177 -0
  366. data/test/progit/nl/07-customizing-git/01-chapter7.markdown +974 -0
  367. data/test/progit/nl/08-git-and-other-scms/01-chapter8.markdown +725 -0
  368. data/test/progit/nl/09-git-internals/01-chapter9.markdown +1013 -0
  369. data/test/progit/no-nb/01-introduction/01-chapter1.markdown +261 -0
  370. data/test/progit/no-nb/02-git-basics/01-chapter2.markdown +1225 -0
  371. data/test/progit/no-nb/03-git-branching/01-chapter3.markdown +606 -0
  372. data/test/progit/no-nb/04-git-server/01-chapter4.markdown +867 -0
  373. data/test/progit/no-nb/05-distributed-git/01-chapter5.markdown +914 -0
  374. data/test/progit/no-nb/06-git-tools/01-chapter6.markdown +1144 -0
  375. data/test/progit/no-nb/07-customizing-git/01-chapter7.markdown +936 -0
  376. data/test/progit/no-nb/08-git-and-other-scms/01-chapter8.markdown +689 -0
  377. data/test/progit/no-nb/09-git-internals/01-chapter9.markdown +977 -0
  378. data/test/progit/no-nb/README +2 -0
  379. data/test/progit/pl/01-introduction/01-chapter1.markdown +257 -0
  380. data/test/progit/pl/02-git-basics/02-chapter2.markdown +1128 -0
  381. data/test/progit/pl/03-git-branching/01-chapter3.markdown +598 -0
  382. data/test/progit/pl/04-git-server/01-chapter4.markdown +897 -0
  383. data/test/progit/pl/05-distributed-git/01-chapter5.markdown +1278 -0
  384. data/test/progit/pl/06-git-tools/01-chapter6.markdown +1550 -0
  385. data/test/progit/pl/07-customizing-git/01-chapter7.markdown +1058 -0
  386. data/test/progit/pl/08-git-and-other-scms/01-chapter8.markdown +948 -0
  387. data/test/progit/pl/09-git-internals/01-chapter9.markdown +1382 -0
  388. data/test/progit/pl/translation-guidelines.txt +70 -0
  389. data/test/progit/pt-br/01-introduction/01-chapter1.markdown +256 -0
  390. data/test/progit/pt-br/02-git-basics/01-chapter2.markdown +1127 -0
  391. data/test/progit/pt-br/03-git-branching/01-chapter3.markdown +596 -0
  392. data/test/progit/pt-br/04-git-server/01-chapter4.markdown +888 -0
  393. data/test/progit/pt-br/05-distributed-git/01-chapter5.markdown +896 -0
  394. data/test/progit/pt-br/06-git-tools/01-chapter6.markdown +1122 -0
  395. data/test/progit/pt-br/07-customizing-git/01-chapter7.markdown +932 -0
  396. data/test/progit/pt-br/08-git-and-other-scms/01-chapter8.markdown +691 -0
  397. data/test/progit/pt-br/09-git-internals/01-chapter9.markdown +978 -0
  398. data/test/progit/pt-br/figures-dia/fig0101.dia +617 -0
  399. data/test/progit/pt-br/figures-dia/fig0102.dia +921 -0
  400. data/test/progit/pt-br/figures-dia/fig0103.dia +1468 -0
  401. data/test/progit/pt-br/figures-dia/fig0104.dia +1432 -0
  402. data/test/progit/pt-br/figures-dia/fig0105.dia +1924 -0
  403. data/test/progit/pt-br/figures-dia/fig0106.dia +562 -0
  404. data/test/progit/pt-br/figures-dia/fig0201.dia +776 -0
  405. data/test/progit/pt-br/figures-dia/fig0301.dia +2006 -0
  406. data/test/progit/pt-br/figures-dia/fig0302.dia +2148 -0
  407. data/test/progit/pt-br/figures-dia/fig0316.dia +1079 -0
  408. data/test/progit/pt-br/figures-dia/fig0322.dia +1142 -0
  409. data/test/progit/pt-br/figures-dia/fig0323.dia +1407 -0
  410. data/test/progit/pt-br/figures-dia/fig0324.dia +1603 -0
  411. data/test/progit/pt-br/figures-dia/fig0325.dia +2003 -0
  412. data/test/progit/pt-br/figures-dia/fig0326.dia +2013 -0
  413. data/test/progit/pt-br/figures-dia/fig0336.dia +786 -0
  414. data/test/progit/pt-br/figures-dia/fig0337.dia +1546 -0
  415. data/test/progit/pt-br/figures-dia/fig0338.dia +1755 -0
  416. data/test/progit/pt-br/figures-dia/fig0339.dia +1882 -0
  417. data/test/progit/pt-br/figures-dia/fig0501.dia +456 -0
  418. data/test/progit/pt-br/figures-dia/fig0502.dia +965 -0
  419. data/test/progit/pt-br/figures-dia/fig0503.dia +914 -0
  420. data/test/progit/pt-br/figures-dia/fig0511.dia +1201 -0
  421. data/test/progit/pt-br/figures-dia/fig0515.dia +1721 -0
  422. data/test/progit/pt-br/figures-dia/fig0702.dia +795 -0
  423. data/test/progit/pt-br/figures-dia/fig0703.dia +795 -0
  424. data/test/progit/pt-br/figures-dia/fig0901.dia +669 -0
  425. data/test/progit/pt-br/figures-dia/fig0902.dia +834 -0
  426. data/test/progit/pt-br/figures-dia/fig0903.dia +1483 -0
  427. data/test/progit/pt-br/figures-dia/fig0904.dia +1728 -0
  428. data/test/progit/ro/01-introduction/01-chapter1.markdown +257 -0
  429. data/test/progit/ru/01-introduction/01-chapter1.markdown +259 -0
  430. data/test/progit/ru/02-git-basics/01-chapter2.markdown +1155 -0
  431. data/test/progit/ru/03-git-branching/01-chapter3.markdown +598 -0
  432. data/test/progit/ru/04-git-server/01-chapter4.markdown +854 -0
  433. data/test/progit/ru/05-distributed-git/01-chapter5.markdown +897 -0
  434. data/test/progit/ru/06-git-tools/01-chapter6.markdown +1126 -0
  435. data/test/progit/ru/07-customizing-git/01-chapter7.markdown +938 -0
  436. data/test/progit/ru/08-git-and-other-scms/01-chapter8.markdown +691 -0
  437. data/test/progit/ru/09-git-internals/01-chapter9.markdown +977 -0
  438. data/test/progit/ru/Glossary +38 -0
  439. data/test/progit/ru/README +12 -0
  440. data/test/progit/ru/figures-dia/fig0101.dia +647 -0
  441. data/test/progit/ru/figures-dia/fig0102.dia +1009 -0
  442. data/test/progit/ru/figures-dia/fig0103.dia +1468 -0
  443. data/test/progit/ru/figures-dia/fig0104.dia +1432 -0
  444. data/test/progit/ru/figures-dia/fig0105.dia +1924 -0
  445. data/test/progit/ru/figures-dia/fig0106.dia +561 -0
  446. data/test/progit/ru/figures-dia/fig0201.dia +774 -0
  447. data/test/progit/ru/figures-dia/fig0322.dia +1182 -0
  448. data/test/progit/ru/figures-dia/fig0323.dia +1457 -0
  449. data/test/progit/ru/figures-dia/fig0324.dia +1698 -0
  450. data/test/progit/ru/figures-dia/fig0325.dia +2101 -0
  451. data/test/progit/ru/figures-dia/fig0326.dia +2111 -0
  452. data/test/progit/ru/figures-dia/fig0336.dia +786 -0
  453. data/test/progit/ru/figures-dia/fig0337.dia +1546 -0
  454. data/test/progit/ru/figures-dia/fig0338.dia +1755 -0
  455. data/test/progit/ru/figures-dia/fig0339.dia +1882 -0
  456. data/test/progit/ru/figures-dia/fig0501.dia +477 -0
  457. data/test/progit/ru/figures-dia/fig0502.dia +1063 -0
  458. data/test/progit/ru/figures-dia/fig0503.dia +915 -0
  459. data/test/progit/ru/figures-dia/fig0511.dia +1201 -0
  460. data/test/progit/ru/figures-dia/fig0515.dia +1741 -0
  461. data/test/progit/ru/figures-dia/fig0702.dia +851 -0
  462. data/test/progit/ru/figures-dia/fig0703.dia +851 -0
  463. data/test/progit/sr/01-introduction/01-chapter1.markdown +257 -0
  464. data/test/progit/summary.rb +29 -0
  465. data/test/progit/th/01-introduction/01-chapter1.markdown +257 -0
  466. data/test/progit/th/02-git-basics/01-chapter2.markdown +1126 -0
  467. data/test/progit/th/README.md +47 -0
  468. data/test/progit/tr/01-introduction/01-chapter1.markdown +258 -0
  469. data/test/progit/tr/02-git-basics/01-chapter2.markdown +1129 -0
  470. data/test/progit/tr/03-git-branching/01-chapter3.markdown +598 -0
  471. data/test/progit/tr/04-git-server/01-chapter4.markdown +73 -0
  472. data/test/progit/tr/05-distributed-git/01-chapter5.markdown +215 -0
  473. data/test/progit/uk/01-introduction/01-chapter1.markdown +522 -0
  474. data/test/progit/vi/01-introduction/01-chapter1.markdown +259 -0
  475. data/test/progit/vi/02-git-basics/01-chapter2.markdown +1172 -0
  476. data/test/progit/vi/03-git-branching/01-chapter3.markdown +598 -0
  477. data/test/progit/zh-tw/01-introduction/01-chapter1.markdown +259 -0
  478. data/test/progit/zh-tw/02-git-basics/01-chapter2.markdown +1183 -0
  479. data/test/progit/zh-tw/03-git-branching/01-chapter3.markdown +604 -0
  480. data/test/progit/zh-tw/04-git-server/01-chapter4.markdown +866 -0
  481. data/test/progit/zh-tw/05-distributed-git/01-chapter5.markdown +912 -0
  482. data/test/progit/zh-tw/06-git-tools/01-chapter6.markdown +1139 -0
  483. data/test/progit/zh-tw/07-customizing-git/01-chapter7.markdown +932 -0
  484. data/test/progit/zh-tw/08-git-and-other-scms/01-chapter8.markdown +689 -0
  485. data/test/progit/zh-tw/09-git-internals/01-chapter9.markdown +977 -0
  486. data/test/progit/zh/01-introduction/01-chapter1.markdown +259 -0
  487. data/test/progit/zh/02-git-basics/01-chapter2.markdown +1177 -0
  488. data/test/progit/zh/03-git-branching/01-chapter3.markdown +604 -0
  489. data/test/progit/zh/04-git-server/01-chapter4.markdown +866 -0
  490. data/test/progit/zh/05-distributed-git/01-chapter5.markdown +912 -0
  491. data/test/progit/zh/06-git-tools/01-chapter6.markdown +1125 -0
  492. data/test/progit/zh/07-customizing-git/01-chapter7.markdown +935 -0
  493. data/test/progit/zh/08-git-and-other-scms/01-chapter8.markdown +689 -0
  494. data/test/progit/zh/09-git-internals/01-chapter9.markdown +976 -0
  495. data/test/spec_tests.json +4382 -4070
  496. data/test/test_basics.rb +1 -1
  497. data/test/test_helper.rb +1 -0
  498. data/test/test_maliciousness.rb +4 -2
  499. data/test/test_pathological_inputs.rb +31 -30
  500. data/test/test_spec.rb +5 -4
  501. metadata +972 -4
@@ -0,0 +1,984 @@
1
+ # Gitの内側 #
2
+
3
+ あなたは前の章を飛ばしてこの章に来たのでしょうか、あるいは、この本の他の部分を読んだ後で来たのでしょうか。いずれにせよ、この章ではGit の内部動作と実装を辿っていくことになります。内部動作と実装を学ぶことは、Git がどうしてこんなに便利で有効なのかを根本的に理解するのに重要です。しかし初心者にとっては不必要に複雑で混乱を招いてしまうという人もいました。そのため、遅かれ早かれ学習の仕方に合わせて読めるように、この話題を最後の章に配置しました。いつ読むかって? それは読者の判断にお任せします。
4
+
5
+ もう既にあなたはこの章を読んでいますので、早速、開始しましょう。まず、基本的にGit は連想記憶ファイル・システム(content-addressable filesystem)であり、その上にVCS ユーザー・インターフェイスが記述されているのです。これが意味することを、もう少し見て行きましょう。
6
+
7
+ 初期のGit(主として1.5以前)は、洗練されたVCS というよりもむしろファイル・システムであることを(Gitの特徴として)強調しており、それ故に、ユーザー・インターフェイスは今よりも複雑なものでした。ここ数年の間に、世の中のどのシステムにも劣らないほどGit のユーザー・インターフェイスはシンプルで扱いやすいものに改良されました。しかし、複雑で学習するのが難しいという初期のGit に対する型にはまったイメージはまだ残っています。
8
+
9
+
10
+ 連想記憶ファイル・システム層は驚くほど素晴らしいので、この章の最初にそれをカバーすることにします。その次に転送メカニズムと、今後あなたが行う必要があるかもしれないリポジトリの保守作業について学習することにします。
11
+
12
+ ## 配管(Plumbing)と磁器(Porcelain) ##
13
+
14
+ 本書は、`checkout` や `branch`、`remote` などの約30のコマンドを用いて、Git の使い方を説明しています。ですが、Git は元々、完全にユーザフレンドリーなバージョン管理システムというよりもむしろ、バージョン管理システムのためのツール類でした。そのため、下位レベルの仕事を行うためのコマンドが沢山あり、UNIXの形式(またはスクリプトから呼ばれる形式)と密に関わりながら設計されました。これらのコマンドは、通常は "配管(plumbing)" コマンドと呼ばれ、よりユーザフレンドリーなコマンドは "磁器(porcelain)" コマンドと呼ばれます。
15
+
16
+ 本書のはじめの8つの章は、ほぼ例外なく磁器コマンドを取り扱いますが、本章では下位レベルの配管コマンドを専ら使用することになります。なぜなら、それらのコマンドは、Gitの内部動作にアクセスして、Gitの内部で、何を、どのように、どうして行うのかを確かめるのに役に立つからです。それらのコマンドは、コマンドラインから実行するのに使用されるのではなく、むしろ新規のツールとカスタムスクリプトのための構成要素(building blocks)として使用されます。
17
+
18
+ 新規の、または既存のディレクトリで `git init` を実行すると、Git は `.git` というディレクトリを作ります。Git が保管して操作するほとんどすべてのものがそこに格納されます。もしもレポジトリをバックアップするかクローンを作りたいなら、この1つのディレクトリをどこかにコピーすることで、必要とするほとんどすべてのことが満たされます。この章では全体を通して、`.git` ディレクトリの中を基本的に取り扱います。その中は以下のようになっています。
19
+
20
+ $ ls
21
+ HEAD
22
+ branches/
23
+ config
24
+ description
25
+ hooks/
26
+ index
27
+ info/
28
+ objects/
29
+ refs/
30
+
31
+ これは `git init` を実行した直後のデフォルトのレポジトリです。それ以外の場合は、他にも幾つかのファイルがそこに見つかるかもしれません。`branches` ディレクトリは、新しいバージョンのGitでは使用されません。`description` ファイルは、GitWeb プログラムのみで使用します。そのため、それらについての配慮は不要です。`config` ファイルには、あなたのプロジェクト固有の設定オプションが含まれます。`info` ディレクトリは、追跡されている `.gitignore` ファイルには記述したくない無視パターンを書くための、グローバルレベルの除外設定ファイルを保持します。`hooks` ディレクトリには、あなたのクライアントサイド、または、サーバサイドのフックスクリプトが含まれます。それについての詳細は7章に記述されています。
32
+
33
+ 残りの4つ(`HEAD` ファイルと `index` ファイル、また、`objects` ディレクトリと `refs` ディレクトリ)は重要なエントリです。これらは、Git の中核(コア)の部分に相当します。`objects` ディレクトリはあなたのデータベースのすべてのコンテンツを保管します。`refs` ディレクトリは、そのデータ(ブランチ)内のコミットオブジェクトを指すポインターを保管します。`HEAD` ファイルは、現在チェックアウトしているブランチを指します。`index` ファイルは、Git がステージングエリアの情報の保管する場所を示します。これから各セクションで、Git がどのような仕組みで動くのかを詳細に見ていきます。
34
+
35
+ ## Gitオブジェクト ##
36
+
37
+ Git は連想記憶ファイル・システムです。素晴らしい。…で、それはどういう意味なのでしょう?それは、Git のコアの部分が単純なキーバリューから成り立つデータストアである、という意味です。`hash-object` という配管コマンドを使用することで、それを実際にお見せすることができます。そのコマンドはあるデータを取り出して、それを `.git` ディレクトリに格納し、そのデータが格納された場所を示すキーを返します。まずは、初期化された新しいGit レポジトリには `objects` ディレクトリが存在しないことを確認します。
38
+
39
+ $ mkdir test
40
+ $ cd test
41
+ $ git init
42
+ Initialized empty Git repository in /tmp/test/.git/
43
+ $ find .git/objects
44
+ .git/objects
45
+ .git/objects/info
46
+ .git/objects/pack
47
+ $ find .git/objects -type f
48
+ $
49
+
50
+ Git は `objects` ディレクトリを初期化して、その中に `pack` と `info` というサブディレクトリを作ります。しかし、ファイルはひとつも作られません。今から Git データベースに幾つかのテキストを格納してみます。
51
+
52
+ $ echo 'test content' | git hash-object -w --stdin
53
+ d670460b4b4aece5915caf5c68d12f560a9fe3e4
54
+
55
+ `-w` オプションは `hash-object` に、オブジェクトを格納するように伝えます。`-w` オプションを付けない場合、コマンドはただオブジェクトのキーが何かを伝えます。`--stdin` オプションは、標準入力からコンテンツを読み込むようにコマンドに伝えます。これを指定しない場合、`hash-object` はファイルパスを探そうとします。コマンドを実行すると、40文字から成るチェックサムのハッシュ値が出力されます。これは、SHA-1ハッシュです。(後ほど知ることになりますが、これは格納するコンテンツにヘッダーを加えたデータに対するチェックサムです)これでGitがデータをどのようにして格納するかを知ることができました。
56
+
57
+ $ find .git/objects -type f
58
+ .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
59
+
60
+ ひとつのファイルが objectsディレクトリの中にあります。このようして Git は、最初にコンテンツを格納します。ひとつの部分のコンテンツにつき 1ファイルで、コンテンツとそのヘッダーに対する SHA-1のチェックサムを用いたファイル名で格納します。サブディレクトリは、SHA-1ハッシュのはじめの2文字で名付けられ、残りの38文字でファイル名が決まります。
61
+
62
+ `cat-file` コマンドを使って、コンテンツを Git の外に引き出すことができます。これは Git オブジェクトを調べることにおいて、`cat-file` は万能ナイフ(Swiss army knife)のような便利なコマンドです。`-p` オプションを付けると、`cat-file` コマンドはコンテンツのタイプをわかりやすく表示してくれます。
63
+
64
+ $ git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4
65
+ test content
66
+
67
+ これであなたは Git にコンテンツを追加し、それを再び外に引き出すことができるようになりました。複数のファイルがあるコンテンツに対してもこれと同様のことを行うことができます。例えば、あるファイルに対して幾つかの簡単なバージョン管理行うことができます。まず、新規にファイルを作成し、あなたのデータベースにそのコンテンツを保存します。
68
+
69
+ $ echo 'version 1' > test.txt
70
+ $ git hash-object -w test.txt
71
+ 83baae61804e65cc73a7201a7252750c76066a30
72
+
73
+ それから、幾つか新しいコンテンツをそのファイルに書き込んで、再び保存します。
74
+
75
+ $ echo 'version 2' > test.txt
76
+ $ git hash-object -w test.txt
77
+ 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a
78
+
79
+ データベースには、そこに格納した最初のコンテンツのバージョンに加えて、そのファイルの新しいバージョンが二つ追加されています。
80
+
81
+ $ find .git/objects -type f
82
+ .git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a
83
+ .git/objects/83/baae61804e65cc73a7201a7252750c76066a30
84
+ .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
85
+
86
+ これで、そのファイルを最初のバージョンに復帰(revert)することができます。
87
+
88
+ $ git cat-file -p 83baae61804e65cc73a7201a7252750c76066a30 > test.txt
89
+ $ cat test.txt
90
+ version 1
91
+
92
+ あるいは、二つ目のバージョンに。
93
+
94
+ $ git cat-file -p 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a > test.txt
95
+ $ cat test.txt
96
+ version 2
97
+
98
+ しかし、それぞれのファイルのバージョンの SHA-1キーを覚えることは実用的ではありません。加えて、あなたはコンテンツのみを格納していてファイル名はシステム内に格納していません。このオブジェクトタイプはブロブ(blob)と呼ばれます。`cat-file -t` コマンドに SHA-1キーを渡すことで、あなたは Git 内にあるあらゆるオブジェクトのタイプを問い合わせることができます。
99
+
100
+ $ git cat-file -t 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a
101
+ blob
102
+
103
+ ### ツリーオブジェクト ###
104
+
105
+ 次のタイプはツリーオブジェクトです。これは、ファイル名の格納の問題を解決して、さらに、あるグループに属するファイル群を一緒に格納します。Git がコンテンツを格納する方法は、UNIXのファイルシステムに似ていますが少し簡略されています。すべてのコンテンツはツリーとブロブのオブジェクトとして格納されます。ツリーは UNIXのディレクトリエントリーに対応しており、ブロブは幾分かは iノード またはファイルコンテンツに対応しています。1つのツリーオブジェクトは1つ以上のツリーエントリーを含んでいて、またそれらのツリーは、それに関連するモード、タイプ、そしてファイル名と一緒に、ブロブまたはサブツリーへの SHA-1ポインターを含んでいます。例えば、最も単純なプロジェクトの最新のツリーはこのように見えるかもしれません。
106
+
107
+ $ git cat-file -p master^{tree}
108
+ 100644 blob a906cb2a4a904a152e80877d4088654daad0c859 README
109
+ 100644 blob 8f94139338f9404f26296befa88755fc2598c289 Rakefile
110
+ 040000 tree 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0 lib
111
+
112
+ `master^{tree}` のシンタックスは、`master` ブランチ上での最後のコミットによってポイントされたツリーオブジェクトを示します。`lib` サブディレクトリがブロブではなく、別のツリーへのポインタであることに注意してください。
113
+
114
+ $ git cat-file -p 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0
115
+ 100644 blob 47c6340d6459e05787f644c2447d2595f5d3a54b simplegit.rb
116
+
117
+ 概念的に、Git が格納するデータは図9-1のようなものです。
118
+
119
+ Insert 18333fig0901.png
120
+ 図9-1. Gitデータモデルの簡略版
121
+
122
+ 独自のツリーを作ることも可能です。Git は通常、ステージングエリアもしくはインデックスの状態を取得することによってツリーを作成し、
123
+ そこからツリーオブジェクトを書き込みます。そのため、ツリーオブジェクトを作るには、まず幾つかのファイルをステージングしてインデックスをセットアップしなければなりません。
124
+ test.txt ファイルの最初のバージョンである単一エントリーのインデックスを作るには、`update-index` という配管コマンドを使います。
125
+ 前バージョンの test.txt ファイルを新しいステージングエリアに人為的に追加するにはこのコマンドを使います。
126
+ ファイルはまだステージングエリアには存在しない(未だステージングエリアをセットアップさえしていない)ので、`--add` オプションを付けなければなりません。
127
+ また、追加しようとしているファイルはディレクトリには無くデータベースにあるので、`--cacheinfo`オプションを付ける必要があります。
128
+ その次に、モードと SHA-1、そしてファイル名を指定します。
129
+
130
+ $ git update-index --add --cacheinfo 100644 \
131
+ 83baae61804e65cc73a7201a7252750c76066a30 test.txt
132
+
133
+ この例では、`100644` のモードを指定しています。これは、それが通常のファイルであることを意味します。他には、実行可能ファイルであることを意味する `100755` や、シンボリックリンクであることを示す `120000` のオプションがあります。このモードは通常の UNIX モードから取り入れた概念ですが融通性はもっと劣ります。これら三つのモードは、(他のモードはディレクトリとサブモジュールに使用されますが)Git のファイル(ブロブ)に対してのみ有効です。
134
+
135
+ これであなたは `write-tree` コマンドを使って、ステージングエリアをツリーオブジェクトに書き出すことができます。`-w` オプションは一切必要とされません。`write-tree` コマンドを呼ぶことで、ツリーがまだ存在しない場合に、自動的にインデックスの状態からツリーオブジェクトを作ります。
136
+
137
+ $ git write-tree
138
+ d8329fc1cc938780ffdd9f94e0d364e0ea74f579
139
+ $ git cat-file -p d8329fc1cc938780ffdd9f94e0d364e0ea74f579
140
+ 100644 blob 83baae61804e65cc73a7201a7252750c76066a30 test.txt
141
+
142
+ また、これがツリーオブジェクトであることを検証することができます。
143
+
144
+ $ git cat-file -t d8329fc1cc938780ffdd9f94e0d364e0ea74f579
145
+ tree
146
+
147
+ これから、二つ目のバージョンの test.txt に新しいファイルを加えて新しくツリーを作ります。
148
+
149
+ $ echo 'new file' > new.txt
150
+ $ git update-index test.txt
151
+ $ git update-index --add new.txt
152
+
153
+ これでステージングエリアには、new.txt という新しいファイルに加えて、新しいバージョンの test.txt を持つようになります。(ステージングエリアまたはインデックスの状態を記録している)そのツリーを書き出してみると、以下のように見えます。
154
+
155
+ $ git write-tree
156
+ 0155eb4229851634a0f03eb265b69f5a2d56f341
157
+ $ git cat-file -p 0155eb4229851634a0f03eb265b69f5a2d56f341
158
+ 100644 blob fa49b077972391ad58037050f2a75f74e3671e92 new.txt
159
+ 100644 blob 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a test.txt
160
+
161
+ このツリーは両方のファイルエントリを持っていて、さらに、test.txt の SHA-1ハッシュは最初の文字(`1f7a7a`)から "バージョン2" の SHA-1ハッシュとなっていることに注意してください。ちょっと試しに、最初のツリーをサブディレクトリとしてこの中の1つに追加してみましょう。`read-tree` を呼ぶことで、ステージングエリアの中にツリーを読み込むことができます。このケースでは、`--prefix` オプションを付けて `read-tree` コマンド使用することで、ステージングエリアの中に既存のツリーを、サブツリーとして読み込むことができます。
162
+
163
+ $ git read-tree --prefix=bak d8329fc1cc938780ffdd9f94e0d364e0ea74f579
164
+ $ git write-tree
165
+ 3c4e9cd789d88d8d89c1073707c3585e41b0e614
166
+ $ git cat-file -p 3c4e9cd789d88d8d89c1073707c3585e41b0e614
167
+ 040000 tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579 bak
168
+ 100644 blob fa49b077972391ad58037050f2a75f74e3671e92 new.txt
169
+ 100644 blob 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a test.txt
170
+
171
+ 先ほど書き込んだ新しいツリーから作業ディレクトリを作っていれば、二つのファイルが作業ディレクトリのトップレベルに見つかり、また、最初のバージョンの test.txt ファイルが含まれている `bak` という名前のサブディレクトリが見つかります。これらの構造のために Git がデータをどのように含めているかは、図9-2のようにイメージすることができます。
172
+
173
+ Insert 18333fig0902.png
174
+ 図9-2. 現在のGitデータのコンテンツ構造
175
+
176
+ ### コミットオブジェクト ###
177
+
178
+ 追跡(track)したいと思うプロジェクトの異なるスナップショットを特定するためのツリーが三つありますが、前の問題が残っています。スナップショットを呼び戻すためには3つすべての SHA-1 の値を覚えなければならない、という問題です。さらに、あなたはそれらのスナップショットがいつ、どのような理由で、誰が保存したのかについての情報を一切持っておりません。これはコミットオブジェクトがあなたのために保持する基本的な情報です。
179
+
180
+ コミットオブジェクトを作成するには、単一ツリーの SHA-1 と、もしそれに直に先行して作成されたコミットオブジェクトがあれば、それらを指定して `commit-tree` を呼びます。あなたが書き込んだ最初のツリーから始めましょう。
181
+
182
+ $ echo 'first commit' | git commit-tree d8329f
183
+ fdf4fc3344e67ab068f836878b6c4951e3b15f3d
184
+
185
+ これで `cat-file` コマンドを呼んで新しいコミットオブジェクトを見ることができます。
186
+
187
+ $ git cat-file -p fdf4fc3
188
+ tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579
189
+ author Scott Chacon <schacon@gmail.com> 1243040974 -0700
190
+ committer Scott Chacon <schacon@gmail.com> 1243040974 -0700
191
+
192
+ first commit
193
+
194
+ コミットオブジェクトの形式はシンプルです。それはプロジェクトのその時点のスナップショットに対して、トップレベルのツリーを指定します。その時点のスナップショットには、現在のタイムスタンプと共に `user.name` と `user.email` の設定から引き出された作者(author)/コミッター(committer)の情報、ブランクライン、そしてコミットメッセージが含まれます。
195
+
196
+ 次に、あなたは二つのコミットオブジェクトを書き込みます。各コミットオブジェクトはその直前に来たコミットを参照しています。
197
+
198
+ $ echo 'second commit' | git commit-tree 0155eb -p fdf4fc3
199
+ cac0cab538b970a37ea1e769cbbde608743bc96d
200
+ $ echo 'third commit' | git commit-tree 3c4e9c -p cac0cab
201
+ 1a410efbd13591db07496601ebc7a059dd55cfe9
202
+
203
+ 三つのコミットオブジェクトは、それぞれ、あなたが作成した三つのスナップショットのツリーのひとつを指し示しています。面白いことに、あなたは本物のGitヒストリーを持っており、`git log` コマンドによってログをみることができます。もしも最後のコミットの SHA-1ハッシュを指定して実行すると、
204
+
205
+ $ git log --stat 1a410e
206
+ commit 1a410efbd13591db07496601ebc7a059dd55cfe9
207
+ Author: Scott Chacon <schacon@gmail.com>
208
+ Date: Fri May 22 18:15:24 2009 -0700
209
+
210
+ third commit
211
+
212
+ bak/test.txt | 1 +
213
+ 1 files changed, 1 insertions(+), 0 deletions(-)
214
+
215
+ commit cac0cab538b970a37ea1e769cbbde608743bc96d
216
+ Author: Scott Chacon <schacon@gmail.com>
217
+ Date: Fri May 22 18:14:29 2009 -0700
218
+
219
+ second commit
220
+
221
+ new.txt | 1 +
222
+ test.txt | 2 +-
223
+ 2 files changed, 2 insertions(+), 1 deletions(-)
224
+
225
+ commit fdf4fc3344e67ab068f836878b6c4951e3b15f3d
226
+ Author: Scott Chacon <schacon@gmail.com>
227
+ Date: Fri May 22 18:09:34 2009 -0700
228
+
229
+ first commit
230
+
231
+ test.txt | 1 +
232
+ 1 files changed, 1 insertions(+), 0 deletions(-)
233
+
234
+ 驚くべきことです。あなたは Git ヒストリーを形成するために、フロントエンドにある何かを利用することせずに、ただ下位レベルのオペレーションを行っただけなのです。これは `git add` コマンドと `git commit` コマンドを実行するときに Git が行う本質的なことなのです。それは変更されたファイルに対応して、ブロブを格納し、インデックスを更新し、ツリーを書き出します。そして、トップレベルのツリーとそれらの直前に来たコミットを参照するコミットオブジェクトを書きます。これらの三つの主要な Git オブジェクト - ブロブとツリーとコミットは、`.git/object` ディレクトリに分割されたファイルとして最初に格納されます。こちらは、例のディレクトリに今あるすべてのオブジェクトであり、それらが何を格納しているのかコメントされています。
235
+
236
+ $ find .git/objects -type f
237
+ .git/objects/01/55eb4229851634a0f03eb265b69f5a2d56f341 # tree 2
238
+ .git/objects/1a/410efbd13591db07496601ebc7a059dd55cfe9 # commit 3
239
+ .git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a # test.txt v2
240
+ .git/objects/3c/4e9cd789d88d8d89c1073707c3585e41b0e614 # tree 3
241
+ .git/objects/83/baae61804e65cc73a7201a7252750c76066a30 # test.txt v1
242
+ .git/objects/ca/c0cab538b970a37ea1e769cbbde608743bc96d # commit 2
243
+ .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 # 'test content'
244
+ .git/objects/d8/329fc1cc938780ffdd9f94e0d364e0ea74f579 # tree 1
245
+ .git/objects/fa/49b077972391ad58037050f2a75f74e3671e92 # new.txt
246
+ .git/objects/fd/f4fc3344e67ab068f836878b6c4951e3b15f3d # commit 1
247
+
248
+ もしすべての内部のポインタを辿ってゆけば、図9-3のようなオブジェクトグラフを得られます。
249
+
250
+ Insert 18333fig0903.png
251
+ 図9-3. Gitレポジトリ内のすべてのオブジェクト
252
+
253
+ ### オブジェクトストレージ ###
254
+
255
+ ヘッダはコンテンツと一緒に格納されることを、以前に述べました。少し時間を割いて、Git がどのようにしてオブジェクトを格納するのかを見ていきましょう。あなたはブロブオブジェクトがどのように格納されるのかを見ることになるでしょう。このケースでは "what is up, doc?" という文字列が Rubyスクリプト言語の中で対話的に格納されます。`irb` コマンドを使って対話的な Rubyモードを開始します。
256
+
257
+ $ irb
258
+ >> content = "what is up, doc?"
259
+ => "what is up, doc?"
260
+
261
+ Git はオブジェクトタイプで開始するヘッダを構成します。このケースではブロブのタイプです。そして、コンテンツのサイズに従ってスペースを追加して、最後にヌルバイトを追加します。
262
+
263
+ >> header = "blob #{content.length}\0"
264
+ => "blob 16\000"
265
+
266
+ Git はヘッダとオリジナルのコンテンツとを結合して、その新しいコンテンツの SHA-1チェックサムを計算します。Rubyスクリプト内に書かれた文字列のSHA-1のハッシュ値は、`require` を使用して SHA1ダイジェストライブラリをインクルードし、文字列を引数にして `Digest::SHA1.hexdigest()` 関数を呼ぶことで求めることができます。
267
+
268
+ >> store = header + content
269
+ => "blob 16\000what is up, doc?"
270
+ >> require 'digest/sha1'
271
+ => true
272
+ >> sha1 = Digest::SHA1.hexdigest(store)
273
+ => "bd9dbf5aae1a3862dd1526723246b20206e5fc37"
274
+
275
+ Gitは zlib を用いて新しいコンテンツを圧縮します。Rubyにある zlibライブラリをインクルードして使用します。まず、require を使用して zlib ライブラリをインクルードし、コンテンツに対して `Zlib::Deflate.deflate()` を実行します。
276
+
277
+ >> require 'zlib'
278
+ => true
279
+ >> zlib_content = Zlib::Deflate.deflate(store)
280
+ => "x\234K\312\311OR04c(\317H,Q\310,V(-\320QH\311O\266\a\000_\034\a\235"
281
+
282
+ 最後に、zlibで圧縮された(zlib-deflated)コンテンツをディスク上のオブジェクトに書き込みます。オブジェクトの書き込み先のパスを決定します(SHA-1ハッシュ値の最初の2文字はサブディレクトリの名前で、残りの38文字はそのディレクトリ内のファイル名になります)。Rubyでは、`FileUtils.mkdir_p()` 関数を使用して(存在しない場合に)サブディレクトリを作成することができます。そして、`File.open()` によってファイルを開いて、前に zlib で圧縮された(zlib-compressed)コンテンツをファイルに書き出します。ファイルへの書き出しは、開いたファイルのハンドルに対して `write()` を呼ぶことで行います。
283
+
284
+ >> path = '.git/objects/' + sha1[0,2] + '/' + sha1[2,38]
285
+ => ".git/objects/bd/9dbf5aae1a3862dd1526723246b20206e5fc37"
286
+ >> require 'fileutils'
287
+ => true
288
+ >> FileUtils.mkdir_p(File.dirname(path))
289
+ => ".git/objects/bd"
290
+ >> File.open(path, 'w') { |f| f.write zlib_content }
291
+ => 32
292
+
293
+ これで終わりです。あなたは妥当な Git ブロブオブジェクトを作りました。ただタイプが異なるだけで、Git オブジェクトはすべて同じ方法で格納されます。ブロブの文字列ではない場合には、ヘッダはコミットまたはツリーから始まります。また、ブロブのコンテンツはほぼ何にでもなれるのに対して、コミットとツリーのコンテンツはかなり特定的に形式付けられています。
294
+
295
+ ## Gitの参照 ##
296
+
297
+ すべての履歴をひと通り見るには `git log 1a410e` のように実行します。しかしそれでも履歴を辿りながらそれらすべてのオブジェクトを見つけるためには、`1a410e` が最後のコミットであることを覚えていなければなりません。SHA-1ハッシュ値を格納できるファイルが必要です。ファイル名はシンプルなもので、未加工(raw)の SHA-1ハッシュ値ではなくポインタを使用することができます。
298
+
299
+ Git では、これらは "参照(references)" ないしは "refs" と呼ばれます。SHA-1のハッシュ値を含んでいるファイルは `.git/refs` ディレクトリ内に見つけることができます。現在のプロジェクトでは、このディレクトリに何もファイルはありませんが、シンプルな構成を持っています。
300
+
301
+ $ find .git/refs
302
+ .git/refs
303
+ .git/refs/heads
304
+ .git/refs/tags
305
+ $ find .git/refs -type f
306
+ $
307
+
308
+ 最後のコミットはどこにあるのかを覚えるのに役立つような参照を新しく作るには、これと同じぐらいシンプルなことを技術的にすることができます。
309
+
310
+ $ echo "1a410efbd13591db07496601ebc7a059dd55cfe9" > .git/refs/heads/master
311
+
312
+ これであなたは、Git コマンドにある SHA-1のハッシュ値ではなく、たった今作成したヘッダの参照を使用することができます。
313
+
314
+ $ git log --pretty=oneline master
315
+ 1a410efbd13591db07496601ebc7a059dd55cfe9 third commit
316
+ cac0cab538b970a37ea1e769cbbde608743bc96d second commit
317
+ fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit
318
+
319
+ 参照ファイルに対して直接、変更を行うことは推奨されません。Git はそれを行うためのより安全なコマンドを提供しています。もし参照を更新したければ `update-ref` というコマンドを呼びます。
320
+
321
+ $ git update-ref refs/heads/master 1a410efbd13591db07496601ebc7a059dd55cfe9
322
+
323
+ Git にとって基本的にブランチとは何なのかをこれは示しているのです。すなわちそれはシンプルなポインタ、もしくは作業ライン(line of work)のヘッドへの参照なのです。二回目のコミット時にバックアップのブランチを作るには、次のようにします。
324
+
325
+ $ git update-ref refs/heads/test cac0ca
326
+
327
+ これでブランチはそのコミットから下の作業のみを含むことになります。
328
+
329
+ $ git log --pretty=oneline test
330
+ cac0cab538b970a37ea1e769cbbde608743bc96d second commit
331
+ fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit
332
+
333
+ いま、Git のデータベースは概念的には図9-4のように見えます。
334
+
335
+ Insert 18333fig0904.png
336
+ 図9-4. ブランチのヘッドへの参照を含むGitディレクトリオブジェクト
337
+
338
+ `git branch (ブランチ名)` のようにコマンドを実行すると基本的に Git は `update-ref` コマンドを実行します。そして、あなたが作りたいと思っている新しい参照は何であれ、いま自分が作業しているブランチ上のブランチの最後のコミットの SHA-1ハッシュを追加します。
339
+
340
+ ### HEADブランチ ###
341
+
342
+ では、`git branch (ブランチ名)` を実行したときに、どこから Git は最後のコミットの SHA-1ハッシュを知ることができるでしょうか? 答えは、HEADファイルです。HEADファイルは、あなたが現在作業中のブランチに対するシンボリック参照(symbolic reference)です。通常の参照と区別する意図でシンボリック参照と呼びますが、それは、一般的にSHA-1ハッシュ値を持たずに他の参照へのポインタを持ちます。通常は以下のファイルが見えるでしょう。
343
+
344
+ $ cat .git/HEAD
345
+ ref: refs/heads/master
346
+
347
+ `git checkout test` を実行すると、Git はこのようにファイルを更新します。
348
+
349
+ $ cat .git/HEAD
350
+ ref: refs/heads/test
351
+
352
+ `git commit` を実行すると、コミットオブジェクトが作られます。HEADにある参照先の SHA-1ハッシュ値が何であれ、そのコミットオブジェクトの親が参照先に指定されます。
353
+
354
+ このファイルを直に編集することもできますが、`symbolic-ref` と呼ばれる、それを安全に行うためのコマンドが存在します。このコマンドを使ってHEADの値を読み取ることができます。
355
+
356
+ $ git symbolic-ref HEAD
357
+ refs/heads/master
358
+
359
+ HEADの値を設定することもできます。
360
+
361
+ $ git symbolic-ref HEAD refs/heads/test
362
+ $ cat .git/HEAD
363
+ ref: refs/heads/test
364
+
365
+ `refs` の形式以外では、シンボリック参照を設定することはできません。
366
+
367
+ $ git symbolic-ref HEAD test
368
+ fatal: Refusing to point HEAD outside of refs/
369
+
370
+ ### タグ ###
371
+
372
+ これまで Git の主要な三つのオブジェクトを見てきましたが、タグという四つ目のオブジェクトがあります。タグオブジェクトはコミットオブジェクトにとても似ています。それには、タガー(tagger)、日付、メッセージ、そしてポインタが含まれます。主な違いは、タグオブジェクトはツリーではなくコミットを指し示すことです。タグオブジェクトはブランチの参照に似ていますが、決して変動しません。そのため常に同じコミットを示しますが、より親しみのある名前が与えられます。
373
+
374
+ 2章で述べましたが、タグには二つのタイプがあります。軽量 (lightweight) 版と注釈付き (annotated) 版です。あなたは、次のように実行して軽量 (lightweight) 版のタグを作ることができます。
375
+
376
+ $ git update-ref refs/tags/v1.0 cac0cab538b970a37ea1e769cbbde608743bc96d
377
+
378
+ これが軽量版のタグのすべてです。つまり決して変動しないブランチなのです。一方、注釈付き版のタグはもっと複雑です。注釈付き版のタグを作ろうとすると、Git はタグオブジェクトを作り、そして、コミットに対する直接的な参照ではなく、そのタグをポイントする参照を書き込みます。注釈付き版のタグを作ることで、これを見ることができます。(注釈付き版のタグを作るには `-a` オプションを指定して実行します)
379
+
380
+ $ git tag -a v1.1 1a410efbd13591db07496601ebc7a059dd55cfe9 -m 'test tag'
381
+
382
+ これで、作られたオブジェクトの SHA-1ハッシュ値を見ることができます。
383
+
384
+ $ cat .git/refs/tags/v1.1
385
+ 9585191f37f7b0fb9444f35a9bf50de191beadc2
386
+
387
+ ここで、そのSHA-1ハッシュ値に対して `cat-file` コマンドを実行します。
388
+
389
+ $ git cat-file -p 9585191f37f7b0fb9444f35a9bf50de191beadc2
390
+ object 1a410efbd13591db07496601ebc7a059dd55cfe9
391
+ type commit
392
+ tag v1.1
393
+ tagger Scott Chacon <schacon@gmail.com> Sat May 23 16:48:58 2009 -0700
394
+
395
+ test tag
396
+
397
+ オブジェクトエントリはあなたがタグ付けしたコミットの SHA-1 ハッシュ値をポイントすることに注意してください。またそれがコミットをポイントする必要がないことに注意してください。あらゆる Git オブジェクトに対してタグ付けをすることができます。例えば、Git のソースコードの保守では GPG 公開鍵をブロブオブジェクトとして追加して、それからタグ付けをします。Git ソースコードレポジトリで、以下のように実行することで公開鍵を閲覧することができます。
398
+
399
+ $ git cat-file blob junio-gpg-pub
400
+
401
+ Linuxカーネルのリポジトリは、さらに、非コミットポインティング(non-commit-pointing)タグオブジェクトを持っています。このタグオブジェクトは、最初のタグが作られるとソースコードのインポートの最初のツリーをポイントします。
402
+
403
+ ### リモート ###
404
+
405
+ これから見ていく三つ目の参照のタイプはリモート参照です。リモートを追加してそれにプッシュを実行すると、Git は追加したリモートにあなたが最後にプッシュした値をを格納します。そのリモートは `refs/remotes` ディレクトリにある各ブランチを参照します。例えば、`origin` と呼ばれるリモートを追加して、それを `master` ブランチにプッシュすることができます。
406
+
407
+ $ git remote add origin git@github.com:schacon/simplegit-progit.git
408
+ $ git push origin master
409
+ Counting objects: 11, done.
410
+ Compressing objects: 100% (5/5), done.
411
+ Writing objects: 100% (7/7), 716 bytes, done.
412
+ Total 7 (delta 2), reused 4 (delta 1)
413
+ To git@github.com:schacon/simplegit-progit.git
414
+ a11bef0..ca82a6d master -> master
415
+
416
+ そして、`origin` リモートに対してどの `master` ブランチが最後にサーバと通信したのかを、`refs/remotes/origin/master` ファイルをチェックすることで知ることができます。
417
+
418
+ $ cat .git/refs/remotes/origin/master
419
+ ca82a6dff817ec66f44342007202690a93763949
420
+
421
+ リモート参照は主にそれらがチェックアウトされ得ないという点において、ブランチ(`refs/heads` への参照)とは異なります。Git はそれらをブックマークとして、それらのブランチがかつてサーバー上に存在していた場所の最後に知られている状態に移し変えます。
422
+
423
+ ## パックファイル ##
424
+
425
+ Git レポジトリ test のオブジェクトデータベースに戻りましょう。この時点で、あなたは11個のオブジェクトを持っています。4つのブロブ、3つのツリー、3つのコミット、そして1つのタグです。
426
+
427
+ $ find .git/objects -type f
428
+ .git/objects/01/55eb4229851634a0f03eb265b69f5a2d56f341 # tree 2
429
+ .git/objects/1a/410efbd13591db07496601ebc7a059dd55cfe9 # commit 3
430
+ .git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a # test.txt v2
431
+ .git/objects/3c/4e9cd789d88d8d89c1073707c3585e41b0e614 # tree 3
432
+ .git/objects/83/baae61804e65cc73a7201a7252750c76066a30 # test.txt v1
433
+ .git/objects/95/85191f37f7b0fb9444f35a9bf50de191beadc2 # tag
434
+ .git/objects/ca/c0cab538b970a37ea1e769cbbde608743bc96d # commit 2
435
+ .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 # 'test content'
436
+ .git/objects/d8/329fc1cc938780ffdd9f94e0d364e0ea74f579 # tree 1
437
+ .git/objects/fa/49b077972391ad58037050f2a75f74e3671e92 # new.txt
438
+ .git/objects/fd/f4fc3344e67ab068f836878b6c4951e3b15f3d # commit 1
439
+
440
+ Git は zlib を使用してこれらのファイルのコンテンツを圧縮するため、多くを格納していません。これらすべてのファイルを集めても 925バイトにしかならないのです。Git の興味深い機能を実際に見るために、幾つか大きなコンテンツをレポジトリに追加してみましょう。前に作業したGritライブラリから `repo.rb` ファイルを追加します。これは約 12Kバイトのソースコードファイルです。
441
+
442
+ $ curl -L https://raw.github.com/mojombo/grit/master/lib/grit/repo.rb > repo.rb
443
+ $ git add repo.rb
444
+ $ git commit -m 'added repo.rb'
445
+ [master 484a592] added repo.rb
446
+ 3 files changed, 459 insertions(+), 2 deletions(-)
447
+ delete mode 100644 bak/test.txt
448
+ create mode 100644 repo.rb
449
+ rewrite test.txt (100%)
450
+
451
+ 結果のツリーを見ると、ブロブオブジェクトから取得した `repo.rb` ファイルの SHA-1ハッシュ値を見ることができます。
452
+
453
+ $ git cat-file -p master^{tree}
454
+ 100644 blob fa49b077972391ad58037050f2a75f74e3671e92 new.txt
455
+ 100644 blob 9bc1dc421dcd51b4ac296e3e5b6e2a99cf44391e repo.rb
456
+ 100644 blob e3f094f522629ae358806b17daf78246c27c007b test.txt
457
+
458
+ それから、そのオブジェクトのディスク上のサイズがどのくらいか調べることもできます。
459
+
460
+ $ du -b .git/objects/9b/c1dc421dcd51b4ac296e3e5b6e2a99cf44391e
461
+ 4102 .git/objects/9b/c1dc421dcd51b4ac296e3e5b6e2a99cf44391e
462
+
463
+ ここで、ファイルに少し変更を加えたらどうなるのか見てみましょう。
464
+
465
+ $ echo '# testing' >> repo.rb
466
+ $ git commit -am 'modified repo a bit'
467
+ [master ab1afef] modified repo a bit
468
+ 1 files changed, 1 insertions(+), 0 deletions(-)
469
+
470
+ このコミットによって作られたツリーをチェックすると、興味深いことがわかります。
471
+
472
+ $ git cat-file -p master^{tree}
473
+ 100644 blob fa49b077972391ad58037050f2a75f74e3671e92 new.txt
474
+ 100644 blob 05408d195263d853f09dca71d55116663690c27c repo.rb
475
+ 100644 blob e3f094f522629ae358806b17daf78246c27c007b test.txt
476
+
477
+ そのブロブは今では当初とは異なるブロブです。つまり、400行あるファイルの最後に1行だけ追加しただけなのに、Git はその新しいコンテンツを完全に新しいオブジェクトとして格納するのです。
478
+
479
+ $ du -b .git/objects/05/408d195263d853f09dca71d55116663690c27c
480
+ 4109 .git/objects/05/408d195263d853f09dca71d55116663690c27c
481
+
482
+ これだとディスク上にほとんど同一の 4Kバイトのオブジェクトを二つ持つことになります。もし Git がそれらのひとつは完全に格納するが二つ目のオブジェクトはもうひとつとの差分(delta)のみを格納するのだとしたら、どんなに素晴らしいことかと思いませんか?
483
+
484
+ それが可能になったのです。Git がディスク上にオブジェクトを格納する初期のフォーマットは、緩いオブジェクトフォーマット(loose object format)と呼ばれます。しかし Git はこれらのオブジェクトの中の幾つかをひとつのバイナリファイルに詰め込む(pack up)ことがあります。そのバイナリファイルは、空きスペースを保存してより効率的にするための、パックファイル(packfile)と呼ばれます。あまりにたくさんの緩いオブジェクトがそこら中にあるときや、`git gc` コマンドを手動で実行したとき、または、リモートサーバにプッシュしたときに、Git はこれを実行します。何が起こるのかを知るには、`git gc` コマンドを呼ぶことで、Git にオブジェクトを詰め込むように手動で問い合わせることができます。
485
+
486
+ $ git gc
487
+ Counting objects: 17, done.
488
+ Delta compression using 2 threads.
489
+ Compressing objects: 100% (13/13), done.
490
+ Writing objects: 100% (17/17), done.
491
+ Total 17 (delta 1), reused 10 (delta 0)
492
+
493
+ オブジェクトディレクトリの中を見ると、大半のオブジェクトは消えて、新しいファイルのペアが現れていることがわかります。
494
+
495
+ $ find .git/objects -type f
496
+ .git/objects/71/08f7ecb345ee9d0084193f147cdad4d2998293
497
+ .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
498
+ .git/objects/info/packs
499
+ .git/objects/pack/pack-7a16e4488ae40c7d2bc56ea2bd43e25212a66c45.idx
500
+ .git/objects/pack/pack-7a16e4488ae40c7d2bc56ea2bd43e25212a66c45.pack
501
+
502
+ 残りのオブジェクトは、どのコミットにもポイントされていないブロブです。このケースでは、以前に作成した "what is up, doc?" の例と "test content" のブロブの例がそれにあたります。それらに対していかなるコミットも加えられてないので、それらは遊離(dangling)しているとみなされ新しいパックファイルに詰め込まれないのです。
503
+
504
+ 他のファイルは新しいパックファイルとインデックスです。パックファイルは、ファイルシステムから取り除かれたすべてのオブジェクトのコンテンツを含んでいる単一のファイルです。インデックスは、特定のオブジェクトを速く探し出せるようにパックファイルの中にあるオフセットを含むファイルです。素晴らしいことに、`gc` を実行する前のディスク上のオブジェクトを集めると約 8Kバイトのサイズであったのに対して、新しいパックファイルは 4Kバイトになっています。オブジェクトをパックすることで、ディスクの使用量が半分になったのです。
505
+
506
+ Git はどうやってこれを行うのでしょうか? Git はオブジェクトをパックするとき、似たような名前とサイズのファイルを探し出し、ファイルのあるバージョンから次のバージョンまでの増分のみを格納します。パックファイルの中を見ることで、スペースを確保するために Git が何を行ったのかを知ることができます。`git verify-pack` という配管コマンドを使用して、何が詰め込まれたのかを知ることができます。
507
+
508
+ $ git verify-pack -v \
509
+ .git/objects/pack/pack-7a16e4488ae40c7d2bc56ea2bd43e25212a66c45.idx
510
+ 0155eb4229851634a0f03eb265b69f5a2d56f341 tree 71 76 5400
511
+ 05408d195263d853f09dca71d55116663690c27c blob 12908 3478 874
512
+ 09f01cea547666f58d6a8d809583841a7c6f0130 tree 106 107 5086
513
+ 1a410efbd13591db07496601ebc7a059dd55cfe9 commit 225 151 322
514
+ 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a blob 10 19 5381
515
+ 3c4e9cd789d88d8d89c1073707c3585e41b0e614 tree 101 105 5211
516
+ 484a59275031909e19aadb7c92262719cfcdf19a commit 226 153 169
517
+ 83baae61804e65cc73a7201a7252750c76066a30 blob 10 19 5362
518
+ 9585191f37f7b0fb9444f35a9bf50de191beadc2 tag 136 127 5476
519
+ 9bc1dc421dcd51b4ac296e3e5b6e2a99cf44391e blob 7 18 5193 1 \
520
+ 05408d195263d853f09dca71d55116663690c27c
521
+ ab1afef80fac8e34258ff41fc1b867c702daa24b commit 232 157 12
522
+ cac0cab538b970a37ea1e769cbbde608743bc96d commit 226 154 473
523
+ d8329fc1cc938780ffdd9f94e0d364e0ea74f579 tree 36 46 5316
524
+ e3f094f522629ae358806b17daf78246c27c007b blob 1486 734 4352
525
+ f8f51d7d8a1760462eca26eebafde32087499533 tree 106 107 749
526
+ fa49b077972391ad58037050f2a75f74e3671e92 blob 9 18 856
527
+ fdf4fc3344e67ab068f836878b6c4951e3b15f3d commit 177 122 627
528
+ chain length = 1: 1 object
529
+ pack-7a16e4488ae40c7d2bc56ea2bd43e25212a66c45.pack: ok
530
+
531
+ ここで、`9bc1d` というブロブを覚えてますでしょうか、これは `repo.rb` ファイルの最初のバージョンですが、このブロブは二つ目のバージョンである `05408` というブロブを参照しています。出力にある三つ目のカラムはオブジェクトの実体のサイズを示しており、`05408` の実体は 12Kバイトを要しているが、`9bc1d` の実体はたったの 7バイトしか要していないことがわかります。さらに興味深いのは、最初のバージョンは増分として格納されているのに対して、二つ目のバージョンのファイルは完全な状態で格納されているということです。これは直近のバージョンのファイルにより速くアクセスする必要があるであろうことに因ります。
532
+
533
+ これに関する本当に素晴らしいことは、いつでも再パックが可能なことです。Git は時折データベースを自動的に再パックして、常により多くのスペースを確保しようと努めます。また、あなたはいつでも `git gc` を実行することによって手動で再パックをすることができるのです。
534
+
535
+ ## 参照仕様(Refspec) ##
536
+
537
+ 本書の全体に渡って、リモートブランチからローカルの参照へのシンプルなマッピングを使用してきました。しかし、それらはもっと複雑なものです。以下のようにリモートを追加したとしましょう。
538
+
539
+ $ git remote add origin git@github.com:schacon/simplegit-progit.git
540
+
541
+ `.git/config` ファイルにセクションを追加して、リモート(`origin`)の名前、リモートレポジトリのURL、そしてフェッチするための参照仕様(refspec)を指定します。
542
+
543
+ [remote "origin"]
544
+ url = git@github.com:schacon/simplegit-progit.git
545
+ fetch = +refs/heads/*:refs/remotes/origin/*
546
+
547
+ 参照仕様はコロン(:)で分割した `<src>:<dst>` の形式で、オプションとして先頭に `+` を付けます。`<src>` はリモート側への参照に対するパターンで、`<dst>` はそれらの参照がローカル上で書かれる場所を示します。`+` の記号は Git にそれが早送り(fast-forward)でない場合でも参照を更新することを伝えます。
548
+
549
+ デフォルトのケースでは `git remote add` コマンドを実行することで自動的に書かれます。このコマンドを実行すると、Git はサーバ上の `refs/heads/` 以下にあるすべての参照をフェッチして、ローカル上の `refs/remotes/origin/` にそれらを書きます。そのため、もしもサーバ上に `master` ブランチがあると、ローカルからそのブランチのログにアクセスすることができます。
550
+
551
+ $ git log origin/master
552
+ $ git log remotes/origin/master
553
+ $ git log refs/remotes/origin/master
554
+
555
+ これらはすべて同じ意味を持ちます。なぜなら、Git はそれら各々を `refs/remotes/origin/master` に拡張するからです。
556
+
557
+ その代わりに、Git に毎回 `master` ブランチのみを引き出して、リモートサーバ上のそれ以外のすべてのブランチは引き出さないようにしたい場合は、フェッチラインを以下のように変更します。
558
+
559
+ fetch = +refs/heads/master:refs/remotes/origin/master
560
+
561
+ これはまさにリモートへの `git fetch` に対する参照仕様のデフォルトの振る舞いです。
562
+ もし何かを一度実行したければ、コマンドライン上の参照仕様を指定することもできます。
563
+ リモート上の `master` ブランチをプルして、ローカル上の `origin/mymaster` に落とすには、以下のように実行します。
564
+
565
+ $ git fetch origin master:refs/remotes/origin/mymaster
566
+
567
+ 複数の参照仕様を指定することも可能です。コマンドライン上で、幾つかのブランチをこのように引き落とす(pull down)ことができます。
568
+
569
+ $ git fetch origin master:refs/remotes/origin/mymaster \
570
+ topic:refs/remotes/origin/topic
571
+ From git@github.com:schacon/simplegit
572
+ ! [rejected] master -> origin/mymaster (non fast forward)
573
+ * [new branch] topic -> origin/topic
574
+
575
+ このケースでは、master ブランチのプルは早送りの参照ではなかったため拒否されました。`+` の記号を参照仕様の先頭に指定することで、それを上書きすることができます。
576
+
577
+ さらに設定ファイルの中のフェッチ設定に複数の参照仕様を指定することができます。もし master と実験用のブランチを常にフェッチしたいならば、二行を追加します。
578
+
579
+ [remote "origin"]
580
+ url = git@github.com:schacon/simplegit-progit.git
581
+ fetch = +refs/heads/master:refs/remotes/origin/master
582
+ fetch = +refs/heads/experiment:refs/remotes/origin/experiment
583
+
584
+ ブロブの一部をパターンに使用することはできません。これは無効となります。
585
+
586
+ fetch = +refs/heads/qa*:refs/remotes/origin/qa*
587
+
588
+ しかし、似たようなことを達成するのに名前空間を使用することができます。もし一連のブランチをプッシュしてくれる QAチームがいて、master ブランチと QAチームのブランチのみを取得したいならば、設定ファイルのセクションを以下のように使用することができます。
589
+
590
+ [remote "origin"]
591
+ url = git@github.com:schacon/simplegit-progit.git
592
+ fetch = +refs/heads/master:refs/remotes/origin/master
593
+ fetch = +refs/heads/qa/*:refs/remotes/origin/qa/*
594
+
595
+ QAチームと開発チームがローカルのブランチにプッシュして、結合チームがリモートのブランチ上でプッシュして、共同で開発するような、複雑なワークフローのプロセスであるならば、このように、名前空間によってそれらを簡単に分類することができます。
596
+
597
+ ### 参照仕様へのプッシュ ###
598
+
599
+ その方法で名前空間で分類された参照をフェッチできることは素晴らしいことです。しかし、そもそもどうやって QAチームは、彼らのブランチを `qa/` という名前空間の中で取得できるのでしょうか?
600
+ 参照仕様にプッシュすることによってそれが可能です。
601
+
602
+ QAチームが彼らの `master` ブランチをリモートサーバ上の `qa/master` にプッシュしたい場合、以下のように実行します。
603
+
604
+ $ git push origin master:refs/heads/qa/master
605
+
606
+ もし彼らが `git push origin` を実行する都度、Git に自動的にそれを行なってほしいならば、設定ファイルに `push` の値を追加することで目的が達成されます。
607
+
608
+ [remote "origin"]
609
+ url = git@github.com:schacon/simplegit-progit.git
610
+ fetch = +refs/heads/*:refs/remotes/origin/*
611
+ push = refs/heads/master:refs/heads/qa/master
612
+
613
+ 再度、これは `git push origin` の実行をローカルの `master` ブランチに、リモートの `qa/master` ブランチに、デフォルトで引き起こします。
614
+
615
+ ### 参照の削除 ###
616
+
617
+ また、リモートサーバから以下のように実行することによって、参照仕様を参照を削除する目的で使用することもできます。
618
+
619
+ $ git push origin :topic
620
+
621
+ 参照仕様は `<src>:<dst>` という形式であり、`<src>` の部分を取り除くことは、要するに何もないブランチをリモート上に作ることであり、それを削除することになるのです。
622
+
623
+ ## トランスファープロトコル ##
624
+
625
+ Git は2つのレポジトリ間を二つの主要な方法によってデータを移行することができます。ひとつは HTTPによって、もうひとつは、`file://` や `ssh://`、また、`git://` によるトランスポートに使用される、いわゆるスマートプロトコルによって。このセクションでは、これらの主要なプロトコルがどのように機能するのかを駆け足で見ていきます。
626
+
627
+ ### 無口なプロトコル ###
628
+
629
+ Git の over HTTPによる移行は、しばしば無口なプロトコル(dumb protocol)と言われます。なぜなら、トランスポートプロセスの最中に、サーバ側に関する Git 固有のコードは何も必要としないからです。フェッチプロセスは、一連の GET リクエストであり、クライアントはサーバ上の Gitレポジトリのレイアウトを推測することができます。simplegit ライブラリに対する `http-fetch` のプロセスを追ってみましょう。
630
+
631
+ $ git clone http://github.com/schacon/simplegit-progit.git
632
+
633
+ 最初にこのコマンドが行うことは `info/refs` ファイルを引き出す(pull down)ことです。このファイルは `update-server-info` コマンドによって書き込まれます。そのために、HTTPトランスポートが適切に動作するための `post-receive` フックとして、そのコマンドを有効にする必要があります。
634
+
635
+ => GET info/refs
636
+ ca82a6dff817ec66f44342007202690a93763949 refs/heads/master
637
+
638
+ いまあなたはリモート参照と SHAのハッシュのリストを持っています。
639
+ 次に、終了時に何をチェックアウトするのかを知るために、HEAD参照が何かを探します。
640
+
641
+ => GET HEAD
642
+ ref: refs/heads/master
643
+
644
+ プロセスの完了時に、`master` ブランチをチェックアウトする必要があります。この時点で、あなたは参照を辿るプロセス(the walking process)を開始する準備ができています。開始時点はあなたが `info/refs` ファイルの中に見た `ca82a6` のコミットオブジェクトなので、それをフェッチすることによって開始します。
645
+
646
+ => GET objects/ca/82a6dff817ec66f44342007202690a93763949
647
+ (179 bytes of binary data)
648
+
649
+ オブジェクトバック(object back)を取得します。それは、サーバ上の緩い形式のオブジェクトで、静的な HTTP GETリクエストを超えてそれをフェッチします。zlib-uncompress を使ってそれを解凍することができます。ヘッダを剥ぎ取り(strip off)それからコミットコンテンツを見てみます。
650
+
651
+ $ git cat-file -p ca82a6dff817ec66f44342007202690a93763949
652
+ tree cfda3bf379e4f8dba8717dee55aab78aef7f4daf
653
+ parent 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
654
+ author Scott Chacon <schacon@gmail.com> 1205815931 -0700
655
+ committer Scott Chacon <schacon@gmail.com> 1240030591 -0700
656
+
657
+ changed the version number
658
+
659
+ 次に、取り戻すためのオブジェクトがもう二つあります。それは、たった今取り戻したコミットがポイントするコンテンツのツリーである `cfda3b` と、親のコミットである `085bb3` です。
660
+
661
+ => GET objects/08/5bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
662
+ (179 bytes of data)
663
+
664
+ それは次のコミットオブジェクトを与えます。ツリーオブジェクトをつかみます。
665
+
666
+ => GET objects/cf/da3bf379e4f8dba8717dee55aab78aef7f4daf
667
+ (404 - Not Found)
668
+
669
+ おっと、どうやらそのツリーオブジェクトはサーバ上の緩い形式には存在しないようです。そのため404のレスポンスを受け取っています。これには二つの理由があります。ひとつは、オブジェクトは代替のレポジトリ内に存在し得るため、もうひとつは、このレポジトリ内のパックファイルの中に存在し得るため。Git はまずリストにあるあらゆる代替の URLをチェックします。
670
+
671
+ => GET objects/info/http-alternates
672
+ (empty file)
673
+
674
+ 代替の URLのリストと一緒にこれが戻ってくるなら、Git はそこにある緩いファイルとパックファイルをチェックします。これは、ディスク上のオブジェクトを共有するために互いにフォークし合っているプロジェクトにとって素晴らしい機構(mechanism)です。しかし、このケースではリスト化された代替は存在しないため、オブジェクトはパックファイルの中にあるに違いありません。サーバー上の何のパックファイルが利用可能かを知るには、`objects/info/packs` のファイルを取得することが必要です。そのファイルには(さらに `update-server-info` によって生成された)それらの一覧が含まれています。
675
+
676
+ => GET objects/info/packs
677
+ P pack-816a9b2334da9953e530f27bcac22082a9f5b835.pack
678
+
679
+ サーバー上にはパックファイルがひとつしかないので、あなたのオブジェクトは明らかにそこにあります。しかし念の為にインデックスファイルをチェックしてみましょう。これが便利でもあるのは、もしサーバー上にパックファイルを複数持つ場合に、どのパックファイルにあなたが必要とするオブジェクトが含まれているのかを知ることができるからです。
680
+
681
+ => GET objects/pack/pack-816a9b2334da9953e530f27bcac22082a9f5b835.idx
682
+ (4k of binary data)
683
+
684
+ パックファイルのインデックスを持っているので、あなたのオブジェクトがその中にあるのかどうかを知ることができます。なぜならインデックスにはパックファイルの中にあるオブジェクトの SHAハッシュとそれらのオブジェクトに対するオフセットがリストされているからです。あなたのオブジェクトはそこにあります。さあ、すべてのパックファイルを取得してみましょう。
685
+
686
+ => GET objects/pack/pack-816a9b2334da9953e530f27bcac22082a9f5b835.pack
687
+ (13k of binary data)
688
+
689
+ あなたはツリーオブジェクトを持っているのでコミットを辿ってみましょう。それらすべてはまた、あなたが丁度ダウンロードしたパックファイルの中にあります。そのため、もはやサーバーに対していかなるリクエストも不要です。Git は `master` ブランチの作業用コピーをチェックアウトします。そのブランチは最初にダウンロードした HEAD への参照によってポイントされています。
690
+
691
+ このプロセスのすべての出力はこのように見えます。
692
+
693
+ $ git clone http://github.com/schacon/simplegit-progit.git
694
+ Initialized empty Git repository in /private/tmp/simplegit-progit/.git/
695
+ got ca82a6dff817ec66f44342007202690a93763949
696
+ walk ca82a6dff817ec66f44342007202690a93763949
697
+ got 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
698
+ Getting alternates list for http://github.com/schacon/simplegit-progit.git
699
+ Getting pack list for http://github.com/schacon/simplegit-progit.git
700
+ Getting index for pack 816a9b2334da9953e530f27bcac22082a9f5b835
701
+ Getting pack 816a9b2334da9953e530f27bcac22082a9f5b835
702
+ which contains cfda3bf379e4f8dba8717dee55aab78aef7f4daf
703
+ walk 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
704
+ walk a11bef06a3f659402fe7563abf99ad00de2209e6
705
+
706
+ ### スマートプロトコル ###
707
+
708
+ HTTPメソッドはシンプルですが少し非効率です。スマートプロトコルを使用することはデータ移行のより一般的な手段です。これらのプロトコルは Git をよく知っているリモートエンド上にプロセスを持っています。そのリモートエンドは、ローカルのデータを読んで、クライアントが何を持っているか、または、必要としているか、そして、それに対するカスタムデータを生成するのか知ることができます。データを転送するためのプロセスが2セットあります。データをアップロードするペア、それと、ダウンロードするペアです。
709
+
710
+ #### データのアップロード ####
711
+
712
+ リモートプロセスにデータをアップロードするため、Git は `send-pack` と `receive-pack` のプロセスを使用します。`send-pack` プロセスはクライアント上で実行されリモートサイド上の `receive-pack` プロセスに接続します。
713
+
714
+ 例えば、あなたのプロジェクトで `git push origin master` を実行したとしましょう。そして `origin` は SSHプロトコルを使用する URLとして定義されているとします。Git はあなたのサーバーへの SSHによる接続を開始する `send-pack` プロセスを実行します。リモートサーバ上で以下のようなSSHの呼び出しを介してコマンドを実行しようとします。
715
+
716
+ $ ssh -x git@github.com "git-receive-pack 'schacon/simplegit-progit.git'"
717
+ 005bca82a6dff817ec66f4437202690a93763949 refs/heads/master report-status delete-refs
718
+ 003e085bb3bcb608e1e84b2432f8ecbe6306e7e7 refs/heads/topic
719
+ 0000
720
+
721
+ `git-receive-pack` コマンドは現在持っている各々の参照に対してひとつの行をすぐに返します。このケースでは、`master` ブランチとその SHAハッシュのみです。最初の行はサーバーの可能性(ここでは、`report-status` と `delete-refs`)のリストも持っています。
722
+
723
+ 各行は 4バイトの 16進数で始まっており、その残りの行がどれくらいの長さなのかを示しています。最初の行は 005b で始まっていますが、これは16進数では 91 であり、その行には 91バイトが残っていることを意味します。次の行は 003e で始まっていて、これは 62 です。そのため残りの 62バイトを読みます。次の行は 0000 であり、サーバーはその参照のリスト表示を終えたことを意味します。
724
+
725
+ サーバーの状態がわかったので、あなたの `send-pack` プロセスはサーバーが持っていないのは何のコミットかを決定します。このプッシュが更新する予定の各参照に対して、`send-pack` プロセスは `receive-pack` プロセスにその情報を伝えます。例えば、もしもあなたが `master` ブランチを更新していて、さらに、`experiment` ブランチを追加しているとき、`send-pack` のレスポンスは次のように見えるかもしれません。
726
+
727
+ 0085ca82a6dff817ec66f44342007202690a93763949 15027957951b64cf874c3557a0f3547bd83b3ff6 refs/heads/master report-status
728
+ 00670000000000000000000000000000000000000000 cdfdb42577e2506715f8cfeacdbabc092bf63e8d refs/heads/experiment
729
+ 0000
730
+
731
+ すべてが `'0'` の SHA-1ハッシュ値は以前そこには何もなかったことを意味します。それはあなたが experiment の参照を追加しているためです。もしもあなたが参照を削除していたとすると、あなたは逆にすべての `'0'` が右側にあるのを見るでしょう。
732
+
733
+ Git はあなたが古い SHA1ハッシュで更新している各々の古い参照、新しい参照、そして更新されている参照に対して行を送信します。最初の行はまたクライアントの性能(capabilities)を持っています。次に、クライアントはサーバーが未だ持ったことのないすべてのオブジェクトのパックファイルをアップロードします。最後に、サーバーは成功(あるいは失敗)の表示を返します。
734
+
735
+ 000Aunpack ok
736
+
737
+ #### データのダウンロード ####
738
+
739
+ データをダウンロードするときには、`fetch-pack` と `upload-pack` プロセスが伴います。クライアントは `fetch-pack` プロセスを開始します。何のデータが移送されてくるのかを取り決める(negotiate)ため、それはリモートサイド上の `upload-pack` プロセスに接続します。
740
+
741
+ リモートリポジトリ上の `upload-pack` プロセスを開始する異なった方法があります。あなたは `receive-pack` プロセスと同様に SSH経由で実行することができます。さらに、Git デーモンを介してプロセスを開始することもできます。そのデーモンは、デフォルトではサーバ上の 9418ポートを使用します。`fetch-pack` プロセスはデータを送信します。そのデータは接続後のデーモンに対して、以下のように見えます。
742
+
743
+ 003fgit-upload-pack schacon/simplegit-progit.git\0host=myserver.com\0
744
+
745
+ どれくらい多くのデータが続いているのかを示す 4バイトから始まります。それから、ヌルバイトに続いて実行コマンド、そして最後のヌルバイトに続いてサーバーのホスト名が来ます。Git デーモンはコマンドが実行でき、レポジトリが存在して、それがパブリックのパーミッションを持っていることをチェックします。もしすべてが素晴らしいなら、`upload-pack` プロセスを発行して、それに対するリクエストを渡します。
746
+
747
+ もし SSHを介してフェッチを行っているとき、`fetch-pack` は代わりにこのように実行します。
748
+
749
+ $ ssh -x git@github.com "git-upload-pack 'schacon/simplegit-progit.git'"
750
+
751
+ いずれケースでも、`fetch-pack` の接続のあと、`upload-pack` はこのように送り返します。
752
+
753
+ 0088ca82a6dff817ec66f44342007202690a93763949 HEAD\0multi_ack thin-pack \
754
+ side-band side-band-64k ofs-delta shallow no-progress include-tag
755
+ 003fca82a6dff817ec66f44342007202690a93763949 refs/heads/master
756
+ 003e085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 refs/heads/topic
757
+ 0000
758
+
759
+ これは `receive-pack` が返答する内容にとても似ていますが、性能は異なります。加えて、これがクローンの場合はクライアントが何をチェックアウトするのかを知るために HEAD への参照を送り返します。
760
+
761
+ この時点で、`fetch-pack` プロセスは何のオブジェクトがそれを持っているかを見ます。そして "want" とそれが求める SHA1ハッシュを送ることによって、それが必要なオブジェクトを返答します。"have" とその SHA1ハッシュで既に持っているオブジェクトすべてを送ります。このリストの最後で、それが必要とするデータのパックファイルを送信する `upload-pack` プロセスを開始するために "done" を書き込みます。
762
+
763
+ 0054want ca82a6dff817ec66f44342007202690a93763949 ofs-delta
764
+ 0032have 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
765
+ 0000
766
+ 0009done
767
+
768
+ これはトランスファープロトコルのとても基本的なケースです。より複雑なケースでは、クライアントは `multi_ack` または `side-band` の性能をサポートします。しかしこの例ではスマートプロトコルのプロセスによって使用される基本の部分を示します。
769
+
770
+ ## メインテナンスとデータリカバリ ##
771
+
772
+ 時々、幾らかのお掃除をする必要があるかもしれません。つまり、レポジトリをよりコンパクトにすること、インポートしたリポジトリをクリーンアップすること、あるいは失った作業をもとに戻すことです。このセクションではこれらのシナリオの幾つかをカバーします。
773
+
774
+ ### メインテナンス ###
775
+
776
+ Git は時々 "`auto gc`" と呼ばれるコマンドを自動的に実行します。大抵の場合、このコマンドは何もしません。もし沢山の緩いオブジェクト(パックファイルの中にないオブジェクト)があったり、あまりに多くのパックファイルがあると、Git は完全な(full-fledged)`git gc` コマンドを開始します。`gc` はガベージコレクト(garbage collect)を意味します。このコマンドは幾つものことを行います。まず、すべての緩いオブジェクトを集めてそれらをパックファイルの中に入れます。複数のパックファイルをひとつの大きなパックファイルに統合します。どのコミットからも到達が不可能なオブジェクトや数ヶ月の間何も更新がないオブジェクトを削除します。
777
+
778
+ 次のように手動で `auto gc` を実行することができます。
779
+
780
+ $ git gc --auto
781
+
782
+ 繰り返しますが、これは通常は何も行いません。約 7,000個もの緩いオブジェクトがあるか、または50以上のパックファイルがないと、Gitは実際に gc コマンドを開始しません。これらのリミットは設定ファイルの `gc.auto` と `gc.autopacklimit` によってそれぞれ変更することができます。
783
+
784
+ 他にも `gc` が行うこととしては、あなたが持つ参照を1つのファイルにまとめて入れることが挙げられます。あなたのレポジトリには、次のようなブランチとタグが含まれているとしましょう。
785
+
786
+ $ find .git/refs -type f
787
+ .git/refs/heads/experiment
788
+ .git/refs/heads/master
789
+ .git/refs/tags/v1.0
790
+ .git/refs/tags/v1.1
791
+
792
+ `git gc` を実行すると、`refs` ディレクトリにはこれらのファイルはもはや存在しなくなります。効率性のために Git はそれらを、以下のような `.git/packed-refs` という名前のファイルに移します。
793
+
794
+ $ cat .git/packed-refs
795
+ # pack-refs with: peeled
796
+ cac0cab538b970a37ea1e769cbbde608743bc96d refs/heads/experiment
797
+ ab1afef80fac8e34258ff41fc1b867c702daa24b refs/heads/master
798
+ cac0cab538b970a37ea1e769cbbde608743bc96d refs/tags/v1.0
799
+ 9585191f37f7b0fb9444f35a9bf50de191beadc2 refs/tags/v1.1
800
+ ^1a410efbd13591db07496601ebc7a059dd55cfe9
801
+
802
+ もし参照を更新すると、Git はこのファイルを編集せず、その代わりに `refs/heads` に新しいファイルを書き込みます。与えられた参照に対する適切な SHA1ハッシュを得るために、Git は `refs` ディレクトリ内でその参照をチェックし、それから予備(fallback)として `packed-refs` ファイルをチェックします。ところがもし `refs` ディレクトリ内で参照が見つけられない場合は、それはおそらく `packed-refs` ファイル内にあります。
803
+
804
+ ファイルの最後の行に注意してください。それは `^` という文字で始まっています。これはタグを意味し、そのすぐ上にあるのはアノテートタグ(annotated tag)であり、その行はアノテートタグがポイントするコミットです。
805
+
806
+ ### データリカバリ ###
807
+
808
+ Git を使っていく過程のある時点で、誤ってコミットを失ってしまうことがあるかもしれません。これが起こるのは一般的には、作業後のブランチを `force-delete` して、その後結局そのブランチが必要になったとき、あるいはブランチを `hard-reset` したために、そこから何か必要とするコミットが破棄されるときです。これが起きたとしたら、あなたはどうやってコミットを元に戻しますか?
809
+
810
+ こちらの例では、あなたの test リポジトリ内の master ブランチを古いコミットに hard-reset して、それから失ったコミットを復元します。まず、ここであなたのレポジトリがどこにあるのか調べてみましょう。
811
+
812
+ $ git log --pretty=oneline
813
+ ab1afef80fac8e34258ff41fc1b867c702daa24b modified repo a bit
814
+ 484a59275031909e19aadb7c92262719cfcdf19a added repo.rb
815
+ 1a410efbd13591db07496601ebc7a059dd55cfe9 third commit
816
+ cac0cab538b970a37ea1e769cbbde608743bc96d second commit
817
+ fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit
818
+
819
+ ここで、`master` ブランチを移動させて、中間のコミットに戻します。
820
+
821
+ $ git reset --hard 1a410efbd13591db07496601ebc7a059dd55cfe9
822
+ HEAD is now at 1a410ef third commit
823
+ $ git log --pretty=oneline
824
+ 1a410efbd13591db07496601ebc7a059dd55cfe9 third commit
825
+ cac0cab538b970a37ea1e769cbbde608743bc96d second commit
826
+ fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit
827
+
828
+ あなたはトップにある二つのコミットを手際よく失いました。それらのコミットからはどのブランチからも到達され得ません。最後のコミットの SHA1ハッシュを見つけて、それにポイントするブランチを追加する必要があります。その最後のコミットの SHA1ハッシュを見つけるコツは、記憶しておくことではないですよね?
829
+
830
+ 大抵の場合、最も手っ取り早いのは、`git reflog` と呼ばれるツールを使う方法です。あなたが作業をしているとき、変更する度に Git は HEAD が何であるかを黙って記録します。ブランチをコミットまたは変更する度に `reflog` は更新されます。`reflog` はまた `git update-ref` コマンドによっても更新されます。このチャプターの前の "Gitの参照" のセクションでカバーしましたが、これは、`ref` ファイルに SHA1ハッシュ値を直に書くのではなくコマンドを使用する別の理由です。`git reflog` を実行することで自分がどこにいたのかをいつでも知ることができます。
831
+
832
+ $ git reflog
833
+ 1a410ef HEAD@{0}: 1a410efbd13591db07496601ebc7a059dd55cfe9: updating HEAD
834
+ ab1afef HEAD@{1}: ab1afef80fac8e34258ff41fc1b867c702daa24b: updating HEAD
835
+
836
+ ここでチェックアウトした2つのコミットを見つけることができますが、ここに多くの情報はありません。もっと有効な方法で同じ情報を見るためには、`git log -g` を実行することができます。これは reflog に対する通常のログ出力を提供してくれます。
837
+
838
+ $ git log -g
839
+ commit 1a410efbd13591db07496601ebc7a059dd55cfe9
840
+ Reflog: HEAD@{0} (Scott Chacon <schacon@gmail.com>)
841
+ Reflog message: updating HEAD
842
+ Author: Scott Chacon <schacon@gmail.com>
843
+ Date: Fri May 22 18:22:37 2009 -0700
844
+
845
+ third commit
846
+
847
+ commit ab1afef80fac8e34258ff41fc1b867c702daa24b
848
+ Reflog: HEAD@{1} (Scott Chacon <schacon@gmail.com>)
849
+ Reflog message: updating HEAD
850
+ Author: Scott Chacon <schacon@gmail.com>
851
+ Date: Fri May 22 18:15:24 2009 -0700
852
+
853
+ modified repo a bit
854
+
855
+ 一番下にあるコミットがあなたが失ったコミットのようです。そのコミットの新しいブランチを作成することでそれを復元することができます。例えば、そのコミット(ab1afef)から `recover-branch` という名前でブランチを開始することができます。
856
+
857
+ $ git branch recover-branch ab1afef
858
+ $ git log --pretty=oneline recover-branch
859
+ ab1afef80fac8e34258ff41fc1b867c702daa24b modified repo a bit
860
+ 484a59275031909e19aadb7c92262719cfcdf19a added repo.rb
861
+ 1a410efbd13591db07496601ebc7a059dd55cfe9 third commit
862
+ cac0cab538b970a37ea1e769cbbde608743bc96d second commit
863
+ fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit
864
+
865
+ 素晴らしい。`master` ブランチがかつて存在した場所に、最初の二つのコミットを再び到達可能にして、あなたはいま `recover-branch` という名前のブランチを持っています。次に、損失の原因は reflog の中にはないある理由によるものだったと想定しましょう。`recover-branch` を取り除いて reflog を削除することによって、それをシミュレートすることができます。最初の二つのコミットは今いかなるものからも到達不能な状態です。
866
+
867
+ $ git branch -D recover-branch
868
+ $ rm -Rf .git/logs/
869
+
870
+ なぜなら reflog データは `.git/logs/` ディレクトリに残っているため、あなたは効率的に reflog を持たない状態です。この時点でそのコミットをどうやって復元できるのでしょうか? ひとつの方法は `git fsck` ユティリティーを使用することです。それはあなたのデータベースの完全性(integrity)をチェックします。もし `--full` オプションを付けて実行すると、別のオブジェクトによってポイントされていないすべてのオブジェクトを表示します。
871
+
872
+ $ git fsck --full
873
+ dangling blob d670460b4b4aece5915caf5c68d12f560a9fe3e4
874
+ dangling commit ab1afef80fac8e34258ff41fc1b867c702daa24b
875
+ dangling tree aea790b9a58f6cf6f2804eeac9f0abbe9631e4c9
876
+ dangling blob 7108f7ecb345ee9d0084193f147cdad4d2998293
877
+
878
+ このケースでは、あなたは浮遊コミットの後に見失ったコミットを見つけることができます。その SHA1ハッシュにポイントするブランチを加えることによって、同様にそれを復元することができます。
879
+
880
+ ### オブジェクトの除去 ###
881
+
882
+ Git には素晴らしいものたくさんあります。しかし問題が生じる可能性がある機能がひとつあります。`git clone` がすべてのファイルのすべてのバージョンを含んだプロジェクトの履歴全体をダウンロードしてしまうということです。すべてがソースコードならこれは申し分のないことです。なぜなら Git はそのデータを効率良く圧縮することに高度に最適化されているからです。しかし、もし誰かがある時点であなたのプロジェクトの履歴に1つ非常に大きなファイルを加えると、すべてのクローンは以後ずっと、その大きなファイルのダウンロードを強いられることになります。たとえ、まさに次のコミットでそれをプロジェクトから取り除かれたとしても。なぜなら常にそこに存在して、履歴から到達可能だからです。
883
+
884
+ Subversion または Perforce のレポジトリを Git に変換するときに、これは大きな問題になり得ます。なぜなら、それらのシステムではすべての履歴をダウンロードする必要がないため、非常に大きなファイルを追加してもほとんど悪影響がないからです。もし別のシステムからインポートを行った場合、あるいはあなたのレポジトリがあるべき状態よりもずっと大きくなっている場合、大きなオブジェクトを見つけて取り除く方法があります。
885
+
886
+ 注意: このテクニックはあなたのコミット履歴を壊すことになります。大きなファイルへの参照を取り除くために修正が必要な一番前のツリーからすべての下流のコミットオブジェクトに再書き込みをします。もしインポートした後そのコミット上での作業を誰かが開始する前にすぐにこれを行った場合は問題ないです。その他の場合は、あなたの新しいコミット上に作業をリベースしなければならないことをすべての関係者(contributors)に知らせる必要があります。
887
+
888
+ 実演するために、あなたの `test` リポジトリに大きなファイルを追加して、次のコミットでそれを取り除き、それを見つけて、そしてレポジトリからそれを永久に取り除きます。まず、あなたの履歴に大きなオブジェクトを追加します。
889
+
890
+ $ curl http://kernel.org/pub/software/scm/git/git-1.6.3.1.tar.bz2 > git.tbz2
891
+ $ git add git.tbz2
892
+ $ git commit -am 'added git tarball'
893
+ [master 6df7640] added git tarball
894
+ 1 files changed, 0 insertions(+), 0 deletions(-)
895
+ create mode 100644 git.tbz2
896
+
897
+ おっと、誤ってプロジェクトに非常に大きなターボールを追加してしまいました。取り除いたほうがいいでしょう。
898
+
899
+ $ git rm git.tbz2
900
+ rm 'git.tbz2'
901
+ $ git commit -m 'oops - removed large tarball'
902
+ [master da3f30d] oops - removed large tarball
903
+ 1 files changed, 0 insertions(+), 0 deletions(-)
904
+ delete mode 100644 git.tbz2
905
+
906
+ ここで、データベースに対して `gc` を実行して、どれくらい多くのスペースを使用しているのかを見てみます。
907
+
908
+ $ git gc
909
+ Counting objects: 21, done.
910
+ Delta compression using 2 threads.
911
+ Compressing objects: 100% (16/16), done.
912
+ Writing objects: 100% (21/21), done.
913
+ Total 21 (delta 3), reused 15 (delta 1)
914
+
915
+ `count-objects` コマンドを実行してどれくらい多くのスペースを使用しているのかをすぐに見ることができます。
916
+
917
+ $ git count-objects -v
918
+ count: 4
919
+ size: 16
920
+ in-pack: 21
921
+ packs: 1
922
+ size-pack: 2016
923
+ prune-packable: 0
924
+ garbage: 0
925
+
926
+ `size-pack` エントリにはパックファイルのサイズがキロバイトで記されていて、2MB使用していることがわかります。最後のコミットの前は、2KB近くを使用していました。明らかに前のコミットからファイルが取り除かれましたが、そのファイルは履歴からは取り除かれませんでした。このレポジトリを誰かがクローンする都度、彼らはこの小さなプロジェクトを取得するだけに 2MBすべてをクローンする必要があるでしょう。なぜならあなたは誤って大きなファイルを追加してしまったからです。それを取り除きましょう。
927
+
928
+ 最初にあなたはそれを見つけなければなりません。このケースでは、あなたはそれが何のファイルかを既に知っています。しかし、もし知らなかったとします。その場合どうやってあなたは多くのスペースを占めているファイルを見分けるのでしょうか? もし `git gc` を実行したとき、すべてのプロジェクトはパックファイルのなかにあります。大きなオブジェクトは別の配管コマンドを実行することで見分けることができます。それは `git verify-pack` と呼ばれ、ファイルサイズを意味する三つ目の出力フィールドに対して並び替えを行います。それを `tail` コマンドと通してパイプすることもできます。なぜなら最後の幾つかの大きなファイルのみが関心の対象となるからです。
929
+
930
+ $ git verify-pack -v .git/objects/pack/pack-3f8c0...bb.idx | sort -k 3 -n | tail -3
931
+ e3f094f522629ae358806b17daf78246c27c007b blob 1486 734 4667
932
+ 05408d195263d853f09dca71d55116663690c27c blob 12908 3478 1189
933
+ 7a9eb2fba2b1811321254ac360970fc169ba2330 blob 2056716 2056872 5401
934
+
935
+ 大きなオブジェクトは一番下の 2MBのものです。それが何のファイルなのかを知るには7章で少し使用した `rev-list` コマンドを使用します。`--objects` を `rev-list` に渡すと、すべてのコミットの SHA1ハッシュとブロブの SHA1ハッシュをそれらに関連するファイルパスと一緒にリストします。ブロブの名前を見つけるためにこれを使うことができます。
936
+
937
+ $ git rev-list --objects --all | grep 7a9eb2fb
938
+ 7a9eb2fba2b1811321254ac360970fc169ba2330 git.tbz2
939
+
940
+ ここで、あなたは過去のすべてのツリーからこのファイルを取り除く必要があります。このファイルを変更したのは何のコミットなのか知ることは簡単です。
941
+
942
+ $ git log --pretty=oneline --branches -- git.tbz2
943
+ da3f30d019005479c99eb4c3406225613985a1db oops - removed large tarball
944
+ 6df764092f3e7c8f5f94cbe08ee5cf42e92a0289 added git tarball
945
+
946
+ Git レポジトリから完全にこのファイルを取り除くためには、`6df76` から下流のすべてのコミットを書き直さなければなりません。そのためには、6章で使用した `filter-branch` を使用します。
947
+
948
+ $ git filter-branch --index-filter \
949
+ 'git rm --cached --ignore-unmatch git.tbz2' -- 6df7640^..
950
+ Rewrite 6df764092f3e7c8f5f94cbe08ee5cf42e92a0289 (1/2)rm 'git.tbz2'
951
+ Rewrite da3f30d019005479c99eb4c3406225613985a1db (2/2)
952
+ Ref 'refs/heads/master' was rewritten
953
+
954
+ `--index-filter` オプションは、ディスク上のチェックアウトされたファイルを変更するコマンドを渡すのではなく、ステージングエリアまたはインデックスを毎度変更することを除けば、6章で使用した `--tree-filter` オプションに似ています。特定のファイルに対して `rm file` を実行するように取り除くよりもむしろ、`git rm --cached` を実行して取り除かなければなりません。つまりディスクではなくインデックスからそれを取り除くのです。このようにする理由はスピードです。Git はあなたの除去作業の前にディスク上の各リビジョンをチェックアウトする必要がないので、プロセスをもっともっと速くすることができます。同様のタスクを `--tree-filter` を使用することで達成することができます。`git rm` に渡す `--ignore-unmatch` オプションは取り除こうとするパターンがそこにない場合にエラーを出力しないようにします。最後に、`filter-branch` に `6df7640` のコミットから後の履歴のみを再書き込みするように伝えます。なぜならこれが問題が生じた場所であることをあなたは知っているからです。さもなければ、最初から開始することになり不必要に長くかかるでしょう。
955
+
956
+ 履歴にはもはやそのファイルへの参照が含まれなくなります。しかしあなたの reflog と `.git/refs/original` の下で `filter-branch` を行ったときに Git が追加した新しいセットの refs には、参照はまだ含まれているので、それらを取り除いてそしてデータベースを再パックしなければなりません。再パックの前にそれら古いコミットへのポインタを持ついかなるものを取り除く必要があります。
957
+
958
+ $ rm -Rf .git/refs/original
959
+ $ rm -Rf .git/logs/
960
+ $ git gc
961
+ Counting objects: 19, done.
962
+ Delta compression using 2 threads.
963
+ Compressing objects: 100% (14/14), done.
964
+ Writing objects: 100% (19/19), done.
965
+ Total 19 (delta 3), reused 16 (delta 1)
966
+
967
+ どれくらいのスペースが節約されたかを見てみましょう。
968
+
969
+ $ git count-objects -v
970
+ count: 8
971
+ size: 2040
972
+ in-pack: 19
973
+ packs: 1
974
+ size-pack: 7
975
+ prune-packable: 0
976
+ garbage: 0
977
+
978
+ パックされたレポジトリのサイズは 7KBに下がりました。当初の 2MBよりもずっとよくなりました。サイズの値から大きなオブジェクトが未だ緩いオブジェクトの中にあることがわかります。そのため、それは無くなったわけではないのです。ですが、それはプッシュや後続するクローンで移送されることは決してありません。これは重要なことです。本当にそれを望んでいたのなら、`git prune --expire` を実行することでオブジェクトを完全に取り除くことができました。
979
+
980
+ ## 要約 ##
981
+
982
+ Git がバックグラウンドで何を行うのかについて、また、ある程度までの Git の実装の方法について、かなり良い理解が得られたことでしょう。この章では幾つかの配管コマンドを取り扱いました。このコマンドは、本書の残りで学んだ磁器コマンドよりもシンプルでもっと下位レベルのコマンドです。下位レベルで Git がどのように機能するのかを理解することは、なぜ行うのか、何を行うのかを理解して、さらに、あなた自身でツールを書いて、あなた固有のワークフローが機能するようにスクリプト利用することをより容易にします。
983
+
984
+ 連想記憶ファイル・システムとしての Git は単なるバージョン管理システム(VCS)以上のものとして簡単に使用できる、とても強力なツールです。望むらくは、あなたが Git の内側で見つけた新しい知識を使うことです。その知識は、このテクノロジーを利用するあなた自身の素晴らしいアプリケーションを実装するための知識、また、より進歩した方法で Git を使うことをより快適に感じるための知識です。