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,1228 @@
1
+ # Les tripes de Git #
2
+
3
+ Vous êtes peut-être arrivé à ce chapitre en en sautant certains ou après avoir parcouru tout le reste du livre.
4
+ Dans tous les cas, c'est ici que l'on parle du fonctionnement interne et de la mise en œuvre de Git.
5
+ Pour moi, leur apprentissage a été fondamental pour comprendre à quel point Git est utile et puissant, mais d'autres soutiennent que cela peut être source de confusion et être trop complexe pour les débutants.
6
+ J'en ai donc fait le dernier chapitre de ce livre pour que vous puissiez le lire tôt ou tard lors de votre apprentissage.
7
+ Je vous laisse le choix.
8
+
9
+ Maintenant que vous êtes ici, commençons.
10
+ Tout d'abord et même si ce n'est pas clair tout de suite, Git est fondamentalement un système de fichiers adressables par contenu (*content-addressable filesystem*) avec l'interface utilisateur d'un VCS au-dessus.
11
+ Vous en apprendrez plus à ce sujet dans quelques instants.
12
+
13
+ Aux premiers jours de Git (surtout avant la version 1.5), l'interface utilisateur était beaucoup plus complexe, car elle était centrée sur le système de fichier plutôt que sur l'aspect VCS.
14
+ Ces dernières années, l'interface utilisateur a été peaufinée jusqu'à devenir aussi cohérente et facile à utiliser que n'importe quel autre système.
15
+ Pour beaucoup, l'image du Git des débuts avec son interface utilisateur complexe et difficile à apprendre est toujours présente.
16
+ La couche système de fichiers adressables par contenu est vraiment géniale et j'en parlerai dans ce chapitre.
17
+ Ensuite, vous apprendrez les mécanismes de transport/transmission/communication ainsi que les tâches que vous serez amené à accomplir pour maintenir un dépôt.
18
+
19
+ ## Plomberie et porcelaine ##
20
+
21
+ Ce livre couvre l'utilisation de Git avec une trentaine de verbes comme `checkout`, `branch`, `remote`...
22
+ Mais, puisque Git était initialement une boîte à outils (*toolkit*) pour VCS, plutôt qu'un VCS complet et convivial, il dispose de tout un ensemble d'actions pour les tâches bas niveau qui étaient conçues pour être liées dans le style UNIX ou appelées depuis des scripts.
23
+ Ces commandes sont dites commandes de « plomberie » (*plumbing*) et les autres, plus conviviales sont appelées « porcelaines » (*porcelain*).
24
+
25
+ Les huit premiers chapitres du livre concernent presque exclusivement les commandes porcelaine.
26
+ Par contre, dans ce chapitre, vous serez principalement confronté aux commandes de plomberie bas niveau, car elles vous donnent accès au fonctionnement interne de Git et aident à montrer comment et pourquoi Git fonctionne comme il le fait.
27
+ Ces commandes ne sont pas faites pour être utilisées à la main sur une ligne de commande, mais sont plutôt utilisées comme briques de base pour écrire de nouveaux outils et scripts personnalisés.
28
+
29
+ Quand vous exécutez `git init` dans un nouveau répertoire ou un répertoire existant, Git crée un répertoire `.git` qui contient presque tout ce que Git stocke et manipule.
30
+ Si vous voulez sauvegarder ou cloner votre dépôt, copier ce seul répertoire suffirait presque.
31
+ Ce chapitre traite principalement de ce que contient ce répertoire.
32
+ Voici à quoi il ressemble :
33
+
34
+ $ ls
35
+ HEAD
36
+ branches/
37
+ config
38
+ description
39
+ hooks/
40
+ index
41
+ info/
42
+ objects/
43
+ refs/
44
+
45
+ Vous y verrez sans doute d'autres fichiers, mais ceci est un dépôt qui vient d'être crée avec `git init` et c'est ce que vous verrez par défaut.
46
+ Le répertoire `branches` n'est pas utilisé par les versions récentes de Git et le fichier `description` est utilisé uniquement par le programme GitWeb, il ne faut donc pas s'en soucier.
47
+ Le fichier `config` contient les options de configuration spécifiques à votre projet et le répertoire `info` contient un fichier listant les motifs que vous souhaitez ignorer et que vous ne voulez pas mettre dans un fichier `.gitignore`.
48
+ Le répertoire `hooks` contient les scripts de procédures automatiques côté client ou serveur, ils sont décrits en détail dans le chapitre 7.
49
+
50
+ Il reste quatre éléments importants : les fichiers `HEAD` et `index`, ainsi que les répertoires `objects` et `refs`.
51
+ Ce sont les composants principaux d'un dépôt Git.
52
+ Le répertoire `objects` stocke le contenu de votre base de données, le répertoire `refs` stocke les pointeurs vers les objets *commit* de ces données (branches), le fichier `HEAD` pointe sur la branche qui est en cours dans votre répertoire de travail (*checkout*) et le fichier `index` est l'endroit où Git stocke les informations sur la zone d'attente.
53
+ Vous allez maintenant plonger en détail dans chacune de ces sections et voir comment Git fonctionne.
54
+
55
+ ## Les objets Git ##
56
+
57
+ Git est un système de fichier adressables par contenu.
58
+ Super !
59
+ Mais qu'est-ce que ça veut dire ?
60
+ Ça veut dire que le cœur de Git est une simple base de paires clé/valeur.
61
+ Vous pouvez y insérer n'importe quelle sorte de données et il vous retournera une clé que vous pourrez utiliser à n'importe quel moment pour récupérer ces données.
62
+ Pour illustrer cela, vous pouvez utiliser la commande de plomberie `hash-object`, qui prend des données, les stocke dans votre répertoire `.git`, puis retourne la clé sous laquelle les données sont stockées.
63
+ Tout d'abord, créez un nouveau dépôt Git et vérifiez que rien ne se trouve dans le répertoire `object` :
64
+
65
+ $ mkdir test
66
+ $ cd test
67
+ $ git init
68
+ Initialized empty Git repository in /tmp/test/.git/
69
+ $ find .git/objects
70
+ .git/objects
71
+ .git/objects/info
72
+ .git/objects/pack
73
+ $ find .git/objects -type f
74
+ $
75
+
76
+ Git a initialisé le répertoire `objects` et y a créé les sous-répertoires `pack` et `info`, mais ils ne contiennent pas de fichier régulier.
77
+ Maintenant, stockez du texte dans votre base de données Git :
78
+
79
+ $ echo 'test content' | git hash-object -w --stdin
80
+ d670460b4b4aece5915caf5c68d12f560a9fe3e4
81
+
82
+ L'option `-w` spécifie à `hash-object` de stocker l'objet, sinon la commande répondrait seulement quelle serait la clé.
83
+ `--stdin` spécifie à la commande de lire le contenu depuis l'entrée standard, sinon `hash-object` s'attend à trouver un chemin vers un fichier.
84
+ La sortie de la commande est une empreinte de 40 caractères.
85
+ C'est l'empreinte SHA-1 : une somme de contrôle du contenu du fichier que vous stockez plus un en-tête, dont les détails sont un peu plus bas.
86
+ Voyez maintenant comment Git a stocké vos données :
87
+
88
+ $ find .git/objects -type f
89
+ .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
90
+
91
+ Vous pouvez voir un fichier dans le répertoire `objects`.
92
+ C'est comme cela que Git stocke initialement du contenu : un fichier par contenu, nommé d'après la somme de contrôle SHA-1 du contenu et de son en-tête.
93
+ Le sous-répertoire est nommé d'après les 2 premiers caractères de l'empreinte et le fichier d'après les 38 caractères restants.
94
+
95
+ Vous pouvez récupérer le contenu avec la commande `cat-file`.
96
+ Cette commande est un peu le couteau suisse pour l'inspection des objets Git.
97
+ Utiliser l'option `-p` avec `cat-file` vous permet de connaître le type de contenu et de l'afficher clairement :
98
+
99
+ $ git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4
100
+ test content
101
+
102
+ Vous pouvez maintenant ajouter du contenu à Git et le récupérer.
103
+ Vous pouvez aussi faire ceci avec des fichiers.
104
+ Par exemple, vous pouvez mettre en œuvre une gestion de version simple d'un fichier.
105
+ D'abord, créez un nouveau fichier et enregistrez son contenu dans la base de données :
106
+
107
+ $ echo 'version 1' > test.txt
108
+ $ git hash-object -w test.txt
109
+ 83baae61804e65cc73a7201a7252750c76066a30
110
+
111
+ Puis, modifiez le contenu du fichier et enregistrez-le à nouveau :
112
+
113
+ $ echo 'version 2' > test.txt
114
+ $ git hash-object -w test.txt
115
+ 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a
116
+
117
+ Votre base de données contient les 2 versions du fichier, ainsi que le premier contenu que vous avez stocké ici :
118
+
119
+ $ find .git/objects -type f
120
+ .git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a
121
+ .git/objects/83/baae61804e65cc73a7201a7252750c76066a30
122
+ .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
123
+
124
+ Vous pouvez restaurer le fichier à sa première version :
125
+
126
+ $ git cat-file -p 83baae61804e65cc73a7201a7252750c76066a30 > test.txt
127
+ $ cat test.txt
128
+ version 1
129
+
130
+ ou à sa seconde version :
131
+
132
+ $ git cat-file -p 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a > test.txt
133
+ $ cat test.txt
134
+ version 2
135
+
136
+ Se souvenir de la clé SHA-1 de chaque version de votre fichier n'est pas pratique.
137
+ En plus, vous ne stockez pas le fichier lui-même, mais seulement son contenu, dans votre base.
138
+ Ce type d'objet est appelé un blob (*Binary Large OBject*, soit en français : Gros Objet Binaire).
139
+ Git peut vous donner le type d'objet de n'importe quel objet Git, étant donné sa clé SHA-1, avec `cat-file -t` :
140
+
141
+ $ git cat-file -t 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a
142
+ blob
143
+
144
+ ### Objets arbre ###
145
+
146
+ Le prochain type que vous allez étudier est l'objet arbre (*tree*) qui résout le problème de stockage d'un groupe de fichiers.
147
+ Git stocke du contenu de la même manière, mais plus simplement, qu'un système de fichier UNIX.
148
+ Tout le contenu est stocké comme des objets de type arbre ou blob : un arbre correspondant à un répertoire UNIX et un blob correspond à peu près à un i-nœud ou au contenu d'un fichier.
149
+ Un unique arbre contient une ou plusieurs entrées de type arbre, chacune incluant un pointeur SHA-1 vers un blob, un sous-arbre (*sub-tree*), ainsi que les droits d'accès (*mode*), le type et le nom de fichier.
150
+ L'arbre le plus récent du projet simplegit pourrait ressembler, par exemple à ceci :
151
+
152
+ $ git cat-file -p master^{tree}
153
+ 100644 blob a906cb2a4a904a152e80877d4088654daad0c859 README
154
+ 100644 blob 8f94139338f9404f26296befa88755fc2598c289 Rakefile
155
+ 040000 tree 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0 lib
156
+
157
+ La syntaxe `master^{tree}` signifie l'objet arbre qui est pointé par le dernier *commit* de la branche `master`.
158
+ Remarquez que le sous-répertoire `lib` n'est pas un blob, mais un pointeur vers un autre arbre :
159
+
160
+ $ git cat-file -p 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0
161
+ 100644 blob 47c6340d6459e05787f644c2447d2595f5d3a54b simplegit.rb
162
+
163
+ Conceptuellement, les données que Git stocke ressemblent à la figure 9-1.
164
+
165
+ Insert 18333fig0901.png
166
+ Figure 9-1. Une version simple du modèle de données Git.
167
+
168
+ Vous pouvez créer votre propre arbre.
169
+ Git crée habituellement un arbre à partir de l'état de la zone d'attente ou de l'index.
170
+ Pour créer un objet arbre, vous devez donc d'abord mettre en place un index en mettant quelques fichiers en attente.
171
+ Pour créer un index contenant une entrée, la première version de votre fichier `test.txt` par exemple, utilisons la commande de plomberie `update-index`.
172
+ Vous pouvez utiliser cette commande pour ajouter artificiellement une version plus ancienne à une nouvelle zone d'attente.
173
+ Vous devez utiliser les options `--add` car le fichier n'existe pas encore dans votre zone d'attente (vous n'avez même pas encore mis en place une zone d'attente) et `--cacheinfo` car le fichier que vous ajoutez n'est pas dans votre répertoire, mais dans la base de données.
174
+ Vous pouvez ensuite préciser le mode, SHA-1 et le nom de fichier :
175
+
176
+ $ git update-index --add --cacheinfo 100644 \
177
+ 83baae61804e65cc73a7201a7252750c76066a30 test.txt
178
+
179
+ Dans ce cas, vous précisez le mode `100644`, qui signifie que c'est un fichier normal.
180
+ Les alternatives sont `100755`, qui signifie que c'est un exécutable et `120000`, qui précise que c'est un lien symbolique.
181
+ Le concept de « mode » a été repris des mode UNIX, mais est beaucoup moins flexible : ces trois modes sont les seuls valides pour Git, pour les fichiers (blobs) (bien que d'autres modes soient utilisés pour les répertoires et sous-modules).
182
+
183
+ Vous pouvez maintenant utiliser la commande `write-tree` pour écrire la zone d'attente dans un objet arbre.
184
+ L'option' `-w` est inutile (appeler `write-tree` crée automatiquement un objet arbre à partir de l'état de l'index si cet arbre n'existe pas) :
185
+
186
+ $ git write-tree
187
+ d8329fc1cc938780ffdd9f94e0d364e0ea74f579
188
+ $ git cat-file -p d8329fc1cc938780ffdd9f94e0d364e0ea74f579
189
+ 100644 blob 83baae61804e65cc73a7201a7252750c76066a30 test.txt
190
+
191
+ Vous pouvez également vérifier que c'est un objet arbre :
192
+
193
+ $ git cat-file -t d8329fc1cc938780ffdd9f94e0d364e0ea74f579
194
+ tree
195
+
196
+ Vous allez créer maintenant un nouvel arbre avec la seconde version de `test.txt` et un nouveau fichier :
197
+
198
+ $ echo 'new file' > new.txt
199
+ $ git update-index test.txt
200
+ $ git update-index --add new.txt
201
+
202
+ Votre zone d'attente contient maintenant la nouvelle version de `test.txt` ainsi qu'un nouveau fichier `new.txt`.
203
+ Enregistrez cet arbre (c'est-à-dire enregistrez l'état de la zone d'attente ou de l'index dans un objet arbre) :
204
+
205
+ $ git write-tree
206
+ 0155eb4229851634a0f03eb265b69f5a2d56f341
207
+ $ git cat-file -p 0155eb4229851634a0f03eb265b69f5a2d56f341
208
+ 100644 blob fa49b077972391ad58037050f2a75f74e3671e92 new.txt
209
+ 100644 blob 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a test.txt
210
+
211
+ Remarquez que cet arbre contient des entrées pour les deux fichiers et que l'empreinte SHA de `test.txt` est l'empreinte de la « version 2 » de tout à l'heure (`1f7a7a`).
212
+ Pour le plaisir, ajoutez le premier arbre à celui-ci, en tant que sous-répertoire.
213
+ Vous pouvez maintenant récupérer un arbre de votre zone d'attente en exécutant `read-tree`.
214
+ Dans ce cas, vous pouvez récupérer un arbre existant dans votre zone d'attente comme étant un sous-arbre en utilisant l'option `--prefix` de `read-tree` :
215
+
216
+ $ git read-tree --prefix=bak d8329fc1cc938780ffdd9f94e0d364e0ea74f579
217
+ $ git write-tree
218
+ 3c4e9cd789d88d8d89c1073707c3585e41b0e614
219
+ $ git cat-file -p 3c4e9cd789d88d8d89c1073707c3585e41b0e614
220
+ 040000 tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579 bak
221
+ 100644 blob fa49b077972391ad58037050f2a75f74e3671e92 new.txt
222
+ 100644 blob 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a test.txt
223
+
224
+ Si vous créez un répertoire de travail à partir du nouvel arbre que vous venez d'enregistrer, vous aurez deux fichiers à la racine du répertoire de travail, ainsi qu'un sous-répertoire appelé `bak` qui contient la première version du fichier `test.txt`.
225
+ Vous pouvez vous représenter les données que Git utilise pour ces structures comme sur la figure 9-2.
226
+
227
+ Insert 18333fig0902.png
228
+ Figure 9-2. Structure du contenu de vos données Git actuelles.
229
+
230
+ ### Objets *Commit* ###
231
+
232
+ Vous avez trois arbres qui définissent différents instantanés du projet que vous suivez, mais certains problèmes persistent : vous devez vous souvenir des valeurs des trois empreintes SHA-1 pour accéder aux instantanés.
233
+ Vous n'avez pas non plus d'information sur qui a enregistré les instantanés, quand et pourquoi.
234
+ Ce sont les informations élémentaires qu'un objet *commit* stocke pour vous.
235
+
236
+ Pour créer un objet *commit*, il suffit d'exécuter `commit-tree`, de préciser l'empreinte SHA-1 et quel objet *commit*, s'il y en a, le précède directement.
237
+ Commencez avec le premier arbre que vous avez créé :
238
+
239
+ $ echo 'first commit' | git commit-tree d8329f
240
+ fdf4fc3344e67ab068f836878b6c4951e3b15f3d
241
+
242
+ Vous pouvez voir votre nouvel objet *commit* avec `cat-file` :
243
+
244
+ $ git cat-file -p fdf4fc3
245
+ tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579
246
+ author Scott Chacon <schacon@gmail.com> 1243040974 -0700
247
+ committer Scott Chacon <schacon@gmail.com> 1243040974 -0700
248
+
249
+ first commit
250
+
251
+ Le format d'un *commit* est simple : il contient l'arbre racine de l'instantané du projet à ce moment, les informations sur l'auteur et le validateur qui sont extraites des variables de configuration `user.name` et `user.email` accompagnées d'un horodatage, une ligne vide et le message de validation.
252
+
253
+ Ensuite, vous enregistrez les deux autres objets *commit*, chacun référençant le *commit* dont il est issu :
254
+
255
+ $ echo 'second commit' | git commit-tree 0155eb -p fdf4fc3
256
+ cac0cab538b970a37ea1e769cbbde608743bc96d
257
+ $ echo 'third commit' | git commit-tree 3c4e9c -p cac0cab
258
+ 1a410efbd13591db07496601ebc7a059dd55cfe9
259
+
260
+ Chacun des trois objets *commit* pointe sur un arbre de l'instantané que vous avez créé.
261
+ Curieusement, vous disposez maintenant d'un historique Git complet que vous pouvez visualiser avec la commande `git log`, si vous la lancez sur le SHA-1 du dernier *commit* :
262
+
263
+ $ git log --stat 1a410e
264
+ commit 1a410efbd13591db07496601ebc7a059dd55cfe9
265
+ Author: Scott Chacon <schacon@gmail.com>
266
+ Date: Fri May 22 18:15:24 2009 -0700
267
+
268
+ third commit
269
+
270
+ bak/test.txt | 1 +
271
+ 1 files changed, 1 insertions(+), 0 deletions(-)
272
+
273
+ commit cac0cab538b970a37ea1e769cbbde608743bc96d
274
+ Author: Scott Chacon <schacon@gmail.com>
275
+ Date: Fri May 22 18:14:29 2009 -0700
276
+
277
+ second commit
278
+
279
+ new.txt | 1 +
280
+ test.txt | 2 +-
281
+ 2 files changed, 2 insertions(+), 1 deletions(-)
282
+
283
+ commit fdf4fc3344e67ab068f836878b6c4951e3b15f3d
284
+ Author: Scott Chacon <schacon@gmail.com>
285
+ Date: Fri May 22 18:09:34 2009 -0700
286
+
287
+ first commit
288
+
289
+ test.txt | 1 +
290
+ 1 files changed, 1 insertions(+), 0 deletions(-)
291
+
292
+ Fantastique.
293
+ Vous venez d'effectuer les opérations bas niveau pour construire un historique Git sans avoir utilisé aucune des commandes haut niveau.
294
+ C'est l'essence de ce que fait Git quand vous exécutez les commandes `git add` et `git commit`.
295
+ Il stocke les blobs correspondant aux fichiers modifiés, met à jour l'index, écrit les arbres et ajoute les objets *commit* qui référencent les arbres racines venant juste avant eux.
296
+ Ces trois objets principaux (le blob, l'arbre et le *commit*) sont initialement stockés dans des fichiers séparés du répertoire `.git/objects`.
297
+ Voici tous les objets contenus dans le répertoire exemple, commentés d'après leur contenu :
298
+
299
+ $ find .git/objects -type f
300
+ .git/objects/01/55eb4229851634a0f03eb265b69f5a2d56f341 # tree 2
301
+ .git/objects/1a/410efbd13591db07496601ebc7a059dd55cfe9 # commit 3
302
+ .git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a # test.txt v2
303
+ .git/objects/3c/4e9cd789d88d8d89c1073707c3585e41b0e614 # tree 3
304
+ .git/objects/83/baae61804e65cc73a7201a7252750c76066a30 # test.txt v1
305
+ .git/objects/ca/c0cab538b970a37ea1e769cbbde608743bc96d # commit 2
306
+ .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 # 'test content'
307
+ .git/objects/d8/329fc1cc938780ffdd9f94e0d364e0ea74f579 # tree 1
308
+ .git/objects/fa/49b077972391ad58037050f2a75f74e3671e92 # new.txt
309
+ .git/objects/fd/f4fc3344e67ab068f836878b6c4951e3b15f3d # commit 1
310
+
311
+ Si vous suivez les pointeurs internes de ces objets, vous obtenez un graphe comme celui de la figure 9-3.
312
+
313
+ Insert 18333fig0903.png
314
+ Figure 9-3. Tous les objets de votre répertoire Git.
315
+
316
+ ### Stockage des objets ###
317
+
318
+ On a parlé plus tôt de l'en-tête présent avec le contenu.
319
+ Prenons un moment pour étudier la façon dont Git stocke les objets.
320
+ On verra comment stocker interactivement un objet Blob (ici, la chaîne « what is up, doc? ») avec le langage Ruby.
321
+ Vous pouvez démarrer Ruby en mode interactif avec la commande `irb` :
322
+
323
+ $ irb
324
+ >> content = "what is up, doc?"
325
+ => "what is up, doc?"
326
+
327
+ Git construit un en-tête qui commence avec le type de l'objet, ici un blob.
328
+ Ensuite, il ajoute un espace suivi de taille du contenu et enfin un octet nul :
329
+
330
+ >> header = "blob #{content.length}\0"
331
+ => "blob 16\000"
332
+
333
+ Git concatène l'en-tête avec le contenu original et calcule l'empreinte SHA-1 du nouveau contenu.
334
+ En Ruby, vous pouvez calculer l'empreinte SHA-1 d'une chaîne, en incluant la bibliothèque « digest/SHA-1 » via la commande `require`, puis en appelant `Digest::SHA1.hexdigest()` sur la chaîne :
335
+
336
+ >> store = header + content
337
+ => "blob 16\000what is up, doc?"
338
+ >> require 'digest/sha1'
339
+ => true
340
+ >> sha1 = Digest::SHA1.hexdigest(store)
341
+ => "bd9dbf5aae1a3862dd1526723246b20206e5fc37"
342
+
343
+ Git compresse le nouveau contenu avec zlib, ce que vous pouvez faire avec la bibliothèque zlib de Ruby.
344
+ Vous devez inclure la bibliothèque et exécuter `Zlib::Deflate.deflate()` sur le contenu :
345
+
346
+ >> require 'zlib'
347
+ => true
348
+ >> zlib_content = Zlib::Deflate.deflate(store)
349
+ => "x\234K\312\311OR04c(\317H,Q\310,V(-\320QH\311O\266\a\000_\034\a\235"
350
+
351
+ Finalement, vous enregistrerez le contenu compressé dans un objet sur le disque.
352
+ Vous déterminerez le chemin de l'objet que vous voulez enregistrer (les deux premiers caractères de l'empreinte SHA-1 formeront le nom du sous-répertoire et les 38 derniers formeront le nom du fichier dans ce répertoire).
353
+ En Ruby, on peut utiliser la fonction `FileUtils.mkdir_p()` pour créer un sous-répertoire s'il n'existe pas.
354
+ Ensuite, ouvrez le fichier avec `File.open()` et enregistrez le contenu compressé en appelant la fonction `write()` sur la référence du fichier :
355
+
356
+ >> path = '.git/objects/' + sha1[0,2] + '/' + sha1[2,38]
357
+ => ".git/objects/bd/9dbf5aae1a3862dd1526723246b20206e5fc37"
358
+ >> require 'fileutils'
359
+ => true
360
+ >> FileUtils.mkdir_p(File.dirname(path))
361
+ => ".git/objects/bd"
362
+ >> File.open(path, 'w') { |f| f.write zlib_content }
363
+ => 32
364
+
365
+ C'est tout !
366
+ Vous venez juste de créer un objet Blob valide.
367
+ Tout les objets Git sont stockés de la même façon, mais avec des types différents : l'en-tête commencera par « commit » ou « tree » au lieu de la chaîne « blob ».
368
+ Bien que le contenu d'un blob puisse être presque n'importe quoi, le contenu d'un *commit* ou d'un arbre est formaté d'une façon particulière.
369
+
370
+ ## Références Git ##
371
+
372
+ On peut exécuter quelque chose comme `git log 1a410e` pour visualiser tout l'historique, mais il faut se souvenir que `1a410e` est le dernier *commit* afin de parcourir l'historique et trouver tous ces objets.
373
+ Vous avez besoin d'un fichier ayant un nom simple qui contient l'empreinte SHA-1 afin d'utiliser ce pointeur plutôt que l'empreinte SHA-1 elle-même.
374
+
375
+ Git appelle ces pointeurs des « références », ou « refs ».
376
+ On trouve les fichiers contenant des empreintes SHA-1 dans le répertoire `git/refs`.
377
+ Dans le projet actuel, ce répertoire ne contient aucun fichier, mais possède une structure simple :
378
+
379
+ $ find .git/refs
380
+ .git/refs
381
+ .git/refs/heads
382
+ .git/refs/tags
383
+ $ find .git/refs -type f
384
+ $
385
+
386
+ Pour créer une nouvelle référence servant à se souvenir du dernier *commit*, vous pouvez simplement faire ceci :
387
+
388
+ $ echo "1a410efbd13591db07496601ebc7a059dd55cfe9" > .git/refs/heads/master
389
+
390
+ Vous pouvez maintenant utiliser la référence principale que vous venez de créer à la place de l'empreinte SHA-1 dans vos commandes Git :
391
+
392
+ $ git log --pretty=oneline master
393
+ 1a410efbd13591db07496601ebc7a059dd55cfe9 third commit
394
+ cac0cab538b970a37ea1e769cbbde608743bc96d second commit
395
+ fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit
396
+
397
+ Il n'est pas conseillé d'éditer directement les fichiers des références.
398
+ Git propose une manière sûre de mettre à jour une référence, c'est la commande `update-ref` :
399
+
400
+ $ git update-ref refs/heads/master 1a410efbd13591db07496601ebc7a059dd55cfe9
401
+
402
+ C'est simplement ce qu'est une branche dans Git : un simple pointeur ou référence sur le dernier état d'une suite de travaux.
403
+ Pour créer une branche à partir du deuxième *commit*, vous pouvez faire ceci :
404
+
405
+ $ git update-ref refs/heads/test cac0ca
406
+
407
+ Cette branche contiendra seulement le travail effectué jusqu'à ce *commit* :
408
+
409
+ $ git log --pretty=oneline test
410
+ cac0cab538b970a37ea1e769cbbde608743bc96d second commit
411
+ fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit
412
+
413
+ La base de donnée Git ressemble maintenant à quelque chose comme la figure 9-4.
414
+
415
+ Insert 18333fig0904.png
416
+ Figure 9-4. Le répertoire d'objets de Git y compris la référence au dernier état de la branche.
417
+
418
+ Quand on exécute un commande comme `git branch (nomdebranche)`, Git exécute simplement la commande `update-ref` pour ajouter l'empreinte SHA-1 du dernier *commit* dans la référence que l'on veut créer.
419
+
420
+ ### La branche HEAD ###
421
+
422
+ On peut se poser la question : « Comment Git peut avoir connaissance de l'empreinte SHA-1 du dernier *commit* quand on exécute `git branch (branchname)` ? »
423
+ La réponse est dans le fichier HEAD (qui veut dire tête en français, soit, ici, l'état courant).
424
+ Le fichier HEAD est une référence symbolique à la branche courante.
425
+ Par référence symbolique, j'entends que contrairement à une référence normale, elle ne contient pas une empreinte SHA-1, mais plutôt un pointeur vers une autre référence.
426
+ Si vous regardez ce fichier, vous devriez voir quelque chose comme ceci :
427
+
428
+ $ cat .git/HEAD
429
+ ref: refs/heads/master
430
+
431
+ Si vous exécutez `git checkout test`, Git met à jour ce fichier, qui ressemblera à ceci :
432
+
433
+ $ cat .git/HEAD
434
+ ref: refs/heads/test
435
+
436
+ Quand vous exécutez `git commit`, il crée l'objet *commit* en spécifiant le parent du *commit* comme étant l'empreinte SHA-1 pointé par la référence du fichier HEAD :
437
+
438
+ On peut éditer manuellement ce fichier, mais encore une fois, il existe une commande supplémentaire pour le faire : `symbolic-ref`.
439
+ Vous pouvez lire le contenu de votre fichier HEAD avec cette commande :
440
+
441
+ $ git symbolic-ref HEAD
442
+ refs/heads/master
443
+
444
+ Vous pouvez aussi initialiser la valeur de HEAD :
445
+
446
+ $ git symbolic-ref HEAD refs/heads/test
447
+ $ cat .git/HEAD
448
+ ref: refs/heads/test
449
+
450
+ Vous ne pouvez pas initialiser une référence symbolique à une valeur non contenu dans refs :
451
+
452
+ $ git symbolic-ref HEAD test
453
+ fatal: Refusing to point HEAD outside of refs/
454
+
455
+ ### Étiquettes ###
456
+
457
+ Nous venons de parcourir les trois types d'objets utilisés par Git, mais il existe un quatrième objet.
458
+ L'objet étiquette (*tag* en anglais) ressemble beaucoup à un objet *commit*.
459
+ Il contient un étiqueteur, une date, un message et un pointeur.
460
+ La principale différence est que l'étiquette pointe vers un *commit* plutôt qu'un arbre.
461
+ C'est comme une référence à une branche, mais elle ne bouge jamais : elle pointe toujours vers le même *commit*, lui donnant un nom plus sympathique.
462
+
463
+ Comme présenté au chapitre 2, il existe deux types d'étiquettes : annotée et légère.
464
+ Vous pouvez créer une étiquette légère comme ceci :
465
+
466
+ $ git update-ref refs/tags/v1.0 cac0cab538b970a37ea1e769cbbde608743bc96d
467
+
468
+ C'est tout ce qu'est une étiquette légère : une branche qui n'est jamais modifiée.
469
+ Une étiquette annotée est plus complexe.
470
+ Quand on crée une étiquette annotée, Git crée un objet étiquette, puis enregistre une référence qui pointe vers lui plutôt que directement vers le *commit*.
471
+ Vous pouvez voir ceci en créant une étiquette annotée (`-a` spécifie que c'est une étiquette annotée) :
472
+
473
+ $ git tag -a v1.1 1a410efbd13591db07496601ebc7a059dd55cfe9 –m 'test tag'
474
+
475
+ Voici l'empreinte SHA-1 de l'objet créé :
476
+
477
+ $ cat .git/refs/tags/v1.1
478
+ 9585191f37f7b0fb9444f35a9bf50de191beadc2
479
+
480
+ Exécutez ensuite, la commande `cat-file` sur l'empreinte SHA-1 :
481
+
482
+ $ git cat-file -p 9585191f37f7b0fb9444f35a9bf50de191beadc2
483
+ object 1a410efbd13591db07496601ebc7a059dd55cfe9
484
+ type commit
485
+ tag v1.1
486
+ tagger Scott Chacon <schacon@gmail.com> Sat May 23 16:48:58 2009 -0700
487
+
488
+ test tag
489
+
490
+ Remarquez que le contenu de l'objet pointe vers l'empreinte SHA-1 du *commit* que vous avez étiqueté.
491
+ Remarquez qu'il n'est pas nécessaire qu'il pointe vers un *commit*.
492
+ On peut étiqueter n'importe quel objet.
493
+ Par exemple, dans le code source de Git, le mainteneur a ajouté ses clés GPG dans un blob et l'a étiqueté.
494
+ Vous pouvez voir la clé publique en exécutant :
495
+
496
+ $ git cat-file blob junio-gpg-pub
497
+
498
+ dans le code source de Git.
499
+ Le noyau Linux contient aussi une étiquette ne pointant pas vers un *commit* : la première étiquette créée pointe vers l'arbre initial lors de l'importation du code source.
500
+
501
+ ### Références distantes ###
502
+
503
+ Le troisième type de références que l'on étudiera sont les références distantes (*remotes*).
504
+ Si l'on ajoute une référence distante et que l'on pousse des objets vers elle, Git stocke la valeur que vous avez poussée en dernière vers cette référence pour chaque branche dans le répertoire `refs/remotes`.
505
+ Vous pouvez par exemple, ajouter une référence distante nommée `origin` et y pousser votre branche `master` :
506
+
507
+ $ git remote add origin git@github.com:schacon/simplegit-progit.git
508
+ $ git push origin master
509
+ Counting objects: 11, done.
510
+ Compressing objects: 100% (5/5), done.
511
+ Writing objects: 100% (7/7), 716 bytes, done.
512
+ Total 7 (delta 2), reused 4 (delta 1)
513
+ To git@github.com:schacon/simplegit-progit.git
514
+ a11bef0..ca82a6d master -> master
515
+
516
+ Ensuite, vous pouvez voir l'état de la branche `master` dans la référence distante `origin` la dernière fois que vous avez communiqué avec le serveur en regardant le fichier `refs/remotes/origin/master` :
517
+
518
+ $ cat .git/refs/remotes/origin/master
519
+ ca82a6dff817ec66f44342007202690a93763949
520
+
521
+ Les références distantes diffèrent des branches (références `refs/heads`) principalement parce qu'on ne peut pas les récupérer dans le répertoire de travail.
522
+ Git les modifie comme des marque-pages du dernier état de ces branches sur le serveur.
523
+
524
+ ## Fichiers groupés ##
525
+
526
+ Revenons à la base de donnée d'objet de notre dépôt Git de test.
527
+ Pour l'instant, elle contient 11 objets : 4 blobs, 3 arbres, 3 *commits* et 1 tag :
528
+
529
+ $ find .git/objects -type f
530
+ .git/objects/01/55eb4229851634a0f03eb265b69f5a2d56f341 # arbre 2
531
+ .git/objects/1a/410efbd13591db07496601ebc7a059dd55cfe9 # commit 3
532
+ .git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a # test.txt v2
533
+ .git/objects/3c/4e9cd789d88d8d89c1073707c3585e41b0e614 # arbre 3
534
+ .git/objects/83/baae61804e65cc73a7201a7252750c76066a30 # test.txt v1
535
+ .git/objects/95/85191f37f7b0fb9444f35a9bf50de191beadc2 # tag
536
+ .git/objects/ca/c0cab538b970a37ea1e769cbbde608743bc96d # commit 2
537
+ .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 # 'test content'
538
+ .git/objects/d8/329fc1cc938780ffdd9f94e0d364e0ea74f579 # arbre 1
539
+ .git/objects/fa/49b077972391ad58037050f2a75f74e3671e92 # new.txt
540
+ .git/objects/fd/f4fc3344e67ab068f836878b6c4951e3b15f3d # commit 1
541
+
542
+ Git compresse le contenu de ces fichiers avec zlib et on ne stocke pas grand chose, au final, tous ces fichiers occupent seulement 925 octets.
543
+ Ajoutons de plus gros contenu au dépôt pour montrer une fonctionnalité intéressante de Git.
544
+ Ajoutez le fichier `repo.rb` de la bibliothèque Grit que vous avez manipulé plus tôt.
545
+ Il représente environ 12 Kio de code source :
546
+
547
+ $ curl -L https://raw.github.com/mojombo/grit/master/lib/grit/repo.rb > repo.rb
548
+ $ git add repo.rb
549
+ $ git commit -m 'added repo.rb'
550
+ [master 484a592] added repo.rb
551
+ 3 files changed, 459 insertions(+), 2 deletions(-)
552
+ delete mode 100644 bak/test.txt
553
+ create mode 100644 repo.rb
554
+ rewrite test.txt (100%)
555
+
556
+ Si vous observez l'arbre qui en résulte, vous verrez l'empreinte SHA-1 du blob contenant le fichier `repo.rb` :
557
+
558
+ $ git cat-file -p master^{tree}
559
+ 100644 blob fa49b077972391ad58037050f2a75f74e3671e92 new.txt
560
+ 100644 blob 9bc1dc421dcd51b4ac296e3e5b6e2a99cf44391e repo.rb
561
+ 100644 blob e3f094f522629ae358806b17daf78246c27c007b test.txt
562
+
563
+ Vous pouvez vérifier la taille de l'objet sur disque :
564
+
565
+ $ du -b .git/objects/9b/c1dc421dcd51b4ac296e3e5b6e2a99cf44391e
566
+ 4102 .git/objects/9b/c1dc421dcd51b4ac296e3e5b6e2a99cf44391e
567
+
568
+ Maintenant, modifiez le fichier un peu et voyez ce qui arrive :
569
+
570
+ $ echo '# testing' >> repo.rb
571
+ $ git commit -am 'modified repo a bit'
572
+ [master ab1afef] modified repo a bit
573
+ 1 files changed, 1 insertions(+), 0 deletions(-)
574
+
575
+ Regardez l'arbre créé par ce *commit* et vous verrez quelque chose d'intéressant :
576
+
577
+ $ git cat-file -p master^{tree}
578
+ 100644 blob fa49b077972391ad58037050f2a75f74e3671e92 new.txt
579
+ 100644 blob 05408d195263d853f09dca71d55116663690c27c repo.rb
580
+ 100644 blob e3f094f522629ae358806b17daf78246c27c007b test.txt
581
+
582
+ Ce blob est un blob différent.
583
+ Bien que l'on ait ajouté une seule ligne à la fin d'un fichier en faisant 400, Git enregistre ce nouveau contenu dans un objet totalement différent :
584
+
585
+ $ du -b .git/objects/05/408d195263d853f09dca71d55116663690c27c
586
+ 4109 .git/objects/05/408d195263d853f09dca71d55116663690c27c
587
+
588
+ Il y a donc deux objets de 4 Kio quasiment identiques sur le disque.
589
+ Ne serait-ce pas bien si Git pouvait n'enregistrer qu'un objet en entier, le deuxième n'étant qu'un delta (une différence) avec le premier ?
590
+
591
+ Il se trouve que c'est possible.
592
+ Le format initial dans lequel Git enregistre les objets sur le disque est appelé le format brut (*loose object*).
593
+ De temps en temps, Git compacte plusieurs de ces objets en un seul fichier binaire appelé *packfile* (fichier groupé), afin d'économiser de l'espace et d'être plus efficace.
594
+ Git effectue cette opération quand il y a trop d'objets au format brut, ou si l'on exécute manuellement la commande `git gc`, ou encore quand on pousse vers un serveur distant.
595
+ Pour voir cela en action, vous pouvez demander manuellement à Git de compacter les objets en exécutant la commande `git gc` :
596
+
597
+ $ git gc
598
+ Counting objects: 17, done.
599
+ Delta compression using 2 threads.
600
+ Compressing objects: 100% (13/13), done.
601
+ Writing objects: 100% (17/17), done.
602
+ Total 17 (delta 1), reused 10 (delta 0)
603
+
604
+ Si l'on jette un œil dans le répertoire des objets, on constatera que la plupart des objets ne sont plus là et qu'un couple de fichiers est apparu :
605
+
606
+ $ find .git/objects -type f
607
+ .git/objects/71/08f7ecb345ee9d0084193f147cdad4d2998293
608
+ .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
609
+ .git/objects/info/packs
610
+ .git/objects/pack/pack-7a16e4488ae40c7d2bc56ea2bd43e25212a66c45.idx
611
+ .git/objects/pack/pack-7a16e4488ae40c7d2bc56ea2bd43e25212a66c45.pack
612
+
613
+ Les objets restant sont des blobs qui ne sont pointés par aucun *commit*.
614
+ Dans notre cas, il s'agit des blobs « what is up, doc? » et « test content » créés plus tôt comme exemple.
615
+ Puisqu'ils n'ont été ajoutés à aucun *commit*, ils sont considérés en suspend et ne sont pas compactés dans le nouveau fichier groupé.
616
+
617
+ Les autres fichiers sont le nouveau fichier groupé et un index.
618
+ Le fichier groupé est un fichier unique rassemblant le contenu de tous les objets venant d'être supprimés du système de fichier.
619
+ L'index est un fichier contenant les emplacements dans le fichier groupé, pour que l'on puisse accéder rapidement à un objet particulier.
620
+ Ce qui est vraiment bien, c'est que les objets occupaient environ 12 Kio d'espace disque avant `gc` et que le nouveau fichier groupé en occupe seulement 6 Kio.
621
+ On a divisé par deux l'occupation du disque en regroupant les objets.
622
+
623
+ Comment Git réalise-t-il cela ?
624
+ Quand Git compacte des objets, il recherche les fichiers qui ont des noms et des tailles similaires, puis enregistre seulement les deltas entre une version du fichier et la suivante.
625
+ On peut regarder à l'intérieur du fichier groupé et voir l'espace économisé par Git.
626
+ La commande de plomberie `git verify-pack` vous permet de voir ce qui a été compacté :
627
+
628
+ $ git verify-pack -v \
629
+ .git/objects/pack/pack-7a16e4488ae40c7d2bc56ea2bd43e25212a66c45.idx
630
+ 0155eb4229851634a0f03eb265b69f5a2d56f341 tree 71 76 5400
631
+ 05408d195263d853f09dca71d55116663690c27c blob 12908 3478 874
632
+ 09f01cea547666f58d6a8d809583841a7c6f0130 tree 106 107 5086
633
+ 1a410efbd13591db07496601ebc7a059dd55cfe9 commit 225 151 322
634
+ 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a blob 10 19 5381
635
+ 3c4e9cd789d88d8d89c1073707c3585e41b0e614 tree 101 105 5211
636
+ 484a59275031909e19aadb7c92262719cfcdf19a commit 226 153 169
637
+ 83baae61804e65cc73a7201a7252750c76066a30 blob 10 19 5362
638
+ 9585191f37f7b0fb9444f35a9bf50de191beadc2 tag 136 127 5476
639
+ 9bc1dc421dcd51b4ac296e3e5b6e2a99cf44391e blob 7 18 5193 1 \
640
+ 05408d195263d853f09dca71d55116663690c27c
641
+ ab1afef80fac8e34258ff41fc1b867c702daa24b commit 232 157 12
642
+ cac0cab538b970a37ea1e769cbbde608743bc96d commit 226 154 473
643
+ d8329fc1cc938780ffdd9f94e0d364e0ea74f579 tree 36 46 5316
644
+ e3f094f522629ae358806b17daf78246c27c007b blob 1486 734 4352
645
+ f8f51d7d8a1760462eca26eebafde32087499533 tree 106 107 749
646
+ fa49b077972391ad58037050f2a75f74e3671e92 blob 9 18 856
647
+ fdf4fc3344e67ab068f836878b6c4951e3b15f3d commit 177 122 627
648
+ chain length = 1: 1 object
649
+ pack-7a16e4488ae40c7d2bc56ea2bd43e25212a66c45.pack: ok
650
+
651
+ Si on se souvient bien, le blob `9bc1d`, qui est la première version du fichier `repo.rb`, référence le blob `05408`, qui est la seconde version du fichier.
652
+ La troisième colonne de l'affichage est la taille de l'objet dans le fichier compact et on peut voir que `05408` occupe 12 Kio dans le fichier, mais que `9bc1d` occupe seulement 7 octets.
653
+ Ce qui est aussi intéressant est que la seconde version du fichier est celle qui est enregistrée telle quelle, tandis que la version originale est enregistrée sous forme d'un delta.
654
+ La raison en est que vous aurez sans doute besoin d'accéder rapidement aux versions les plus récentes du fichier.
655
+
656
+ Une chose intéressante à propos de ceci est que l'on peut recompacter à tout moment.
657
+ Git recompacte votre base de donnée occasionnellement, en essayant d'économiser de la place.
658
+ Vous pouvez aussi recompacter à la main, en exécutant la commande `git gc` vous-même.
659
+
660
+ ## Les références spécifiques ##
661
+
662
+ Dans tout le livre, nous avons utilisé des associations simples entre les branches distantes et les références locales.
663
+ Elles peuvent être plus complexes.
664
+ Supposons que vous ajoutiez un dépôt distant comme ceci :
665
+
666
+ $ git remote add origin git@github.com:schacon/simplegit-progit.git
667
+
668
+ Cela ajoute une section au fichier `.git/config`, contenant le nom du dépôt distant (`origin`), l'URL de ce dépôt et la spécification des références pour la récupération :
669
+
670
+ [remote "origin"]
671
+ url = git@github.com:schacon/simplegit-progit.git
672
+ fetch = +refs/heads/*:refs/remotes/origin/*
673
+
674
+ Le format d'une spécification de référence est un `+` facultatif, suivi de `<src>:<dst>`, où `<src>` est le motif des références du côté distant et `<dst>` est l'emplacement local où les références seront enregistrées.
675
+ Le `+` précise à Git de mettre à jour la référence même si ce n'est pas une avance rapide.
676
+
677
+ Dans le cas par défaut, qui est celui d'un enregistrement automatique par la commande `git remote add`, Git récupère toutes les références de `refs/heads/` sur le serveur et les enregistre localement dans `refs/remotes/origin/`.
678
+ Ainsi, s'il y a une branche `master` sur le serveur, vous pouvez accéder localement à l'historique de cette branche via :
679
+
680
+ $ git log origin/master
681
+ $ git log remotes/origin/master
682
+ $ git log refs/remotes/origin/master
683
+
684
+ Ces syntaxes sont toutes équivalentes, car Git les développe en `refs/remotes/origin/master`.
685
+
686
+ Si vous préférez que Git récupère seulement la branche `master` et non chacune des branches du serveur distant, vous pouvez remplacer la ligne fetch par :
687
+
688
+ fetch = +refs/heads/master:refs/remotes/origin/master
689
+
690
+ C'est la spécification des références de `git fetch` pour ce dépôt distant.
691
+ Si l'on veut effectuer une action particulière une seule fois, la spécification des références peut aussi être précisée en ligne de commande.
692
+ Pour retirer la branche `master` du dépôt distant vers la branche locale `origin/mymaster`, vous pouvez exécuter :
693
+
694
+ $ git fetch origin master:refs/remotes/origin/mymaster
695
+
696
+ Vous pouvez indiquer des spécifications pour plusieurs références.
697
+ En ligne de commande, vous pouvez tirer plusieurs branches de cette façon :
698
+
699
+ $ git fetch origin master:refs/remotes/origin/mymaster \
700
+ topic:refs/remotes/origin/topic
701
+ From git@github.com:schacon/simplegit
702
+ ! [rejected] master -> origin/mymaster (non fast forward)
703
+ * [new branch] topic -> origin/topic
704
+
705
+ Dans ce cas, la récupération *pull* de la branche `master` a été refusée car ce n'était pas une avance rapide.
706
+ On peut surcharger ce comportement en précisant un `+` devant la spécification de la référence.
707
+
708
+ On peut aussi indiquer plusieurs spécifications de référence pour la récupération, dans le fichier de configuration.
709
+ Si vous voulez toujours récupérer les branches `master` et `experiment`, ajoutez ces deux lignes :
710
+
711
+ [remote "origin"]
712
+ url = git@github.com:schacon/simplegit-progit.git
713
+ fetch = +refs/heads/master:refs/remotes/origin/master
714
+ fetch = +refs/heads/experiment:refs/remotes/origin/experiment
715
+
716
+ Vous ne pouvez pas utiliser des jokers partiels, ce qui suit est donc invalide :
717
+
718
+ fetch = +refs/heads/qa*:refs/remotes/origin/qa*
719
+
720
+ On peut toutefois utiliser des espaces de noms pour accomplir cela.
721
+ S'il existe une équipe qualité (QA) qui publie une série de branches et que l'on veut la branche `master`, les branches de l'équipe qualité et rien d'autre, on peut utiliser la configuration suivante :
722
+
723
+ [remote "origin"]
724
+ url = git@github.com:schacon/simplegit-progit.git
725
+ fetch = +refs/heads/master:refs/remotes/origin/master
726
+ fetch = +refs/heads/qa/*:refs/remotes/origin/qa/*
727
+
728
+ Si vous utilisez des processus complexes impliquant une équipe qualité, des développeurs et des intégrateurs qui publient des branches et qui collaborent sur des branches distantes, vous pouvez facilement utiliser des espaces de noms, de cette façon.
729
+
730
+ ### Publier une référence spécifique ###
731
+
732
+ Il est pratique de pouvoir récupérer des références issues d'espace de nom de cette façon, mais comment l'équipe qualité insère-t-elle ces branches dans l'espace de nom `qa/` en premier lieu ?
733
+ On peut accomplir cela en utilisant les spécifications de références pour la publication.
734
+
735
+ Si l'équipe qualité veut publier sa branche `master` vers `qa/master` sur le serveur distant, elle peut exécuter :
736
+
737
+ $ git push origin master:refs/heads/qa/master
738
+
739
+ Si elle veut que Git le fasse automatiquement à chaque exécution de `git push origin`, elle peut ajouter une entrée `push` au fichier de configuration :
740
+
741
+ [remote "origin"]
742
+ url = git@github.com:schacon/simplegit-progit.git
743
+ fetch = +refs/heads/*:refs/remotes/origin/*
744
+ push = refs/heads/master:refs/heads/qa/master
745
+
746
+ De même, cela fera que, par défaut, `git push origin` publiera la branche locale `master` sur la branche distante `qa/master`.
747
+
748
+ ### Supprimer des références ###
749
+
750
+ Vous pouvez aussi utiliser les spécifications de références pour supprimer des références sur le serveur distant en exécutant une commande comme :
751
+
752
+ $ git push origin :topic
753
+
754
+ La spécification de référence ressemble à `<src>:<dst>`, mais en laissant vide la partie `<src>`, cela signifie une création de la branche à partir de rien et donc sa suppression.
755
+
756
+ ## Protocoles de transfert ##
757
+
758
+ Git peut transférer des données entre deux dépôts, de deux façons principales : via HTTP et via un protocole dit « intelligent » utilisé par les transports `file://`, `ssh://` et `git://`.
759
+ Cette section fait un tour d'horizon du fonctionnement de ces deux protocoles.
760
+
761
+ ### Protocole stupide ###
762
+
763
+ On parle souvent du transfert Git sur HTTP comme étant un protocole stupide, car il ne nécessite aucun code spécifique à Git côté serveur durant le transfert.
764
+ Le processus de récupération est une série de requêtes GET, où le client devine la structure du dépôt Git présent sur le serveur.
765
+ Suivons le processus `http-fetch` pour la bibliothèque simplegit :
766
+
767
+ $ git clone http://github.com/schacon/simplegit-progit.git
768
+
769
+ La première chose que fait cette commande est de récupérer le fichier `info/refs`.
770
+ Ce fichier est écrit par la commande `update-server-info` et c'est pour cela qu'il faut activer le crochet `post-receive`, sinon le transfert HTTP ne fonctionnera pas correctement :
771
+
772
+ => GET info/refs
773
+ ca82a6dff817ec66f44342007202690a93763949 refs/heads/master
774
+
775
+ On possède maintenant une liste des références distantes et empreintes SHA1.
776
+ Ensuite, on regarde vers quoi pointe HEAD, pour savoir sur quelle branche se placer quand on aura fini :
777
+
778
+ => GET HEAD
779
+ ref: refs/heads/master
780
+
781
+ On aura besoin de se placer sur la branche `master`, quand le processus sera terminé.
782
+ On est maintenant prêt à démarrer le processus de parcours.
783
+ Puisque votre point de départ est l'objet *commit* `ca82a6` que vous avez vu dans le fichier `info/refs`, vous commencez par le récupérer :
784
+
785
+ => GET objects/ca/82a6dff817ec66f44342007202690a93763949
786
+ (179 bytes of binary data)
787
+
788
+ Vous obtenez un objet, cet objet est dans le format brut sur le serveur et vous l'avez récupéré à travers une requête HTTP GET statique.
789
+ Vous pouvez le décompresser avec zlib, ignorer l'en-tête et regarder le contenu du *commit* :
790
+
791
+ $ git cat-file -p ca82a6dff817ec66f44342007202690a93763949
792
+ tree cfda3bf379e4f8dba8717dee55aab78aef7f4daf
793
+ parent 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
794
+ author Scott Chacon <schacon@gmail.com> 1205815931 -0700
795
+ committer Scott Chacon <schacon@gmail.com> 1240030591 -0700
796
+
797
+ changed the version number
798
+
799
+ Puis, vous avez deux autres objets supplémentaires à récupérer : `cfda3b` qui est l'arbre du contenu sur lequel pointe le *commit* que nous venons de récupérer et `085bb3` qui est le *commit* parent :
800
+
801
+ => GET objects/08/5bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
802
+ (179 bytes of data)
803
+
804
+ Cela vous donne l'objet du prochain *commit*.
805
+ Récupérez l'objet arbre :
806
+
807
+ => GET objects/cf/da3bf379e4f8dba8717dee55aab78aef7f4daf
808
+ (404 - Not Found)
809
+
810
+ Oups, on dirait que l'objet arbre n'est pas au format brut sur le serveur, vous obtenez donc une réponse 404.
811
+ On peut en déduire certaines raisons : l'objet peut être dans un dépôt suppléant ou il peut être dans un fichier groupé de ce dépôt.
812
+ Git vérifie la liste des dépôts suppléants d'abord :
813
+
814
+ => GET objects/info/http-alternates
815
+ (empty file)
816
+
817
+ Si la réponse contenait une liste d'URL suppléantes, Git aurait cherché les fichiers bruts et les fichiers groupés à ces emplacements, c'est un mécanisme sympathique pour les projets qui ont dérivés d'un autre pour partager les objets sur le disque.
818
+ Cependant, puisqu'il n'y a pas de suppléants listés dans ce cas, votre objet doit se trouver dans un fichier groupé.
819
+ Pour voir quels fichiers groupés sont disponibles sur le serveur, vous avez besoin de récupérer le fichier `objects/info/packs`, qui en contient la liste (générée également par `update-server-info`) :
820
+
821
+ => GET objects/info/packs
822
+ P pack-816a9b2334da9953e530f27bcac22082a9f5b835.pack
823
+
824
+ Il n'existe qu'un seul fichier groupé sur le serveur, votre objet se trouve évidemment dedans, mais vous allez tout de même vérifier l'index pour être sûr.
825
+ C'est également utile lorsque vous avez plusieurs fichiers groupés sur le serveur, vous pouvez donc voir quel fichier groupé contient l'objet dont vous avez besoin :
826
+
827
+ => GET objects/pack/pack-816a9b2334da9953e530f27bcac22082a9f5b835.idx
828
+ (4k of binary data)
829
+
830
+ Maintenant que vous avez l'index du fichier groupé, vous pouvez vérifier si votre objet est bien dedans car l'index liste les empreintes SHA-1 des objets contenus dans ce fichier groupé et des emplacements de ces objets.
831
+ Votre objet est là, allez donc récupérer le fichier groupé complet :
832
+
833
+ => GET objects/pack/pack-816a9b2334da9953e530f27bcac22082a9f5b835.pack
834
+ (13k of binary data)
835
+
836
+ Vous avez votre objet arbre, vous continuez donc le chemin des *commits*.
837
+ Ils sont également tous contenus dans votre fichier groupé que vous venez de télécharger, vous n'avez donc pas d'autres requêtes à faire au serveur.
838
+ Git récupère une copie de travail de votre branche `master` qui été référencée par HEAD que vous avez téléchargé au début.
839
+
840
+ La sortie complète de cette procédure ressemble à :
841
+
842
+ $ git clone http://github.com/schacon/simplegit-progit.git
843
+ Initialized empty Git repository in /private/tmp/simplegit-progit/.git/
844
+ got ca82a6dff817ec66f44342007202690a93763949
845
+ walk ca82a6dff817ec66f44342007202690a93763949
846
+ got 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
847
+ Getting alternates list for http://github.com/schacon/simplegit-progit.git
848
+ Getting pack list for http://github.com/schacon/simplegit-progit.git
849
+ Getting index for pack 816a9b2334da9953e530f27bcac22082a9f5b835
850
+ Getting pack 816a9b2334da9953e530f27bcac22082a9f5b835
851
+ which contains cfda3bf379e4f8dba8717dee55aab78aef7f4daf
852
+ walk 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
853
+ walk a11bef06a3f659402fe7563abf99ad00de2209e6
854
+
855
+ ### Protocole intelligent ###
856
+
857
+ La méthode HTTP est simple mais un peu inefficace.
858
+ Utiliser des protocoles intelligents est une méthode plus habituelles pour transférer des données.
859
+ Ces protocoles ont un exécutable du côté distant qui connaît Git, il peut lire les données locales et deviner ce que le client a ou ce dont il a besoin pour générer des données personnalisées pour lui.
860
+ Il y a deux ensembles d'exécutables pour transférer les données : une paire pour téléverser des données et une paire pour en télécharger.
861
+
862
+ #### Téléverser des données ####
863
+
864
+ Pour téléverser des données vers un exécutable distant, Git utilise les exécutables `send-pack` et `receive-pack`.
865
+ L'exécutable `send-pack` tourne sur le client et se connecte à l'exécutable `receive-pack` du côté serveur.
866
+
867
+ Par exemple, disons que vous exécutez `git push origin master` dans votre projet et `origin` est défini comme une URL qui utilise le protocole SSH.
868
+ Git appelle l'exécutable `send-pack`, qui initialise une connexion à travers SSH vers votre serveur.
869
+ Il essaye d'exécuter une commande sur le serveur distant via un appel SSH qui ressemble à :
870
+
871
+ $ ssh -x git@github.com "git-receive-pack 'schacon/simplegit-progit.git'"
872
+ 005bca82a6dff817ec66f4437202690a93763949 refs/heads/master report-status delete-refs
873
+ 003e085bb3bcb608e1e84b2432f8ecbe6306e7e7 refs/heads/topic
874
+ 0000
875
+
876
+ La commande `git-receive-pack` répond immédiatement avec une ligne pour chaque référence qu'elle connaît actuellement, dans ce cas, uniquement la branche `master` et ses empreintes SHA.
877
+ La première ligne contient également une liste des compétences du serveur (ici : `report-status` et `delete-refs`).
878
+
879
+ Chaque ligne commence avec une valeur hexadécimale sur 4 octets, spécifiant le reste de la longueur de la ligne.
880
+ La première ligne, ici, commence avec `005b`, soit 91 en hexadécimal, ce qui signifie qu'il y a 91 octets restants sur cette ligne.
881
+ La ligne suivante commence avec `003e`, soit 62, vous lisez donc les 62 octets restants.
882
+ La ligne d'après est `0000`, signifiant que le serveur a fini de lister ses références.
883
+
884
+ Maintenant que vous connaissez l'état du serveur, votre exécutable `send-pack` détermine quels *commits* il a que le serveur n'a pas.
885
+ L'exécutable `send-pack` envoie alors à l'exécutable `receive-pack`, les informations concernant chaque référence que cette commande `push` va mettre à jour.
886
+ Par exemple, si vous mettez à jour la branche `master` et ajoutez la branche `experiment`, la réponse de `send-pack` ressemblera à quelque chose comme :
887
+
888
+ 0085ca82a6dff817ec66f44342007202690a93763949 15027957951b64cf874c3557a0f3547bd83b3ff6 refs/heads/master report-status
889
+ 00670000000000000000000000000000000000000000 cdfdb42577e2506715f8cfeacdbabc092bf63e8d refs/heads/experiment
890
+ 0000
891
+
892
+ La valeur SHA-1 remplie de '0' signifie qu'il n'y avait rien à cet endroit avant, car vous êtes en train d'ajouter la référence `experiment`.
893
+ Si vous étiez en train de supprimer une référence, vous verriez l'opposé : que des '0' du côté droit.
894
+
895
+ Git envoie une ligne pour chaque référence que l'on met à jour avec l'ancien SHA, le nouveau SHA et la référence en train d'être mise à jour.
896
+ La première ligne contient également les compétences du client.
897
+ Puis, le client téléverse un fichier groupé de tous les objets que le serveur n'a pas encore.
898
+ Finalement, le serveur répond avec une indication de succès (ou d'échec) :
899
+
900
+ 000Aunpack ok
901
+
902
+ #### Téléchargement des données ####
903
+
904
+ Lorsque vous téléchargez des données, les exécutables `fetch-pack` et `upload-pack` entrent en jeu.
905
+ Le client initialise un exécutable `fetch-pack` qui se connecte à un exécutable `upload-pack` du côté serveur pour négocier quelles données seront remontées.
906
+
907
+ Il y a plusieurs manières d'initialiser l'exécutable `upload-pack` sur le dépôt distant.
908
+ Vous pouvez passer par SSH de la même manière qu'avec l'exécutable `receive-pack`.
909
+ Vous pouvez également initialiser l'exécutable à travers le *daemon* Git, qui écoute sur le port 9418 du serveur par défaut.
910
+ L'exécutable `fetch-pack` envoie des données qui ressemblent à cela juste après la connexion :
911
+
912
+ 003fgit-upload-pack schacon/simplegit-progit.git\0host=myserver.com\0
913
+
914
+ Cela commence par les 4 octets désignant la quantité de données qui suit, puis la commande à exécuter suivie par un octet nul, puis le nom d'hôte du serveur suivi d'un octet nul final.
915
+ Le *daemon* Git vérifie que la commande peut être exécutée, que le dépôt existe et est accessible publiquement.
916
+ Si tout va bien, il appelle l'exécutable `upload-pack` et lui passe la main.
917
+
918
+ Si vous êtes en train de tirer (*fetch*) à travers SSH, `fetch-pack` exécute plutôt quelque chose du genre :
919
+
920
+ $ ssh -x git@github.com "git-upload-pack 'schacon/simplegit-progit.git'"
921
+
922
+ Dans tous les cas, après que `fetch-pack` se connecte, `upload-pack` lui répond quelque chose du style :
923
+
924
+ 0088ca82a6dff817ec66f44342007202690a93763949 HEAD\0multi_ack thin-pack \
925
+ side-band side-band-64k ofs-delta shallow no-progress include-tag
926
+ 003fca82a6dff817ec66f44342007202690a93763949 refs/heads/master
927
+ 003e085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 refs/heads/topic
928
+ 0000
929
+
930
+ C'est très proche de ce que répondait `receive-pack` mais les compétences sont différentes.
931
+ En plus, il vous répond la référence HEAD, afin que le client sache quoi récupérer dans le cas d'un clone.
932
+
933
+ À ce moment, l'exécutable `fetch-pack` regarde quels objets il a et répond avec les objets dont il a besoin en envoyant « want » (vouloir) suivi du SHA qu'il veut.
934
+ Il envoie tous les objets qu'il a déjà avec « have » suivi du SHA.
935
+ À la fin de la liste, il écrit « done » pour inciter l'exécutable `upload-pack` à commencer à envoyer le fichier groupé des données demandées :
936
+
937
+ 0054want ca82a6dff817ec66f44342007202690a93763949 ofs-delta
938
+ 0032have 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
939
+ 0000
940
+ 0009done
941
+
942
+ C'est le cas basique d'un protocole de transfert.
943
+ Dans des cas plus complexes, le client a des compétences `multi_ack` (plusieurs réponses) ou `side-band` (plusieurs connexions), mais cet exemple vous montre les bases du protocole intelligent.
944
+
945
+
946
+ ## Maintenance et récupération de données ##
947
+
948
+ Parfois, vous aurez besoin de faire un peu de ménage : faire un dépôt plus compact, nettoyer les dépôts importés, ou récupérer du travail perdu.
949
+ Cette section couvrira certains de ces scénarios.
950
+
951
+
952
+ ### Maintenance ###
953
+
954
+ De temps en temps, Git exécute automatiquement une commande appelée « auto gc ».
955
+ La plupart du temps, cette commande ne fait rien.
956
+ Cependant, s'il y a trop d'objets bruts (des objets qui ne sont pas dans des fichiers groupés), ou trop de fichiers groupés, Git lance une commande `git gc` à part entière.
957
+ `gc` est l'abréviation pour « garbage collect » (ramasse-miettes) et la commande fait plusieurs choses : elle rassemble plusieurs objets bruts et les place dans des fichiers groupés, elle rassemble des fichiers groupés en un gros fichier groupé et elle supprime des objets qui ne sont plus accessibles depuis un *commit* et qui sont vieux de plusieurs mois.
958
+
959
+ Vous pouvez exécuter `auto gc` manuellement :
960
+
961
+ $ git gc --auto
962
+
963
+ Encore une fois, cela ne fait généralement rien.
964
+ Vous devez avoir environ 7 000 objets bruts ou plus de 50 fichiers groupés pour que Git appelle une vraie commande `gc`.
965
+ Vous pouvez modifier ces limites avec les propriétés de configuration `gc.auto` et `gc.autopacklimit`, respectivement.
966
+
967
+ `gc` regroupera aussi vos références dans un seul fichier.
968
+ Supposons que votre dépôt contienne les branches et étiquettes suivantes :
969
+
970
+ $ find .git/refs -type f
971
+ .git/refs/heads/experiment
972
+ .git/refs/heads/master
973
+ .git/refs/tags/v1.0
974
+ .git/refs/tags/v1.1
975
+
976
+ Si vous exécutez `git gc`, vous n'aurez plus ces fichiers dans votre répertoire `refs`.
977
+ Git les déplacera pour plus d'efficacité dans un fichier nommé `.git/packed-refs` qui ressemble à ceci :
978
+
979
+ $ cat .git/packed-refs
980
+ # pack-refs with: peeled
981
+ cac0cab538b970a37ea1e769cbbde608743bc96d refs/heads/experiment
982
+ ab1afef80fac8e34258ff41fc1b867c702daa24b refs/heads/master
983
+ cac0cab538b970a37ea1e769cbbde608743bc96d refs/tags/v1.0
984
+ 9585191f37f7b0fb9444f35a9bf50de191beadc2 refs/tags/v1.1
985
+ ^1a410efbd13591db07496601ebc7a059dd55cfe9
986
+
987
+ Si vous mettez à jour une référence, Git ne modifiera pas ce fichier, mais enregistrera plutôt un nouveau fichier dans `refs/heads`.
988
+ Pour obtenir l'empreinte SHA approprié pour une référence donnée, Git cherche d'abord cette référence dans le répertoire `refs`, puis dans le fichier `packed-refs` si non trouvée.
989
+ Cependant, si vous ne pouvez pas trouver une référence dans votre répertoire `refs`, elle est probablement dans votre fichier `packed-refs`.
990
+
991
+ Remarquez la dernière ligne du fichier, celle commençant par `^`.
992
+ Cela signifie que l'étiquette directement au-dessus est une étiquette annotée et que cette ligne est le *commit* que l'étiquette annotée référence.
993
+
994
+ ### Récupération de données ###
995
+
996
+ À un moment quelconque de votre vie avec Git, vous pouvez accidentellement perdre un *commit*.
997
+ Généralement, cela arrive parce que vous avez forcé la suppression d'une branche contenant du travail et il se trouve que vous vouliez cette branche finalement ; ou vous avez réinitialisé une branche avec suppression, en abandonnant des *commits* dont vous vouliez des informations.
998
+ Supposons que cela arrive, comment pouvez-vous récupérer vos *commits* ?
999
+
1000
+ Voici un exemple qui réinitialise la branche `master` avec suppression dans votre dépôt de test vers un ancien *commit* et qui récupère les *commits* perdus.
1001
+ Premièrement, vérifions dans quel état est votre dépôt en ce moment :
1002
+
1003
+ $ git log --pretty=oneline
1004
+ ab1afef80fac8e34258ff41fc1b867c702daa24b modified repo a bit
1005
+ 484a59275031909e19aadb7c92262719cfcdf19a added repo.rb
1006
+ 1a410efbd13591db07496601ebc7a059dd55cfe9 third commit
1007
+ cac0cab538b970a37ea1e769cbbde608743bc96d second commit
1008
+ fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit
1009
+
1010
+ Maintenant, déplaçons la branche `master` vers le *commit* du milieu :
1011
+
1012
+ $ git reset --hard 1a410efbd13591db07496601ebc7a059dd55cfe9
1013
+ HEAD is now at 1a410ef third commit
1014
+ $ git log --pretty=oneline
1015
+ 1a410efbd13591db07496601ebc7a059dd55cfe9 third commit
1016
+ cac0cab538b970a37ea1e769cbbde608743bc96d second commit
1017
+ fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit
1018
+
1019
+ Vous avez effectivement perdu les deux *commits* du haut, vous n'avez pas de branche depuis laquelle ces *commits* seraient accessibles.
1020
+ Vous avez besoin de trouver le SHA du dernier *commit* et d'ajouter une branche s'y référant.
1021
+ Le problème est de trouver ce SHA, ce n'est pas comme si vous l'aviez mémorisé, hein ?
1022
+
1023
+ Souvent, la manière la plus rapide est d'utiliser l'outil `git reflog`.
1024
+ Pendant que vous travaillez, Git enregistre l'emplacement de votre HEAD chaque fois que vous le changez.
1025
+ À chaque *commit* ou commutation de branche, le journal des références (*reflog*) est mis à jour.
1026
+ Le journal des références est aussi mis à jour par la commande `git update-ref`, qui est une autre raison de l'utiliser plutôt que de simplement écrire votre valeur SHA dans vos fichiers de références, comme mentionné dans la section « Références Git » plus haut dans ce chapitre.
1027
+ Vous pouvez voir où vous étiez à n'importe quel moment en exécutant `git reflog` :
1028
+
1029
+ $ git reflog
1030
+ 1a410ef HEAD@{0}: 1a410efbd13591db07496601ebc7a059dd55cfe9: updating HEAD
1031
+ ab1afef HEAD@{1}: ab1afef80fac8e34258ff41fc1b867c702daa24b: updating HEAD
1032
+
1033
+ Ici, nous pouvons voir deux *commits* que nous avons récupérés, cependant, il n'y a pas plus d'information ici.
1034
+ Pour voir, les mêmes informations d'une manière plus utile, nous pouvons exécuter `git log -g`, qui nous donnera une sortie normalisée pour votre journal de références :
1035
+
1036
+ $ git log -g
1037
+ commit 1a410efbd13591db07496601ebc7a059dd55cfe9
1038
+ Reflog: HEAD@{0} (Scott Chacon <schacon@gmail.com>)
1039
+ Reflog message: updating HEAD
1040
+ Author: Scott Chacon <schacon@gmail.com>
1041
+ Date: Fri May 22 18:22:37 2009 -0700
1042
+
1043
+ third commit
1044
+
1045
+ commit ab1afef80fac8e34258ff41fc1b867c702daa24b
1046
+ Reflog: HEAD@{1} (Scott Chacon <schacon@gmail.com>)
1047
+ Reflog message: updating HEAD
1048
+ Author: Scott Chacon <schacon@gmail.com>
1049
+ Date: Fri May 22 18:15:24 2009 -0700
1050
+
1051
+ modified repo a bit
1052
+
1053
+
1054
+ On dirait que le *commit* du bas est celui que vous avez perdu, vous pouvez donc le récupérer en créant une nouvelle branche sur ce *commit*.
1055
+ Par exemple, vous créez une branche nommée `recover-branch` au *commit* (ab1afef):
1056
+
1057
+ $ git branch recover-branch ab1afef
1058
+ $ git log --pretty=oneline recover-branch
1059
+ ab1afef80fac8e34258ff41fc1b867c702daa24b modified repo a bit
1060
+ 484a59275031909e19aadb7c92262719cfcdf19a added repo.rb
1061
+ 1a410efbd13591db07496601ebc7a059dd55cfe9 third commit
1062
+ cac0cab538b970a37ea1e769cbbde608743bc96d second commit
1063
+ fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit
1064
+
1065
+ Super, maintenant vous avez une nouvelle branche appelée `recover-branch` à l'emplacement où votre branche `master` se trouvait, faisant en sorte que les deux premiers *commits* soit à nouveau accessibles.
1066
+
1067
+ Pour poursuivre, nous supposerons que vos pertes ne sont pas dans le journal des références pour une raison quelconque.
1068
+ On peut simuler cela en supprimant `recover-branch` et le journal des références.
1069
+ Maintenant, les deux premiers *commits* ne sont plus accessibles (encore) :
1070
+
1071
+ $ git branch –D recover-branch
1072
+ $ rm -Rf .git/logs/
1073
+
1074
+
1075
+ Puisque les données du journal de référence sont sauvegardées dans le répertoire `.git/logs/`, vous n'avez effectivement plus de journal de références.
1076
+ Comment pouvez-vous récupérer ces *commits* maintenant ?
1077
+ Une manière de faire est d'utiliser l'outil `git fsck`, qui vérifie l'intégrité de votre base de données.
1078
+ Si vous l'exécutez avec l'option `--full`, il vous montre tous les objets qui ne sont pas référencés par d'autres objets :
1079
+
1080
+ $ git fsck --full
1081
+ dangling blob d670460b4b4aece5915caf5c68d12f560a9fe3e4
1082
+ dangling commit ab1afef80fac8e34258ff41fc1b867c702daa24b
1083
+ dangling tree aea790b9a58f6cf6f2804eeac9f0abbe9631e4c9
1084
+ dangling blob 7108f7ecb345ee9d0084193f147cdad4d2998293
1085
+
1086
+ Dans ce cas, vous pouvez voir votre *commit* manquant après « dangling commit ».
1087
+ Vous pouvez le restaurer de la même manière que précédemment, en créant une branche qui référence cette empreinte SHA.
1088
+
1089
+ ### Suppression d'objets ###
1090
+
1091
+ Il y a beaucoup de choses dans Git qui sont géniales, mais une fonctionnalité qui peut poser problème est le fait que `git clone` télécharge l'historique entier du projet, incluant chaque version de chaque fichier.
1092
+ C'est très bien lorsque le tout est du code source, parce que Git est hautement optimisé pour compresser les données efficacement.
1093
+ Cependant, si quelqu'un à un moment donné de l'historique de votre projet a ajouté un énorme fichier, chaque clone sera forcé de télécharger cet énorme fichier, même s'il a été supprimé du projet dans le *commit* suivant.
1094
+ Puisqu'il est accessible depuis l'historique, il sera toujours là.
1095
+
1096
+ Cela peut être un énorme problème, lorsque vous convertissez un dépôt Subversion ou Perforce en un dépôt Git.
1097
+ Car, comme vous ne téléchargez pas l'historique entier dans ces systèmes, ce genre d'ajout n'a que peu de conséquences.
1098
+ Si vous avez importé depuis un autre système ou que votre dépôt est beaucoup plus gros que ce qu'il devrait être, voici comment vous pouvez trouver et supprimer des gros objets.
1099
+
1100
+ Soyez prévenu : cette technique détruit votre historique de *commit*.
1101
+ Elle réécrit chaque objet *commit* depuis le premier objet arbre que vous modifiez pour supprimer une référence d'un gros fichier.
1102
+ Si vous faites cela immédiatement après un import, avant que quiconque n'ait eu le temps de commencer à travailler sur ce *commit*, tout va bien.
1103
+ Sinon, vous devez alerter tous les contributeurs qu'ils doivent recommencer (ou au moins faire un `rebase`) sur votre nouveau *commit*.
1104
+
1105
+ Pour la démonstration, nous allons ajouter un gros fichier dans votre dépôt de test, le supprimer dans le *commit* suivant, le trouver et le supprimer de manière permanente du dépôt.
1106
+ Premièrement, ajoutons un gros objet à votre historique :
1107
+
1108
+ $ curl http://kernel.org/pub/software/scm/git/git-1.6.3.1.tar.bz2 > git.tbz2
1109
+ $ git add git.tbz2
1110
+ $ git commit -am 'added git tarball'
1111
+ [master 6df7640] added git tarball
1112
+ 1 files changed, 0 insertions(+), 0 deletions(-)
1113
+ create mode 100644 git.tbz2
1114
+
1115
+ Oups, vous ne vouliez pas rajouter une énorme archive à votre projet.
1116
+ Il vaut mieux s'en débarrasser :
1117
+
1118
+ $ git rm git.tbz2
1119
+ rm 'git.tbz2'
1120
+ $ git commit -m 'oops - removed large tarball'
1121
+ [master da3f30d] oops - removed large tarball
1122
+ 1 files changed, 0 insertions(+), 0 deletions(-)
1123
+ delete mode 100644 git.tbz2
1124
+
1125
+ Maintenant, faites un `gc` sur votre base de données, pour voir combien d'espace disque vous utilisez :
1126
+
1127
+ $ git gc
1128
+ Counting objects: 21, done.
1129
+ Delta compression using 2 threads.
1130
+ Compressing objects: 100% (16/16), done.
1131
+ Writing objects: 100% (21/21), done.
1132
+ Total 21 (delta 3), reused 15 (delta 1)
1133
+
1134
+ Vous pouvez exécuter la commande `count-objects` pour voir rapidement combien d'espace disque vous utilisez :
1135
+
1136
+ $ git count-objects -v
1137
+ count: 4
1138
+ size: 16
1139
+ in-pack: 21
1140
+ packs: 1
1141
+ size-pack: 2016
1142
+ prune-packable: 0
1143
+ garbage: 0
1144
+
1145
+ L'entrée `size-pack` est la taille de vos fichiers groupés en kilo-octet, vous utilisez donc 2 Mio.
1146
+ Avant votre dernier *commit*, vous utilisiez environ 2 Kio, clairement, supprimer le fichier avec le *commit* précédent ne l'a pas enlevé de votre historique.
1147
+ À chaque fois que quelqu'un clonera votre dépôt, il aura à cloner les 2 Mio pour récupérer votre tout petit projet, parce que vous avez accidentellement rajouté un gros fichier.
1148
+ Débarrassons-nous en.
1149
+
1150
+ Premièrement, vous devez le trouver.
1151
+ Dans ce cas, vous savez déjà de quel fichier il s'agit.
1152
+ Mais supposons que vous ne le sachiez pas, comment identifieriez-vous quel(s) fichier(s) prennent trop de place ?
1153
+ Si vous exécutez `git gc`, tous les objets sont dans des fichiers groupés ; vous pouvez identifier les gros objets en utilisant une autre commande de plomberie appelée `git verify-pack` et en triant sur le troisième champ de la sortie qui est la taille des fichiers.
1154
+ Vous pouvez également le faire suivre à la commande `tail` car vous ne vous intéressez qu'aux fichiers les plus gros :
1155
+
1156
+ $ git verify-pack -v .git/objects/pack/pack-3f8c0...bb.idx | sort -k 3 -n | tail -3
1157
+ e3f094f522629ae358806b17daf78246c27c007b blob 1486 734 4667
1158
+ 05408d195263d853f09dca71d55116663690c27c blob 12908 3478 1189
1159
+ 7a9eb2fba2b1811321254ac360970fc169ba2330 blob 2056716 2056872 5401
1160
+
1161
+ Le gros objet est à la fin : 2 Mio.
1162
+ Pour trouver quel fichier c'est, vous allez utiliser la commande `rev-list`, que vous avez utilisée brièvement dans le chapitre 7.
1163
+ Si vous mettez l'option `--objects` à `rev-list`, elle listera tous les SHA des *commits* et des blobs avec le chemin du fichier associé.
1164
+ Vous pouvez utilisez cette commande pour trouver le nom de votre blob :
1165
+
1166
+ $ git rev-list --objects --all | grep 7a9eb2fb
1167
+ 7a9eb2fba2b1811321254ac360970fc169ba2330 git.tbz2
1168
+
1169
+ Maintenant, vous voulez supprimer ce fichier de toutes les arborescences passées.
1170
+ Vous pouvez facilement voir quels *commits* ont modifié ce fichier :
1171
+
1172
+ $ git log --pretty=oneline --branches -- git.tbz2
1173
+ da3f30d019005479c99eb4c3406225613985a1db oops - removed large tarball
1174
+ 6df764092f3e7c8f5f94cbe08ee5cf42e92a0289 added git tarball
1175
+
1176
+ Vous devez réécrire tous les *commits* qui sont liés à `6df76` pour supprimer totalement ce fichier depuis votre historique Git.
1177
+ Pour cela, utilisez `filter-branch`, que vous avez utilisé dans le chapitre 6 :
1178
+
1179
+ $ git filter-branch --index-filter \
1180
+ 'git rm --cached --ignore-unmatch git.tbz2' -- 6df7640^..
1181
+ Rewrite 6df764092f3e7c8f5f94cbe08ee5cf42e92a0289 (1/2)rm 'git.tbz2'
1182
+ Rewrite da3f30d019005479c99eb4c3406225613985a1db (2/2)
1183
+ Ref 'refs/heads/master' was rewritten
1184
+
1185
+ L'option `--index-filter` est similaire à l'option `--tree-filter` utilisée dans le chapitre 6, sauf qu'au lieu de modifier les fichiers sur le disque, vous modifiez votre zone d'attente et votre index.
1186
+ Plutôt que de supprimer un fichier spécifique avec une commande comme `rm file`, vous devez le supprimer avec `git rm --cached` ; vous devez le supprimer de l'index, pas du disque.
1187
+ La raison de faire cela de cette manière est la rapidité, car Git n'ayant pas besoin de récupérer chaque révision sur disque avant votre filtre, la procédure peut être beaucoup, beaucoup plus rapide.
1188
+ Vous pouvez faire la même chose avec `--tree-filter` si vous voulez.
1189
+ L'option `--ignore-unmatch` de `git rm` lui dit que ce n'est pas une erreur si le motif que vous voulez supprimez n'existe pas.
1190
+ Finalement, vous demandez à `filter-branch` de réécrire votre historique seulement depuis le parent du *commit* `6df7640`, car vous savez que c'est de là que le problème a commencé.
1191
+ Sinon, il aurait démarré du début et serait plus long sans nécessité.
1192
+
1193
+ Votre historique ne contient plus de référence à ce fichier.
1194
+ Cependant, votre journal de révision et un nouvel ensemble de références que Git a ajouté lors de votre `filter-branch` dans `.git/refs/original` en contiennent encore, vous devez donc les supprimer puis regrouper votre base de données.
1195
+ Vous devez vous débarrasser de tout ce qui fait référence à ces vieux *commits* avant de regrouper :
1196
+
1197
+ $ rm -Rf .git/refs/original
1198
+ $ rm -Rf .git/logs/
1199
+ $ git gc
1200
+ Counting objects: 19, done.
1201
+ Delta compression using 2 threads.
1202
+ Compressing objects: 100% (14/14), done.
1203
+ Writing objects: 100% (19/19), done.
1204
+ Total 19 (delta 3), reused 16 (delta 1)
1205
+
1206
+ Voyons combien d'espace vous avez récupéré :
1207
+
1208
+ $ git count-objects -v
1209
+ count: 8
1210
+ size: 2040
1211
+ in-pack: 19
1212
+ packs: 1
1213
+ size-pack: 7
1214
+ prune-packable: 0
1215
+ garbage: 0
1216
+
1217
+ La taille du dépôt regroupé est retombée à 7 Kio, ce qui est beaucoup moins que 2 Mio.
1218
+ Vous pouvez voir dans la valeur « size » que votre gros objet est toujours dans vos objets bruts, il n'est donc pas parti ; mais il ne sera plus transféré lors d'une poussée vers un serveur ou un clone, ce qui est l'important dans l'histoire.
1219
+ Si vous voulez réellement, vous pouvez supprimer complètement l'objet en exécutant `git prune --expire`.
1220
+
1221
+ ## Résumé ##
1222
+
1223
+ Vous devriez avoir une plutôt bonne compréhension de ce que Git fait en arrière plan et, à un certain degré, comment c'est implémenté.
1224
+ Ce chapitre a parcouru un certain nombre de commandes de plomberie, commandes qui sont à un niveau plus bas et plus simple que les commandes de porcelaine que vous avez apprises dans le reste du livre.
1225
+ Comprendre comment Git travaille à bas niveau devrait vous aider à comprendre pourquoi il fait ce qu'il fait et à créer vos propres outils et scripts pour que votre procédure de travail fonctionne comme vous l'entendez.
1226
+
1227
+ Git, comme un système de fichiers adressables par contenu, est un outil puissant que vous pouvez utiliser pour des fonctionnalités au-delà d'un VCS.
1228
+ J'espère que vous pourrez utiliser votre connaissance nouvellement acquise des tripes de Git pour implémenter votre propre super application avec cette technologie et que vous vous sentirez plus à l'aise pour utiliser Git de manière plus poussée.