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,1382 @@
1
+ # Mechanizmy wewnętrzne w Git #
2
+
3
+ <!-- # Git Internals # -->
4
+
5
+ Być może przeskoczyłeś do tego rozdziału z poprzedniego, lub dotarłeś aż dotąd po przeczytaniu reszty książki - w każdym z tych przypadków, dowiesz się tutaj o tym w jaki sposób pracują wewnętrzne mechanizmy i ich implementacja w Git. Wiem, jak ważne jest poznanie tych rzeczy, aby zrozumieć jak przydatnym i potężnym narzędziem jest Git, jednak niektóre osoby wskazywały że może to wprowadzać zamieszanie i niepotrzebnie komplikować sprawy dla początkujących użytkowników. Dlatego zawarłem te informacje w ostatnim rozdziale w książce, tak abyś mógł go przeczytać w dowolnym momencie nauki. Decyzję zostawiam Tobie.
6
+
7
+ <!-- You may have skipped to this chapter from a previous chapter, or you may have gotten here after reading the rest of the book — in either case, this is where you’ll go over the inner workings and implementation of Git. I found that learning this information was fundamentally important to understanding how useful and powerful Git is, but others have argued to me that it can be confusing and unnecessarily complex for beginners. Thus, I’ve made this discussion the last chapter in the book so you could read it early or later in your learning process. I leave it up to you to decide. -->
8
+
9
+ Teraz, gdy jesteś już tutaj, rozpocznijmy. Po pierwsze, jeżeli nie jest to jeszcze jasne, podstawą Gita jest systemem plików ukierunkowanym na treść, z nałożonym interfejsem użytkownika obsługującym kontrolę wersji (VCS). Dowiesz się co to oznacza za chwilę.
10
+
11
+ <!-- Now that you’re here, let’s get started. First, if it isn’t yet clear, Git is fundamentally a content-addressable filesystem with a VCS user interface written on top of it. You’ll learn more about what this means in a bit. -->
12
+
13
+ We wczesnych fazach Gita (głównie przed wersją 1.5), interfejs użytkownika był dużo bardziej skomplikowany, ponieważ kładł nacisk na sam system plików, a nie funkcjonalności VCS. W ciągu ostatnich kilku lat, interfejs został dopracowany i jest teraz tak łatwy jak inne; jednak często pokutuje stereotyp na temat pierwszych wersji UI, które były skomplikowane i trudne do nauczenia.
14
+
15
+ <!-- In the early days of Git (mostly pre 1.5), the user interface was much more complex because it emphasized this filesystem rather than a polished VCS. In the last few years, the UI has been refined until it’s as clean and easy to use as any system out there; but often, the stereotype lingers about the early Git UI that was complex and difficult to learn. -->
16
+
17
+ Warstwa systemu plików jest zadziwiająco fajna, dlatego właśnie ją opiszę w tym rozdziale; następnie, nauczysz się na temat protokołów transportowych oraz zadań związanych z obsługą repozytorium z którymi być może będziesz miał do czynienia.
18
+
19
+ <!-- The content-addressable filesystem layer is amazingly cool, so I’ll cover that first in this chapter; then, you’ll learn about the transport mechanisms and the repository maintenance tasks that you may eventually have to deal with. -->
20
+
21
+ ## Komendy Plumbing i Porcelain ##
22
+
23
+ <!-- ## Plumbing and Porcelain ## -->
24
+
25
+ Ta książka opisuje jak używać Gita przy użyciu około 30 komend, takich jak `checkout`, `branch`, `remote` itd. Ale ponieważ Git był początkowo tylko zestawem narzędzi do obsługi VCS, a nie pełnoprawnym systemem VCS, ma garść komend które wykonują niskopoziomowe czynności i zostały zaprojektowane do łączenia ich w łańcuchy komend w stylu UNIX lub wywoływania z skryptów. Te komendy generalnie nazywane są komendami "plumbing", a te bardziej przyjazne dla użytkownika to komendy "porcelain".
26
+
27
+ <!-- This book covers how to use Git with 30 or so verbs such as `checkout`, `branch`, `remote`, and so on. But because Git was initially a toolkit for a VCS rather than a full user-friendly VCS, it has a bunch of verbs that do low-level work and were designed to be chained together UNIX style or called from scripts. These commands are generally referred to as "plumbing" commands, and the more user-friendly commands are called "porcelain" commands. -->
28
+
29
+ Pierwsze osiem rozdziałów książki opisywało praktycznie wyłącznie komendy "porcelain". Ale w tym rozdziale, będziesz używał głównie komend niskopoziomowych "plumbing", ponieważ daje one dostęp do wewnętrznych mechanizmów Gita i pomagają pokazać jak i dlaczego Git robi to co robi. Te komendy nie zostały stworzone do ręcznego uruchamiania z linii komend, ale raczej aby mogły być użyte do budowania nowych narzędzi lub niestandardowych skryptów.
30
+
31
+ <!-- The book’s first eight chapters deal almost exclusively with porcelain commands. But in this chapter, you’ll be dealing mostly with the lower-level plumbing commands, because they give you access to the inner workings of Git and help demonstrate how and why Git does what it does. These commands aren’t meant to be used manually on the command line, but rather to be used as building blocks for new tools and custom scripts. -->
32
+
33
+ Kiedy uruchomisz `git init` w nowym lub istniejącym katalogu, Git stworzy katalog `.git`, w którym praktycznie wszystko czego używa Git jest umieszczone. Kiedy chcesz wykonać kopię zapasową lub sklonować repozytorium, skopiowanie tylko tego katalogu da Ci praktycznie wszystko czego potrzebujesz. Praktycznie cały ten rozdział dotyczy rzeczy które są umieszczone w tym katalogu. Wygląda on tak:
34
+
35
+ <!-- When you run `git init` in a new or existing directory, Git creates the `.git` directory, which is where almost everything that Git stores and manipulates is located. If you want to back up or clone your repository, copying this single directory elsewhere gives you nearly everything you need. This entire chapter basically deals with the stuff in this directory. Here’s what it looks like: -->
36
+
37
+ $ ls
38
+ HEAD
39
+ branches/
40
+ config
41
+ description
42
+ hooks/
43
+ index
44
+ info/
45
+ objects/
46
+ refs/
47
+
48
+ Możesz zobaczyć tam inne pliki, ale jest to nowy katalog zainicjowany przez `git init` - standardowo właśnie to widzisz. Katalog `branches` nie jest używany przez nowsze wersje Gita, a plik `description` jest używany tylko przez program GitWeb, więc nie zwracaj na nie uwagi na razie. Plik `config` zawiera ustawienia konfiguracyjne dotyczące danego projektu, a katalog `info` przechowuje globalny plik wykluczeń, który przechowuje ignorowane wzorce których nie chcesz mieć w pliku .gitignore. Katalog `hooks` zawiera komendy uruchamiane po stronie klienta lub serwera, które były omawiane w rozdziale 7.
49
+
50
+ <!-- You may see some other files in there, but this is a fresh `git init` repository — it’s what you see by default. The `branches` directory isn’t used by newer Git versions, and the `description` file is only used by the GitWeb program, so don’t worry about those. The `config` file contains your project-specific configuration options, and the `info` directory keeps a global exclude file for ignored patterns that you don’t want to track in a .gitignore file. The `hooks` directory contains your client- or server-side hook scripts, which are discussed in detail in Chapter 7. -->
51
+
52
+ Pozostały bardzo istotne wpisy: pliki `HEAD` i `index`, oraz katalogi `objects` i `refs`. Są one podstawowymi częściami Gita. Katalog `objects` przechowuje całą zawartość bazy danych, katalog `refs` przechowuje wskaźniki do obiektów commitów w danych (branches), plik `HEAD` wskazuje gałąź na której się znajdujesz, a plik `index` jest miejscem w którym przechowywane są informacje na temat przechowalni. W kolejnych częściach tego rozdziału dokładnie zobaczysz jak Git funkcjonuje.
53
+
54
+ <!-- This leaves four important entries: the `HEAD` and `index` files and the `objects` and `refs` directories. These are the core parts of Git. The `objects` directory stores all the content for your database, the `refs` directory stores pointers into commit objects in that data (branches), the `HEAD` file points to the branch you currently have checked out, and the `index` file is where Git stores your staging area information. You’ll now look at each of these sections in detail to see how Git operates. -->
55
+
56
+
57
+ ## Obiekty Gita ##
58
+
59
+ <!-- ## Git Objects ## -->
60
+
61
+ Git to tak naprawdę system plików zorientowany na treść. Super. Ale co to oznacza?
62
+ Oznacza to, że Git u podstaw, to baza danych w której znajdują się dane i przypisane do nich klucze (ang. key-value datastore). Możesz zapisać w niej każdy rodzaj danych, a w odpowiedzi otrzymasz klucz, dzięki któremu będziesz mógł dostać się do tych danych w każdej chwili. Aby zademonstrować jak to działa, możesz użyć komendy `hash-object`, która pobiera jakieś dane, zapisuje je w katalogu `.git` i zwraca klucz pod którym te dane zostały zapisane. Najpierw zainicjujesz nowe repozytorium Gita i sprawdzisz, że katalog `objects` jest pusty:
63
+
64
+ <!-- Git is a content-addressable filesystem. Great. What does that mean?
65
+ It means that at the core of Git is a simple key-value data store. You can insert any kind of content into it, and it will give you back a key that you can use to retrieve the content again at any time. To demonstrate, you can use the plumbing command `hash-object`, which takes some data, stores it in your `.git` directory, and gives you back the key the data is stored as. First, you initialize a new Git repository and verify that there is nothing in the `objects` directory: -->
66
+
67
+ $ mkdir test
68
+ $ cd test
69
+ $ git init
70
+ Initialized empty Git repository in /tmp/test/.git/
71
+ $ find .git/objects
72
+ .git/objects
73
+ .git/objects/info
74
+ .git/objects/pack
75
+ $ find .git/objects -type f
76
+ $
77
+
78
+ Git zainicjował katalog `objects` oraz stworzył w nim dwa katalogi `pack` i `info`, jednak nie ma w nich żadnych plików. Teraz zapisz jakieś dane w bazie danych Gita:
79
+
80
+ <!-- Git has initialized the `objects` directory and created `pack` and `info` subdirectories in it, but there are no regular files. Now, store some text in your Git database: -->
81
+
82
+ $ echo 'test content' | git hash-object -w --stdin
83
+ d670460b4b4aece5915caf5c68d12f560a9fe3e4
84
+
85
+ Opcja `-w` wskazuje komendzie `hash-object` aby zapisała obiekt, w przeciwnym wypadku pokazała by tylko jaki klucz byłby użyty. Opcja `--stdin` wskazuje, aby dane zostały odczytane ze standardowego wejścia; jeżeli nie podasz tej opcji, `hash-object` będzie wymagał podania ścieżki do pliku. Wynikiem działania tej komendy jest 40 znakowa suma kontrolna. Jest to skrót SHA-1 - suma kontrolna zawartości którą zapisujesz, oraz nagłówków, o których dowiesz się za chwilę. Teraz możesz zobaczyć w jaki sposób Git zachował dane:
86
+
87
+ <!-- The `-w` tells `hash-object` to store the object; otherwise, the command simply tells you what the key would be. `-\-stdin` tells the command to read the content from stdin; if you don’t specify this, `hash-object` expects the path to a file. The output from the command is a 40-character checksum hash. This is the SHA-1 hash — a checksum of the content you’re storing plus a header, which you’ll learn about in a bit. Now you can see how Git has stored your data: -->
88
+
89
+ $ find .git/objects -type f
90
+ .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
91
+
92
+ Możesz zobaczyć nowy plik w katalogu `objects`. W ten sposób Git początkowo zapisuje dane - jako pojedynczy plik dla każdej części danych, nazwany tak jak wyliczony skrót SHA-1 z treści danych i nagłówka. Podkatalog jest nazwany od 2 pierwszych znaków SHA, a nazwa pliku to pozostałe 38 znaków.
93
+
94
+ <!-- You can see a file in the `objects` directory. This is how Git stores the content initially — as a single file per piece of content, named with the SHA-1 checksum of the content and its header. The subdirectory is named with the first 2 characters of the SHA, and the filename is the remaining 38 characters. -->
95
+
96
+ Możesz pobrać dane z Gita za pomocą komendy `cat-file`. Polecenie to, to coś w rodzaju szwajcarskiego scyzoryka dla inspekcji obiektów Gita. Przekazanie opcji `-p` mówi `cat-file`, aby rozpoznała ona rodzaj przechowywanych danych i wypisała je na ekran:
97
+
98
+ <!-- You can pull the content back out of Git with the `cat-file` command. This command is sort of a Swiss army knife for inspecting Git objects. Passing `-p` to it instructs the `cat-file` command to figure out the type of content and display it nicely for you: -->
99
+
100
+ $ git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4
101
+ test content
102
+
103
+ Teraz, możesz dodać dane do Gita i pobrać je z powrotem. Możesz również to zrobić z danymi znajdującymi się w plikach. Dla przykładu, dodajmy plik do systemu kontroli wersji. Najpierw stwórzmy nowy plik i zapiszmy jego zawartość w bazie danych:
104
+
105
+ <!-- Now, you can add content to Git and pull it back out again. You can also do this with content in files. For example, you can do some simple version control on a file. First, create a new file and save its contents in your database: -->
106
+
107
+ $ echo 'version 1' > test.txt
108
+ $ git hash-object -w test.txt
109
+ 83baae61804e65cc73a7201a7252750c76066a30
110
+
111
+ Następnie wprowadź nowe dane do tego pliku i zapisz ponownie:
112
+
113
+ <!-- Then, write some new content to the file, and save it again: -->
114
+
115
+ $ echo 'version 2' > test.txt
116
+ $ git hash-object -w test.txt
117
+ 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a
118
+
119
+ Twoja baza danych zawiera teraz dwie nowe wersje pliku, jak również początkową jego zawartość którą zapisałeś:
120
+
121
+ <!-- Your database contains the two new versions of the file as well as the first content you stored there: -->
122
+
123
+ $ find .git/objects -type f
124
+ .git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a
125
+ .git/objects/83/baae61804e65cc73a7201a7252750c76066a30
126
+ .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
127
+
128
+ Teraz możesz cofnąć zawartość pliku do pierwszej wersji:
129
+
130
+ <!-- Now you can revert the file back to the first version -->
131
+
132
+ $ git cat-file -p 83baae61804e65cc73a7201a7252750c76066a30 > test.txt
133
+ $ cat test.txt
134
+ version 1
135
+
136
+ lub drugiej:
137
+
138
+ <!-- or the second version: -->
139
+
140
+ $ git cat-file -p 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a > test.txt
141
+ $ cat test.txt
142
+ version 2
143
+
144
+ Ale zapamiętywanie kluczy SHA-1 dla każdej wersji nie jest praktyczne; dodatkowo nie zachowujesz nazwy pliku - tylko treść. Ten rodzaj obiektu nazywa się "blob". Możesz uzyskać informacje o tym jaki typ obiektu kryje się pod danym skrótem SHA-1 za pomocą `cat-file -t`:
145
+
146
+ <!-- But remembering the SHA-1 key for each version of your file isn’t practical; plus, you aren’t storing the filename in your system — just the content. This object type is called a blob. You can have Git tell you the object type of any object in Git, given its SHA-1 key, with `cat-file -t`: -->
147
+
148
+ $ git cat-file -t 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a
149
+ blob
150
+
151
+ ### Obiekty drzew ###
152
+
153
+ <!-- ### Tree Objects ### -->
154
+
155
+ Następnym typem obiektów który poznasz są obiekty drzew (ang. tree), które rozwiązują problem przechowywania nazw plików oraz pozwalają na przechowywanie grupy plików razem. Git przechowuje treść w sposób podobny do systemu plików UNIX, lecz z pewnymi uproszczeniami. Wszystkie dane przechowywane są jako obiekty tree i blob, obiektami tree odpowiadającymi strukturze katalogów w systemie UNIX, oraz obiektami blob, które w mniejszym lub większym stopniu odpowiadają inodom lub treści plików. Pojedynczy obiekt tree zawiera jeden lub więcej wpisów dotyczących ścieżki, z których każdy zawiera skrót SHA-1 wskazujący na obiekt blob lub poddrzewem (ang. subtree) z przypisanym trybem, typem i nazwą pliku. Na przykład, najnowsze drzewo w projekcie simplegit może wygląda tak:
156
+
157
+ <!-- The next type you’ll look at is the tree object, which solves the problem of storing the filename and also allows you to store a group of files together. Git stores content in a manner similar to a UNIX filesystem, but a bit simplified. All the content is stored as tree and blob objects, with trees corresponding to UNIX directory entries and blobs corresponding more or less to inodes or file contents. A single tree object contains one or more tree entries, each of which contains a SHA-1 pointer to a blob or subtree with its associated mode, type, and filename. For example, the most recent tree in the simplegit project may look something like this: -->
158
+
159
+ $ git cat-file -p master^{tree}
160
+ 100644 blob a906cb2a4a904a152e80877d4088654daad0c859 README
161
+ 100644 blob 8f94139338f9404f26296befa88755fc2598c289 Rakefile
162
+ 040000 tree 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0 lib
163
+
164
+ Składnia `master^{tree}` wskazuje na obiekt tree na który wskazuje ostatni commit w Twojej gałęzi `master`. Zauważ, że podkatalog `lib` nie jest blobem, ale wskaźnikiem na inny obiekt tree.
165
+
166
+ <!-- The `master^{tree}` syntax specifies the tree object that is pointed to by the last commit on your `master` branch. Notice that the `lib` subdirectory isn’t a blob but a pointer to another tree: -->
167
+
168
+ $ git cat-file -p 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0
169
+ 100644 blob 47c6340d6459e05787f644c2447d2595f5d3a54b simplegit.rb
170
+
171
+ W ogólnym zarysie, dane które Git przechowuje wyglądają podobnie do tych pokazanych na rysunku 9-1.
172
+
173
+ <!-- Conceptually, the data that Git is storing is something like Figure 9-1. -->
174
+
175
+ Insert 18333fig0901.png
176
+ Rysunek 9-1. Prosty przykład modelu danych w Git.
177
+
178
+ <!-- Figure 9-1. Simple version of the Git data model. -->
179
+
180
+ Możesz stworzyć swój własny obiekt tree. Git zazwyczaj tworzy taki obiekt poprzez pobranie stanu przechowalni lub indeksu i zapisanie obiektu tree z tych danych. A więc, aby stworzyć obiekt tree, na początek musisz ustawić indeks poprzez dodanie do przechowalni plików. Indeks z jednym elementem - z pierwszą wersją Twojego pliku test.txt - możesz stworzyć używając komendy `update-index`. Możesz jej również do sztucznego dodania poprzedniej wersji pliku test.txt do przechowalni. Musisz podać jej opcje `--add` ponieważ plik nie istnieje jeszcze w przechowalni (nie masz jeszcze nawet ustawionej przechowalni) oraz `--cacheinfo` ponieważ plik który dodajesz nie istnieje w katalogu, a tylko w bazie danych. Następnie wskazujesz tryb, sumę SHA-1 oraz nazwę pliku:
181
+
182
+ <!-- You can create your own tree. Git normally creates a tree by taking the state of your staging area or index and writing a tree object from it. So, to create a tree object, you first have to set up an index by staging some files. To create an index with a single entry — the first version of your test.txt file — you can use the plumbing command `update-index`. You use this command to artificially add the earlier version of the test.txt file to a new staging area. You must pass it the `-\-add` option because the file doesn’t yet exist in your staging area (you don’t even have a staging area set up yet) and `-\-cacheinfo` because the file you’re adding isn’t in your directory but is in your database. Then, you specify the mode, SHA-1, and filename: -->
183
+
184
+ $ git update-index --add --cacheinfo 100644 \
185
+ 83baae61804e65cc73a7201a7252750c76066a30 test.txt
186
+
187
+ W tym przykładzie, podałeś tryb `100644`, który wskazuje na normalny plik. Inne dostępne tryby to `100755`, który wskazuje na plik wykonywalny; oraz `120000`, który wskazuje na dowiązanie symboliczne. Tryby bazują na normalnych uprawnieniach w systemie UNIX, ale mają znacznie mniej opcji - te trzy tryby są jedynymi, które mogą być stosowane do plików (blob-ów) w Gitcie (chociaż inne tryby mogą być użyte dla katalogów i podmodułów).
188
+
189
+ <!-- In this case, you’re specifying a mode of `100644`, which means it’s a normal file. Other options are `100755`, which means it’s an executable file; and `120000`, which specifies a symbolic link. The mode is taken from normal UNIX modes but is much less flexible — these three modes are the only ones that are valid for files (blobs) in Git (although other modes are used for directories and submodules). -->
190
+
191
+ Teraz, możesz użyć komendy `write-tree`, w celu zapisania zawartości przechowani do obiektu tree. Opcja `-w` nie jest potrzebna - wywołanie `write-tree` automatycznie tworzy obiekt tree ze stanu indeksu, jeżeli ten obiekt jeszcze nie istnieje.
192
+
193
+ <!-- Now, you can use the `write-tree` command to write the staging area out to a tree object. No `-w` option is needed — calling `write-tree` automatically creates a tree object from the state of the index if that tree doesn’t yet exist: -->
194
+
195
+ $ git write-tree
196
+ d8329fc1cc938780ffdd9f94e0d364e0ea74f579
197
+ $ git cat-file -p d8329fc1cc938780ffdd9f94e0d364e0ea74f579
198
+ 100644 blob 83baae61804e65cc73a7201a7252750c76066a30 test.txt
199
+
200
+ Możesz również zweryfikować, że to jest obiekt tree:
201
+
202
+ <!-- You can also verify that this is a tree object: -->
203
+
204
+ $ git cat-file -t d8329fc1cc938780ffdd9f94e0d364e0ea74f579
205
+ tree
206
+
207
+ Stworzysz teraz nowy obiekt tree, zawierający drugą wersję pliku test.txt oraz nowy plik:
208
+
209
+ <!-- You’ll now create a new tree with the second version of test.txt and a new file as well: -->
210
+
211
+ $ echo 'new file' > new.txt
212
+ $ git update-index test.txt
213
+ $ git update-index --add new.txt
214
+
215
+
216
+ W Twojej przechowalni znajduje się teraz nowa wersja pliku test.txt oraz nowy plik new.txt. Zapisz ten stan (pobierając stan z przechowalni lub indeksu do obiektu tree) i sprawdź jak on teraz wygląda:
217
+
218
+ <!-- Your staging area now has the new version of test.txt as well as the new file new.txt. Write out that tree (recording the state of the staging area or index to a tree object) and see what it looks like: -->
219
+
220
+ $ git write-tree
221
+ 0155eb4229851634a0f03eb265b69f5a2d56f341
222
+ $ git cat-file -p 0155eb4229851634a0f03eb265b69f5a2d56f341
223
+ 100644 blob fa49b077972391ad58037050f2a75f74e3671e92 new.txt
224
+ 100644 blob 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a test.txt
225
+
226
+ Zauważ, że to drzewo posiada oba wpisy dotyczące plików, oraz że suma SHA w pliku test.txt jest sumą przypisaną do "wersji 2" (`1f7a7a`). Dla zabawy, dodasz pierwszy obiekt tree jako podkatalog w obecnym. Możesz wczytać obiekt tree do swojej przechowalni poprzez wywołanie `read-tree`. W takim wypadku, możesz wczytać obecne drzewo do swojej przechowalni i umieścić je w podkatalogu za pomocą opcji `--prefix` dodanej do `read-tree`:
227
+
228
+ <!-- Notice that this tree has both file entries and also that the test.txt SHA is the "version 2" SHA from earlier (`1f7a7a`). Just for fun, you’ll add the first tree as a subdirectory into this one. You can read trees into your staging area by calling `read-tree`. In this case, you can read an existing tree into your staging area as a subtree by using the `-\-prefix` option to `read-tree`: -->
229
+
230
+ $ git read-tree --prefix=bak d8329fc1cc938780ffdd9f94e0d364e0ea74f579
231
+ $ git write-tree
232
+ 3c4e9cd789d88d8d89c1073707c3585e41b0e614
233
+ $ git cat-file -p 3c4e9cd789d88d8d89c1073707c3585e41b0e614
234
+ 040000 tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579 bak
235
+ 100644 blob fa49b077972391ad58037050f2a75f74e3671e92 new.txt
236
+ 100644 blob 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a test.txt
237
+
238
+ Jeżeli odtworzyłeś katalog roboczy z drzewa które właśnie zapisałeś, otrzymałeś dwa pliki na najwyższym poziomie w tym katalogu, oraz podkatalog `bak`, który zawiera pierwszą wersję pliku test.txt. Możesz myśleć o danych przechowywanych w Gitcie z tymi strukturami, tak jak przedstawiono na rysunku 9-2.
239
+
240
+ <!-- If you created a working directory from the new tree you just wrote, you would get the two files in the top level of the working directory and a subdirectory named `bak` that contained the first version of the test.txt file. You can think of the data that Git contains for these structures as being like Figure 9-2. -->
241
+
242
+ Insert 18333fig0902.png
243
+ Rysunek 9-2. Zawartość struktury obecnych danych Git.
244
+
245
+ <!-- Figure 9-2. The content structure of your current Git data. -->
246
+
247
+ ### Obiekty Commit ###
248
+
249
+ <!-- ### Commit Objects ### -->
250
+
251
+ Masz teraz trzy obiekty tree, które wskazują na różne migawki śledzonego projektu, ale poprzedni problem pozostał: musisz pamiętasz wszystkie trzy wartości SHA-1 aby przywrócić migawkę. Nie masz również żadnych informacji o tym kto zapisał migawkę, kiedy była zapisana, ani dlaczego. To są podstawowe informacje, które przechowywane są w obiektach typu commit.
252
+
253
+ <!-- You have three trees that specify the different snapshots of your project that you want to track, but the earlier problem remains: you must remember all three SHA-1 values in order to recall the snapshots. You also don’t have any information about who saved the snapshots, when they were saved, or why they were saved. This is the basic information that the commit object stores for you. -->
254
+
255
+ Aby stworzyć obiekt commit, wywołaj `commit-tree` i podaj jedną sumę SHA-1 wskazującą na obiekt tree oraz obiekty commit, o ile były jakieś, które bezpośrednio go poprzedziły.
256
+
257
+ <!-- To create a commit object, you call `commit-tree` and specify a single tree SHA-1 and which commit objects, if any, directly preceded it. Start with the first tree you wrote: -->
258
+
259
+ $ echo 'first commit' | git commit-tree d8329f
260
+ fdf4fc3344e67ab068f836878b6c4951e3b15f3d
261
+
262
+ Możesz teraz zobaczyć jak wygląda nowy obiekt commit za pomocą `cat-file`:
263
+
264
+ <!-- Now you can look at your new commit object with `cat-file`: -->
265
+
266
+ $ git cat-file -p fdf4fc3
267
+ tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579
268
+ author Scott Chacon <schacon@gmail.com> 1243040974 -0700
269
+ committer Scott Chacon <schacon@gmail.com> 1243040974 -0700
270
+
271
+ first commit
272
+
273
+ Format obiektu commit jest prosty: wskazuje on najnowszy obiekt tree dla migawki projektu w momencie tworzenia; informacje o autorze/integratorze zmiany pobrane z są ustawień konfiguracyjnych `user.name` i `user.email` wraz z obecnym znacznikiem czasu; pustą linię i potem treść komentarza do zmiany.
274
+
275
+ <!-- The format for a commit object is simple: it specifies the top-level tree for the snapshot of the project at that point; the author/committer information pulled from your `user.name` and `user.email` configuration settings, with the current timestamp; a blank line, and then the commit message. -->
276
+
277
+ Następnie, zapiszesz dwa inne obiekty commit, z których każdy odwołuje się do commit-a który był bezpośrednio przed nim:
278
+
279
+ <!-- Next, you’ll write the other two commit objects, each referencing the commit that came directly before it: -->
280
+
281
+ $ echo 'second commit' | git commit-tree 0155eb -p fdf4fc3
282
+ cac0cab538b970a37ea1e769cbbde608743bc96d
283
+ $ echo 'third commit' | git commit-tree 3c4e9c -p cac0cab
284
+ 1a410efbd13591db07496601ebc7a059dd55cfe9
285
+
286
+ Każdy z trzech obiektów commit wskazuje na jedną z trzech migawek które stworzyłeś. Co ciekawe, masz teraz prawdziwą historię w Git, którą możesz obejrzeć za pomocą komendy `git log`, jeżeli uruchomisz ją na ostatniej sumą SHA-1 obiektu commit:
287
+
288
+ <!-- Each of the three commit objects points to one of the three snapshot trees you created. Oddly enough, you have a real Git history now that you can view with the `git log` command, if you run it on the last commit SHA-1: -->
289
+
290
+ $ git log --stat 1a410e
291
+ commit 1a410efbd13591db07496601ebc7a059dd55cfe9
292
+ Author: Scott Chacon <schacon@gmail.com>
293
+ Date: Fri May 22 18:15:24 2009 -0700
294
+
295
+ third commit
296
+
297
+ bak/test.txt | 1 +
298
+ 1 files changed, 1 insertions(+), 0 deletions(-)
299
+
300
+ commit cac0cab538b970a37ea1e769cbbde608743bc96d
301
+ Author: Scott Chacon <schacon@gmail.com>
302
+ Date: Fri May 22 18:14:29 2009 -0700
303
+
304
+ second commit
305
+
306
+ new.txt | 1 +
307
+ test.txt | 2 +-
308
+ 2 files changed, 2 insertions(+), 1 deletions(-)
309
+
310
+ commit fdf4fc3344e67ab068f836878b6c4951e3b15f3d
311
+ Author: Scott Chacon <schacon@gmail.com>
312
+ Date: Fri May 22 18:09:34 2009 -0700
313
+
314
+ first commit
315
+
316
+ test.txt | 1 +
317
+ 1 files changed, 1 insertions(+), 0 deletions(-)
318
+
319
+ Niesamowite. Wykonałeś właśnie niskopoziomowe operacje i stworzyłeś historię w Git bez używania żadnej z komend użytkownika. Jest to w zasadzie to, co Git robi kiedy uruchomisz komendy `git add` oraz `git commit` - zapisuje obiekty blob dla plików które zmieniłeś, aktualizuje indeks, zapisuje obiekt tree, oraz tworzy obiekt commit odnoszący się do obiektu tree oraz obiektów commit które wystąpiły bezpośrednio przed nim. Te trzy główne obiekty Gita - blob, tree oraz commit - są na początku zapisywane jako pojedyncze pliki w katalogu `.git/objects`. Poniżej widać wszystkie obiekty z naszego przykładu, z komentarzami wskazującymi na to co było w nich zapisane:
320
+
321
+ <!-- Amazing. You’ve just done the low-level operations to build up a Git history without using any of the front ends. This is essentially what Git does when you run the `git add` and `git commit` commands — it stores blobs for the files that have changed, updates the index, writes out trees, and writes commit objects that reference the top-level trees and the commits that came immediately before them. These three main Git objects — the blob, the tree, and the commit — are initially stored as separate files in your `.git/objects` directory. Here are all the objects in the example directory now, commented with what they store: -->
322
+
323
+ $ find .git/objects -type f
324
+ .git/objects/01/55eb4229851634a0f03eb265b69f5a2d56f341 # tree 2
325
+ .git/objects/1a/410efbd13591db07496601ebc7a059dd55cfe9 # commit 3
326
+ .git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a # test.txt v2
327
+ .git/objects/3c/4e9cd789d88d8d89c1073707c3585e41b0e614 # tree 3
328
+ .git/objects/83/baae61804e65cc73a7201a7252750c76066a30 # test.txt v1
329
+ .git/objects/ca/c0cab538b970a37ea1e769cbbde608743bc96d # commit 2
330
+ .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 # 'test content'
331
+ .git/objects/d8/329fc1cc938780ffdd9f94e0d364e0ea74f579 # tree 1
332
+ .git/objects/fa/49b077972391ad58037050f2a75f74e3671e92 # new.txt
333
+ .git/objects/fd/f4fc3344e67ab068f836878b6c4951e3b15f3d # commit 1
334
+
335
+ Jeżeli prześledzisz wszystkie wskaźniki, dostaniesz widok obiektów podobny do rysunku 9-3.
336
+
337
+ <!-- If you follow all the internal pointers, you get an object graph something like Figure 9-3. -->
338
+
339
+ Insert 18333fig0903.png
340
+ Rysunek 9-3. Wszystkie obiekty w Twoim repozytorium Gita.
341
+
342
+ <!-- Figure 9-3. All the objects in your Git directory. -->
343
+
344
+ ### Zapisywanie obiektów ###
345
+
346
+ <!-- ### Object Storage ### -->
347
+
348
+ Wcześniej wspomniałem, że nagłówek jest zapisywanie wraz z treścią. Spójrzmy przez chwilę w jaki sposób Git zapisuje swoje obiekty. Zobaczysz jak zapisać obiekt blob - na przykładzie treści "what is up, doc?" - interaktywnie w języku skryptowym Ruby. Możesz uruchomić tryb interaktywny w Ruby, za pomocą komendy `irb`:
349
+
350
+ <!-- I mentioned earlier that a header is stored with the content. Let’s take a minute to look at how Git stores its objects. You’ll see how to store a blob object — in this case, the string "what is up, doc?" — interactively in the Ruby scripting language. You can start up interactive Ruby mode with the `irb` command: -->
351
+
352
+ $ irb
353
+ >> content = "what is up, doc?"
354
+ => "what is up, doc?"
355
+
356
+ Git tworząc nagłówek na początku wskazuje jakiego typu jest obiekt, w tym wypadku blob. Następnie, dodaje spację i wielkość treści, oraz na końcu znak null:
357
+
358
+ <!-- Git constructs a header that starts with the type of the object, in this case a blob. Then, it adds a space followed by the size of the content and finally a null byte: -->
359
+
360
+ >> header = "blob #{content.length}\0"
361
+ => "blob 16\000"
362
+
363
+ Git łączy nagłówek z treścią, a potem oblicza sumę SHA-1 całości. Możesz obliczyć sumę SHA-1 dla treści w Ruby, po włączeniu biblioteki "SHA1 digest" za pomocą komendy `require`, oraz po wywołaniu `Digest::SHA1.hexdigest()` na nim:
364
+
365
+ <!-- Git concatenates the header and the original content and then calculates the SHA-1 checksum of that new content. You can calculate the SHA-1 value of a string in Ruby by including the SHA1 digest library with the `require` command and then calling `Digest::SHA1.hexdigest()` with the string: -->
366
+
367
+ >> store = header + content
368
+ => "blob 16\000what is up, doc?"
369
+ >> require 'digest/sha1'
370
+ => true
371
+ >> sha1 = Digest::SHA1.hexdigest(store)
372
+ => "bd9dbf5aae1a3862dd1526723246b20206e5fc37"
373
+
374
+ Git kompresuje nową treść za pomocą zlib, co możesz wykonać w Ruby przy użyciu biblioteki zlib. Najpierw, musisz dodać wpis `require`, a potem uruchomić na treści `Zlib::Deflate.deflate()`:
375
+
376
+ <!-- Git compresses the new content with zlib, which you can do in Ruby with the zlib library. First, you need to require the library and then run `Zlib::Deflate.deflate()` on the content: -->
377
+
378
+ >> require 'zlib'
379
+ => true
380
+ >> zlib_content = Zlib::Deflate.deflate(store)
381
+ => "x\234K\312\311OR04c(\317H,Q\310,V(-\320QH\311O\266\a\000_\034\a\235"
382
+
383
+ Na koniec, zapiszesz spakowaną treść jako obiektu na dysku. Ustalisz ścieżkę dla obiektu który zapisujesz (pierwsze dwa znaki z sumy SHA-1 są nazwą podkatalogu, a pozostałe 38 znaków są nazwą pliku w tym katalogu). W Ruby możesz użyć funkcji `FileUtils.mkdir_p()`, aby stworzyć podkatalog w przypadku gdy on nie istnieje. Następnie otwórz plik za pomocą `File.open()` i zapisz otrzymaną skompresowaną zawartość do pliku za pomocą funkcji `write()` wywołanej na otrzymanym uchwycie pliku:
384
+
385
+ <!-- Finally, you’ll write your zlib-deflated content to an object on disk. You’ll determine the path of the object you want to write out (the first two characters of the SHA-1 value being the subdirectory name, and the last 38 characters being the filename within that directory). In Ruby, you can use the `FileUtils.mkdir_p()` function to create the subdirectory if it doesn’t exist. Then, open the file with `File.open()` and write out the previously zlib-compressed content to the file with a `write()` call on the resulting file handle: -->
386
+
387
+ >> path = '.git/objects/' + sha1[0,2] + '/' + sha1[2,38]
388
+ => ".git/objects/bd/9dbf5aae1a3862dd1526723246b20206e5fc37"
389
+ >> require 'fileutils'
390
+ => true
391
+ >> FileUtils.mkdir_p(File.dirname(path))
392
+ => ".git/objects/bd"
393
+ >> File.open(path, 'w') { |f| f.write zlib_content }
394
+ => 32
395
+
396
+ To tyle - stworzyłeś poprawny obiekt blog w Gitcie. Wszystkie obiekty w Git przechowywane są w taki sam sposób, tylko z innymi typami - zamiast ciągu znaków blob, nagłówek będzie rozpoczynał się od commit lub tree. Choć obiekt blob może zawierać praktycznie dowolne dane, to jednak obiekty commit i tree są bardzo specyficznie sformatowane.
397
+
398
+ <!-- That’s it — you’ve created a valid Git blob object. All Git objects are stored the same way, just with different types — instead of the string blob, the header will begin with commit or tree. Also, although the blob content can be nearly anything, the commit and tree content are very specifically formatted. -->
399
+
400
+ ## Referencje w Git ##
401
+
402
+ <!-- ## Git References ## -->
403
+
404
+ Za pomocą komendy `git log 1a410e` możesz również przejrzeć całą historię swojego projektu, ale musisz wiedzieć, że `1a410e` jest ostatnią zmianą (commitem) aby zobaczyć wszystkie modyfikacje. Potrzebujesz pliku w którym będziesz mógł zapisywać wartość SHA-1 pod łatwiejszą nazwą, tak abyś mógł jej używać zamiast sumy SHA-1.
405
+
406
+ <!-- You can run something like `git log 1a410e` to look through your whole history, but you still have to remember that `1a410e` is the last commit in order to walk that history to find all those objects. You need a file in which you can store the SHA-1 value under a simple name so you can use that pointer rather than the raw SHA-1 value. -->
407
+
408
+ W Gitcie nazywane są one "referencjami" lub krócej "refs"; możesz znaleźć pliki zawierające wartość SHA-1 w katalogu `.git/refs`. W obecnym projekcie ten katalog nie zawiera żadnych plików, a jego struktura wygląda tak:
409
+
410
+ <!-- In Git, these are called "references" or "refs"; you can find the files that contain the SHA-1 values in the `.git/refs` directory. In the current project, this directory contains no files, but it does contain a simple structure: -->
411
+
412
+ $ find .git/refs
413
+ .git/refs
414
+ .git/refs/heads
415
+ .git/refs/tags
416
+ $ find .git/refs -type f
417
+ $
418
+
419
+ Aby stworzyć nową referencję, która pomocna będzie przy zapamiętywaniu który commit jest ostatni, możesz wykonać tę prostą komendę:
420
+
421
+ <!-- To create a new reference that will help you remember where your latest commit is, you can technically do something as simple as this: -->
422
+
423
+ $ echo "1a410efbd13591db07496601ebc7a059dd55cfe9" > .git/refs/heads/master
424
+
425
+ Teraz, możesz używać referencji którą właśnie stworzyłeś zamiast sumy SHA-1 w komendach Gita:
426
+
427
+ <!-- Now, you can use the head reference you just created instead of the SHA-1 value in your Git commands: -->
428
+
429
+ $ git log --pretty=oneline master
430
+ 1a410efbd13591db07496601ebc7a059dd55cfe9 third commit
431
+ cac0cab538b970a37ea1e769cbbde608743bc96d second commit
432
+ fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit
433
+
434
+ Nie musisz bezpośrednio zmieniać plików referencji. Git udostępnia bezpieczniejsze narzędzie do tego, gdy chcesz zaktualizować referencje wywołaj `update-ref`:
435
+
436
+ <!-- You aren’t encouraged to directly edit the reference files. Git provides a safer command to do this if you want to update a reference called `update-ref`: -->
437
+
438
+ $ git update-ref refs/heads/master 1a410efbd13591db07496601ebc7a059dd55cfe9
439
+
440
+ Praktycznie tym samym są gałęzie w Git: proste wskazanie lub referencja na najnowszą wprowadzoną zmianę. Aby stworzyć gałąź z poprzedniego commita, wykonaj to:
441
+
442
+ <!-- That’s basically what a branch in Git is: a simple pointer or reference to the head of a line of work. To create a branch back at the second commit, you can do this: -->
443
+
444
+ $ git update-ref refs/heads/test cac0ca
445
+
446
+ Twoja gałąź będzie zawierała tylko zmiany starsze niż podany commit:
447
+
448
+ <!-- Your branch will contain only work from that commit down: -->
449
+
450
+ $ git log --pretty=oneline test
451
+ cac0cab538b970a37ea1e769cbbde608743bc96d second commit
452
+ fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit
453
+
454
+ W tej chwili, Twoja baza w Git wygląda podobnie do tej z rysunka 9-4.
455
+
456
+ <!-- Now, your Git database conceptually looks something like Figure 9-4. -->
457
+
458
+ Insert 18333fig0904.png
459
+ Rysunek 9-4. Obiekty w katalogach Git z uwzględnieniem referencji do gałęzi.
460
+
461
+ <!-- Figure 9-4. Git directory objects with branch head references included. -->
462
+
463
+ Gdy uruchamiasz komendę taką jak `git branch (nazwagałęzi)`, Git po prostu uruchamia komendę `update-ref`, w celu dodania sumy SHA-1 ostatniego commita w gałęzi na której się obecnie znajdujesz, do referencji którą chcesz stworzyć.
464
+
465
+ <!-- When you run commands like `git branch (branchname)`, Git basically runs that `update-ref` command to add the SHA-1 of the last commit of the branch you’re on into whatever new reference you want to create. -->
466
+
467
+ ### HEAD ###
468
+
469
+ <!-- ### The HEAD ### -->
470
+
471
+ Powstaje pytanie, po uruchomieniu `git branch (nazwagałęzi)`, skąd Git wie jaka jest suma SHA-1 ostatniego commita? Odpowiedź to plik HEAD. W tym pliku znajduje się symboliczne dowiązanie do gałęzi w której się obecnie znajdujesz. Poprzez symboliczne dowiązanie, mam na myśli to, że inaczej niż w przypadku normalnego dowiązania, nie zawiera ono sumy SHA-1, ale wskaźnik na inną referencję. Jak zobaczysz na zawartość tego pliku, zazwyczaj zobaczysz coś w stylu:
472
+
473
+ <!-- The question now is, when you run `git branch (branchname)`, how does Git know the SHA-1 of the last commit? The answer is the HEAD file. The HEAD file is a symbolic reference to the branch you’re currently on. By symbolic reference, I mean that unlike a normal reference, it doesn’t generally contain a SHA-1 value but rather a pointer to another reference. If you look at the file, you’ll normally see something like this: -->
474
+
475
+ $ cat .git/HEAD
476
+ ref: refs/heads/master
477
+
478
+ Po uruchomieniu `git checkout test`, Git zaktualizuje ten plik, aby zawierał:
479
+
480
+ <!-- If you run `git checkout test`, Git updates the file to look like this: -->
481
+
482
+ $ cat .git/HEAD
483
+ ref: refs/heads/test
484
+
485
+ Gdy uruchomisz `git commit`, zostanie stworzony obiekt commit, określając rodzica tego obiektu na podstawie wartość SHA-1 na którą wskazuje HEAD.
486
+
487
+ <!-- When you run `git commit`, it creates the commit object, specifying the parent of that commit object to be whatever SHA-1 value the reference in HEAD points to. -->
488
+
489
+ Możesz również ręcznie zmodyfikować ten plik, ale bezpieczniej będzie użyć komendy `symbilic-ref`. Możesz odczytać wartość która jest w HEAD przy jej pomocy:
490
+
491
+ <!-- You can also manually edit this file, but again a safer command exists to do so: `symbolic-ref`. You can read the value of your HEAD via this command: -->
492
+
493
+ $ git symbolic-ref HEAD
494
+ refs/heads/master
495
+
496
+ Możesz również ustawić nową wartość HEAD:
497
+
498
+ <!-- You can also set the value of HEAD: -->
499
+
500
+ $ git symbolic-ref HEAD refs/heads/test
501
+ $ cat .git/HEAD
502
+ ref: refs/heads/test
503
+
504
+ Nie możesz jednak wstawić symbolicznego dowiązania które jest poza katalogiem refs:
505
+
506
+ <!-- You can’t set a symbolic reference outside of the refs style: -->
507
+
508
+ $ git symbolic-ref HEAD test
509
+ fatal: Refusing to point HEAD outside of refs/
510
+
511
+ ### Tagi ###
512
+
513
+ <!-- ### Tags ### -->
514
+
515
+ Poznałeś już trzy główne obiekty Gita, ale istnieje jeszcze czwarty. Obiekt tag, jest bardzo podobny do obiektu commit - zawiera informacje o osobie, dacie, treści komentarza i wskaźnik. Główną różnicą jest to, że obiekt tag wskazuje na commit, a nie na obiekt tree. Jest podobny do referencji gałęzi, ale nigdy się nie zmienia - zawsze wskazuje na ten sam commit, ale z łatwiejszą nazwą.
516
+
517
+ <!-- You’ve just gone over Git’s three main object types, but there is a fourth. The tag object is very much like a commit object — it contains a tagger, a date, a message, and a pointer. The main difference is that a tag object points to a commit rather than a tree. It’s like a branch reference, but it never moves — it always points to the same commit but gives it a friendlier name. -->
518
+
519
+ Jak opisałem w rozdziale 2, istnieją dwa typy tagów: opisanych i lekkich. Możesz stworzyć lekką etykietę poprzez uruchomienie:
520
+
521
+ <!-- As discussed in Chapter 2, there are two types of tags: annotated and lightweight. You can make a lightweight tag by running something like this: -->
522
+
523
+ $ git update-ref refs/tags/v1.0 cac0cab538b970a37ea1e769cbbde608743bc96d
524
+
525
+ Właśnie tym jest lekka etykieta - gałęzią która nigdy się nie zmienia. Opisana etykieta jest jednak bardziej skomplikowana. Gdy tworzysz opisaną etykietę, Git stworzy obiekt tag, a następnie zapisze referencję wskazująca na niego, zamiast na obiekt commit. Możesz to zauważyć, po stworzeniu opisanej etykiety (`-a` wskazuje że będzie to opisana etykieta):
526
+
527
+ <!-- That is all a lightweight tag is — a branch that never moves. An annotated tag is more complex, however. If you create an annotated tag, Git creates a tag object and then writes a reference to point to it rather than directly to the commit. You can see this by creating an annotated tag (`-a` specifies that it’s an annotated tag): -->
528
+
529
+ $ git tag -a v1.1 1a410efbd13591db07496601ebc7a059dd55cfe9 -m 'test tag'
530
+
531
+ Stworzona została następująca wartość SHA-1:
532
+
533
+ <!-- Here’s the object SHA-1 value it created: -->
534
+
535
+ $ cat .git/refs/tags/v1.1
536
+ 9585191f37f7b0fb9444f35a9bf50de191beadc2
537
+
538
+ Teraz, uruchom komendę `cat-file` na tej wartość SHA-1:
539
+
540
+ <!-- Now, run the `cat-file` command on that SHA-1 value: -->
541
+
542
+ $ git cat-file -p 9585191f37f7b0fb9444f35a9bf50de191beadc2
543
+ object 1a410efbd13591db07496601ebc7a059dd55cfe9
544
+ type commit
545
+ tag v1.1
546
+ tagger Scott Chacon <schacon@gmail.com> Sat May 23 16:48:58 2009 -0700
547
+
548
+ test tag
549
+
550
+ Zauważ, że wpis rozpoczynający się od "object" wskazuje na sumą SHA-1 commitu który zatagowałeś. Zauważ również, że nie musi on wskazywać na commit; możesz stworzyć etykietę dla każdego obiektu w Git. Na przykład, w kodzie źródłowym Gita, opiekun projektu zamieścił publiczny klucz GPG, jako obiekt blob i następnie go otagował. Możesz zobaczyć zawartość tego klucz, po wykonaniu
551
+
552
+ <!-- Notice that the object entry points to the commit SHA-1 value that you tagged. Also notice that it doesn’t need to point to a commit; you can tag any Git object. In the Git source code, for example, the maintainer has added their GPG public key as a blob object and then tagged it. You can view the public key by running -->
553
+
554
+ $ git cat-file blob junio-gpg-pub
555
+
556
+ w kodzie źródłowym Gita. Repozytorium ze źródłami projektu Linux ma również taki tag - pierwszy tag stworzony z początkowego stanu kodu źródłowego.
557
+
558
+ <!-- in the Git source code repository. The Linux kernel repository also has a non-commit-pointing tag object — the first tag created points to the initial tree of the import of the source code. -->
559
+
560
+ ### Zdalne repozytoria ###
561
+
562
+ <!-- ### Remotes ### -->
563
+
564
+ Trzecim typem referencji który poznasz, są referencje zdalne. Jeżeli dodasz zdalne repozytorium i wypchniesz do niego kod, Git przechowa wartość którą ostatnio wypchnąłeś do niego, dla każdej gałęzi w katalogu `refs/remotes`. Na przykład, możesz dodać zdalne repozytorium o nazwie `origin` i wypchnąć gałąź `master` do niego:
565
+
566
+ <!-- The third type of reference that you’ll see is a remote reference. If you add a remote and push to it, Git stores the value you last pushed to that remote for each branch in the `refs/remotes` directory. For instance, you can add a remote called `origin` and push your `master` branch to it: -->
567
+
568
+ $ git remote add origin git@github.com:schacon/simplegit-progit.git
569
+ $ git push origin master
570
+ Counting objects: 11, done.
571
+ Compressing objects: 100% (5/5), done.
572
+ Writing objects: 100% (7/7), 716 bytes, done.
573
+ Total 7 (delta 2), reused 4 (delta 1)
574
+ To git@github.com:schacon/simplegit-progit.git
575
+ a11bef0..ca82a6d master -> master
576
+
577
+ Następnie możesz zobaczyć w którym miejscu była gałąź `master` na zdalnym repozytorium `origin` w czasie gdy wysyłałeś zmiany, przez sprawdzenie pliku `refs/remotes/origin/master`:
578
+
579
+ <!-- Then, you can see what the `master` branch on the `origin` remote was the last time you communicated with the server, by checking the `refs/remotes/origin/master` file: -->
580
+
581
+ $ cat .git/refs/remotes/origin/master
582
+ ca82a6dff817ec66f44342007202690a93763949
583
+
584
+ Zdalne referencje różnią się od gałęzi (referencji w `refs/heads`) głównie tym, że nie mogą być pobrane (przez komendę "checkout"). Git zapisuje jest rodzaj zakładek wskazujących na ostatni znany stan w którym te gałęzi były na serwerze.
585
+
586
+ <!-- Remote references differ from branches (`refs/heads` references) mainly in that they can’t be checked out. Git moves them around as bookmarks to the last known state of where those branches were on those servers. -->
587
+
588
+
589
+
590
+ ## Spakowane pliki (packfiles) ##
591
+
592
+ <!-- ## Packfiles ## -->
593
+
594
+ Spójrzmy na obiekty które znajdują się w testowym repozytorium Gita. W tej chwili, masz 11 obiektów - 4 blob, 3 tree, 3 commit i 1 tag.
595
+
596
+ <!-- Let’s go back to the objects database for your test Git repository. At this point, you have 11 objects — 4 blobs, 3 trees, 3 commits, and 1 tag: -->
597
+
598
+ $ find .git/objects -type f
599
+ .git/objects/01/55eb4229851634a0f03eb265b69f5a2d56f341 # tree 2
600
+ .git/objects/1a/410efbd13591db07496601ebc7a059dd55cfe9 # commit 3
601
+ .git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a # test.txt v2
602
+ .git/objects/3c/4e9cd789d88d8d89c1073707c3585e41b0e614 # tree 3
603
+ .git/objects/83/baae61804e65cc73a7201a7252750c76066a30 # test.txt v1
604
+ .git/objects/95/85191f37f7b0fb9444f35a9bf50de191beadc2 # tag
605
+ .git/objects/ca/c0cab538b970a37ea1e769cbbde608743bc96d # commit 2
606
+ .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 # 'test content'
607
+ .git/objects/d8/329fc1cc938780ffdd9f94e0d364e0ea74f579 # tree 1
608
+ .git/objects/fa/49b077972391ad58037050f2a75f74e3671e92 # new.txt
609
+ .git/objects/fd/f4fc3344e67ab068f836878b6c4951e3b15f3d # commit 1
610
+
611
+ Git kompresuje zawartość tych plików za pomocą biblioteki zlib, a Ty nie masz dużej ilości danych, więc te pliki łącznie zajmują tylko 925 bajtów. Dodajmy trochę większych plików do repozytorium, aby pokazać bardzo ciekawą funkcję Gita. Dodaj plik repo.rb z biblioteki Grit na której wcześniej pracowaliśmy - ma on około 12 tysięcy znaków:
612
+
613
+ <!-- Git compresses the contents of these files with zlib, and you’re not storing much, so all these files collectively take up only 925 bytes. You’ll add some larger content to the repository to demonstrate an interesting feature of Git. Add the repo.rb file from the Grit library you worked with earlier — this is about a 12K source code file: -->
614
+
615
+ $ curl -L https://raw.github.com/mojombo/grit/master/lib/grit/repo.rb > repo.rb
616
+ $ git add repo.rb
617
+ $ git commit -m 'added repo.rb'
618
+ [master 484a592] added repo.rb
619
+ 3 files changed, 459 insertions(+), 2 deletions(-)
620
+ delete mode 100644 bak/test.txt
621
+ create mode 100644 repo.rb
622
+ rewrite test.txt (100%)
623
+
624
+ Jak spojrzysz na wynikowe drzewo, zobaczysz jaką sumę SHA-1 plik repo.rb otrzymał:
625
+
626
+ <!-- If you look at the resulting tree, you can see the SHA-1 value your repo.rb file got for the blob object: -->
627
+
628
+ $ git cat-file -p master^{tree}
629
+ 100644 blob fa49b077972391ad58037050f2a75f74e3671e92 new.txt
630
+ 100644 blob 9bc1dc421dcd51b4ac296e3e5b6e2a99cf44391e repo.rb
631
+ 100644 blob e3f094f522629ae358806b17daf78246c27c007b test.txt
632
+
633
+ Następnie możesz sprawdzić ile miejsca zajmuje on na dysku:
634
+
635
+ <!-- You can then check how big is that object on your disk: -->
636
+
637
+ $ du -b .git/objects/9b/c1dc421dcd51b4ac296e3e5b6e2a99cf44391e
638
+ 4102 .git/objects/9b/c1dc421dcd51b4ac296e3e5b6e2a99cf44391e
639
+
640
+ Teraz, zmodyfikujmy trochę ten plik i sprawdźmy co się stanie:
641
+
642
+ <!-- Now, modify that file a little, and see what happens: -->
643
+
644
+ $ echo '# testing' >> repo.rb
645
+ $ git commit -am 'modified repo a bit'
646
+ [master ab1afef] modified repo a bit
647
+ 1 files changed, 1 insertions(+), 0 deletions(-)
648
+
649
+ Sprawdź ponownie wynikowe drzewo projektu, a zobaczysz coś interesującego:
650
+
651
+ <!-- Check the tree created by that commit, and you see something interesting: -->
652
+
653
+ $ git cat-file -p master^{tree}
654
+ 100644 blob fa49b077972391ad58037050f2a75f74e3671e92 new.txt
655
+ 100644 blob 05408d195263d853f09dca71d55116663690c27c repo.rb
656
+ 100644 blob e3f094f522629ae358806b17daf78246c27c007b test.txt
657
+
658
+ Obiekt blog jest teraz zypełnie inny, co oznacza, że pomimo tego że dodałeś tylko jedną linię na końcu pliku który miał 400 linii, Git zapisał całą nową zawartość jako nowy obiekt:
659
+
660
+ <!-- The blob is now a different blob, which means that although you added only a single line to the end of a 400-line file, Git stored that new content as a completely new object: -->
661
+
662
+ $ du -b .git/objects/05/408d195263d853f09dca71d55116663690c27c
663
+ 4109 .git/objects/05/408d195263d853f09dca71d55116663690c27c
664
+
665
+ Masz teraz dwa prawie takie same obiekty zajmujące 4kb na dysku. Czy nie byłoby fajnie, gdyby Git mógł przechowywać tylko jeden z nich, a drugi tylko jako różnicę między nim a pierwszym?
666
+
667
+ <!-- You have two nearly identical 4K objects on your disk. Wouldn’t it be nice if Git could store one of them in full but then the second object only as the delta between it and the first? -->
668
+
669
+ Okazuje się że może. Początkowym formatem w jakim Git przechowuje obiekty na dysku jest tak zwany luźny format. Jednak, czasami Git pakuje kilka obiektów w pojedynczy plik binarny określany jako "packfile", aby zmniejszyć użycie przestrzeni dyskowej i przez to być bardziej wydajnym. Git wykona to, jeżeli masz dużą ilość luźnych obiektów, jeżeli uruchomisz komendę `git gc`, lub jeżeli wypchniesz dane na zdalny serwer. Aby zobaczyć jak to wygląda, możesz ręcznie zmusić Gita aby spakował te obiekty, za pomocą wywołania komendy `git gc`:
670
+
671
+ <!-- It turns out that it can. The initial format in which Git saves objects on disk is called a loose object format. However, occasionally Git packs up several of these objects into a single binary file called a packfile in order to save space and be more efficient. Git does this if you have too many loose objects around, if you run the `git gc` command manually, or if you push to a remote server. To see what happens, you can manually ask Git to pack up the objects by calling the `git gc` command: -->
672
+
673
+ $ git gc
674
+ Counting objects: 17, done.
675
+ Delta compression using 2 threads.
676
+ Compressing objects: 100% (13/13), done.
677
+ Writing objects: 100% (17/17), done.
678
+ Total 17 (delta 1), reused 10 (delta 0)
679
+
680
+ Jak spojrzysz na katalog "objects", zauważysz że większość Twoich obiektów zniknęła i pojawiła się para nowych plików:
681
+
682
+ <!-- If you look in your objects directory, you’ll find that most of your objects are gone, and a new pair of files has appeared: -->
683
+
684
+ $ find .git/objects -type f
685
+ .git/objects/71/08f7ecb345ee9d0084193f147cdad4d2998293
686
+ .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
687
+ .git/objects/info/packs
688
+ .git/objects/pack/pack-7a16e4488ae40c7d2bc56ea2bd43e25212a66c45.idx
689
+ .git/objects/pack/pack-7a16e4488ae40c7d2bc56ea2bd43e25212a66c45.pack
690
+
691
+ Obiekty blob które pozostały, to obiekty które nie wskazywały na żaden obiekt commit - w tym przypadku, przykładowe obiekty blob "what is up, doc?" oraz "test content", które zostały stworzone wcześniej. Ponieważ nie zostały one nigdy powiązane z żadnym commitem, Git uznał że nie są z niczym powiązane i nie włączył ich do żadnego pliku packfile.
692
+
693
+ <!-- The objects that remain are the blobs that aren’t pointed to by any commit — in this case, the "what is up, doc?" example and the "test content" example blobs you created earlier. Because you never added them to any commits, they’re considered dangling and aren’t packed up in your new packfile. -->
694
+
695
+ Kolejne nowe pliki to plik packfile oraz indeks. Plik packfile to pojedynczy plik, zawierający zawartość wszystkich obiektów które zostały usunięte. Plik indeks zawiera informacje o tym, w którym miejscu w pliku packfile znajduje się konkretny obiekt. Co jest ciekawe, to to, że przed uruchomieniem `gc` obiekty na dysku zajmowały łącznie około 8K, a nowy plik packfile tylko 4K. Przez spakowanie obiektów, zmniejszyłeś o połowę ilość zajmowanego miejsca.
696
+
697
+ <!-- The other files are your new packfile and an index. The packfile is a single file containing the contents of all the objects that were removed from your filesystem. The index is a file that contains offsets into that packfile so you can quickly seek to a specific object. What is cool is that although the objects on disk before you ran the `gc` were collectively about 8K in size, the new packfile is only 4K. You’ve halved your disk usage by packing your objects. -->
698
+
699
+ W jaki sposób Git to robi? Gdy Git pakuje obiekty, szuka plików które pod względem nazwy pliku i rozmiaru są podobne, i zachowuje tylko różnicę między wersjami. Możesz obejrzeć zawartość pliku packfile i zobaczyć co Git zrobił aby ograniczyć zużycie przestrzeni dyskowej. Komenda `git verify-pack` pozwala na podgląd tego, co zostało spakowane:
700
+
701
+ <!-- How does Git do this? When Git packs objects, it looks for files that are named and sized similarly, and stores just the deltas from one version of the file to the next. You can look into the packfile and see what Git did to save space. The `git verify-pack` plumbing command allows you to see what was packed up: -->
702
+
703
+ $ git verify-pack -v \
704
+ .git/objects/pack/pack-7a16e4488ae40c7d2bc56ea2bd43e25212a66c45.idx
705
+ 0155eb4229851634a0f03eb265b69f5a2d56f341 tree 71 76 5400
706
+ 05408d195263d853f09dca71d55116663690c27c blob 12908 3478 874
707
+ 09f01cea547666f58d6a8d809583841a7c6f0130 tree 106 107 5086
708
+ 1a410efbd13591db07496601ebc7a059dd55cfe9 commit 225 151 322
709
+ 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a blob 10 19 5381
710
+ 3c4e9cd789d88d8d89c1073707c3585e41b0e614 tree 101 105 5211
711
+ 484a59275031909e19aadb7c92262719cfcdf19a commit 226 153 169
712
+ 83baae61804e65cc73a7201a7252750c76066a30 blob 10 19 5362
713
+ 9585191f37f7b0fb9444f35a9bf50de191beadc2 tag 136 127 5476
714
+ 9bc1dc421dcd51b4ac296e3e5b6e2a99cf44391e blob 7 18 5193 1 \
715
+ 05408d195263d853f09dca71d55116663690c27c
716
+ ab1afef80fac8e34258ff41fc1b867c702daa24b commit 232 157 12
717
+ cac0cab538b970a37ea1e769cbbde608743bc96d commit 226 154 473
718
+ d8329fc1cc938780ffdd9f94e0d364e0ea74f579 tree 36 46 5316
719
+ e3f094f522629ae358806b17daf78246c27c007b blob 1486 734 4352
720
+ f8f51d7d8a1760462eca26eebafde32087499533 tree 106 107 749
721
+ fa49b077972391ad58037050f2a75f74e3671e92 blob 9 18 856
722
+ fdf4fc3344e67ab068f836878b6c4951e3b15f3d commit 177 122 627
723
+ chain length = 1: 1 object
724
+ pack-7a16e4488ae40c7d2bc56ea2bd43e25212a66c45.pack: ok
725
+
726
+ W tym przypadku, obiekt blob `9bc1d`, co możesz pamiętać był pierwszą wersją pliku repo.rb, oraz jest on powiązany z obiektem blob `05408`, który był drugą wersją tego pliku. Trzecia kolumna w wyniku pokazuje rozmiar zawartości obiektu, możesz więc zobaczyć, że zawartość `05408` zajmuje 12K, ale `9bc1d` tylko 7 bajtów. Interesujące jest również to, że to druga wersja pliku została zachowana bez zmian, a poprzednia wersja jest różnicą zmian w stosunku do niej - dzieje się tak dlatego, że najczęściej potrzebujesz szybko dostać się do najnowszej wersji pliku.
727
+
728
+ <!-- Here, the `9bc1d` blob, which if you remember was the first version of your repo.rb file, is referencing the `05408` blob, which was the second version of the file. The third column in the output is the size of the object’s content, so you can see that the content of `05408` takes up 12K, but that of `9bc1d` only takes up 7 bytes. What is also interesting is that the second version of the file is the one that is stored intact, whereas the original version is stored as a delta — this is because you’re most likely to need faster access to the most recent version of the file. -->
729
+
730
+ Bardzo fajną rzeczą z tym związaną jest to, że te pliki mogą być przepakowane w każdej chwili. Git czasami przepakuje bazę danych automatycznie, zawsze starając się aby zachować jak najwięcej miejsca. Możesz również ręcznie przepakować te pliki, wywołując w dowolnym momencie komendę `git gc`.
731
+
732
+ <!-- The really nice thing about this is that it can be repacked at any time. Git will occasionally repack your database automatically, always trying to save more space. You can also manually repack at any time by running `git gc` by hand. -->
733
+
734
+ ## Refspec ##
735
+
736
+ <!-- ## The Refspec ## -->
737
+
738
+ W trakcie czytania tej książki, używałeś prostych mapowań ze zdalnych gałęzi do lokalnych referencji; jednak mogą one być znaczniej bardziej złożone.
739
+ Załóżmy, że dodajesz zdalne repozytorium w taki sposób:
740
+
741
+ <!-- Throughout this book, you’ve used simple mappings from remote branches to local references; but they can be more complex.
742
+ Suppose you add a remote like this: -->
743
+
744
+ $ git remote add origin git@github.com:schacon/simplegit-progit.git
745
+
746
+ Doda to kolejną sekcję w pliku `.git/config`, określającą nazwę zdalnego repozytorium (`origin`), adres URL tego repozytorium, oraz refspec do pobierania:
747
+
748
+ <!-- It adds a section to your `.git/config` file, specifying the name of the remote (`origin`), the URL of the remote repository, and the refspec for fetching: -->
749
+
750
+ [remote "origin"]
751
+ url = git@github.com:schacon/simplegit-progit.git
752
+ fetch = +refs/heads/*:refs/remotes/origin/*
753
+
754
+ Refspec składa się z opcjonalnego znaku `+`, oraz wskazania ścieżki źródłowej i docelowej `<src>:<dst>`, gdzie `<src>` wskazuje referencję na zewnętrznym serwerze, a `<dst>` jest miejscem, w którym te referencje będą zapisywane lokalnie. Znak `+` wskazuje Gitowi, aby wykonywał aktualizację nawet wtedy, gdy ta referencja nie jest zwykłym przesunięciem (ang. fast-forward).
755
+
756
+ <!-- The format of the refspec is an optional `+`, followed by `<src>:<dst>`, where `<src>` is the pattern for references on the remote side and `<dst>` is where those references will be written locally. The `+` tells Git to update the reference even if it isn’t a fast-forward. -->
757
+
758
+ W zwyczajnym przypadku, jest to zapisywane automatycznie przez komendę `git remote add`, Git pobiera wszystkie referencje z `refs/heads/` na serwerze i zapisuje je do `refs/remotes/origin/` lokalnie. Więc, jeżeli istnieje gałąź `master` na serwerze, możesz uzyskać dostęp do logów tej gałęzi poprzez
759
+
760
+ <!-- In the default case that is automatically written by a `git remote add` command, Git fetches all the references under `refs/heads/` on the server and writes them to `refs/remotes/origin/` locally. So, if there is a `master` branch on the server, you can access the log of that branch locally via -->
761
+
762
+ $ git log origin/master
763
+ $ git log remotes/origin/master
764
+ $ git log refs/remotes/origin/master
765
+
766
+ Wszystkie te komendy są równoważne, ponieważ Git rozwinie je wszystkie do `refs/remotes/origin/master`.
767
+
768
+ <!-- They’re all equivalent, because Git expands each of them to `refs/remotes/origin/master`. -->
769
+
770
+ Jeżeli chciałbyś, aby Git pobierał za każdym razem tylko gałąź `master`, a nie wszystkie inne gałęzie na zdalnym serwerze, możesz zmienić linię fetch na
771
+
772
+ <!-- If you want Git instead to pull down only the `master` branch each time, and not every other branch on the remote server, you can change the fetch line to -->
773
+
774
+ fetch = +refs/heads/master:refs/remotes/origin/master
775
+
776
+ Jest to po prostu domyślna definicja refspec używana przez komendę `git fetch` podczas pobierania danych ze zdalnego repozytorium. Jeżeli chcesz wykonać coś jednorazowo, możesz podać definicję refspec również z linii komend. Aby pobrać gałąź `master` z zdalnego serwera, do `origin/mymaster` możesz uruchomić
777
+
778
+ <!-- This is just the default refspec for `git fetch` for that remote. If you want to do something one time, you can specify the refspec on the command line, too. To pull the `master` branch on the remote down to `origin/mymaster` locally, you can run -->
779
+
780
+ $ git fetch origin master:refs/remotes/origin/mymaster
781
+
782
+ Możesz również ustawić kilka refspec. Z linii komend, możesz pobrać kilka gałęzi za pomocą:
783
+
784
+ <!-- You can also specify multiple refspecs. On the command line, you can pull down several branches like so: -->
785
+
786
+ $ git fetch origin master:refs/remotes/origin/mymaster \
787
+ topic:refs/remotes/origin/topic
788
+ From git@github.com:schacon/simplegit
789
+ ! [rejected] master -> origin/mymaster (non fast forward)
790
+ * [new branch] topic -> origin/topic
791
+
792
+ W tym wypadku, pobieranie gałęzi master zostało odrzucone, ponieważ nie była to gałąź fast-forward (tzn. nie było możliwe wykonanie prostego przesunięcia w celu włączenia zmian). Możesz to zmienić, poprzez ustawienie znaku `+` na początku definicji refspec.
793
+
794
+ <!-- In this case, the master branch pull was rejected because it wasn’t a fast-forward reference. You can override that by specifying the `+` in front of the refspec. -->
795
+
796
+ Możesz również ustawić wiele definicji refspec w pliku konfiguracyjnym. Jeżeli zawsze chcesz pobierać gałęzie master i experiment, dodaj dwie linie:
797
+
798
+ <!-- You can also specify multiple refspecs for fetching in your configuration file. If you want to always fetch the master and experiment branches, add two lines: -->
799
+
800
+ [remote "origin"]
801
+ url = git@github.com:schacon/simplegit-progit.git
802
+ fetch = +refs/heads/master:refs/remotes/origin/master
803
+ fetch = +refs/heads/experiment:refs/remotes/origin/experiment
804
+
805
+ Nie możesz użyć masek na ścieżkach, więc takie ustawienie będzie błędne:
806
+
807
+ <!-- You can’t use partial globs in the pattern, so this would be invalid: -->
808
+
809
+ fetch = +refs/heads/qa*:refs/remotes/origin/qa*
810
+
811
+ Możesz jednak użyć przestrzeni nazw aby osiągnąć podobny efekt. Jeżeli masz zespół QA, który wypycha nowe gałęzie, a Ty chcesz pobrać tylko gałąź master oraz wszystkie gałęzie stworzone przez zespół QA, możesz wpisać w pliku konfiguracyjnym coś takiego:
812
+
813
+ <!-- However, you can use namespacing to accomplish something like that. If you have a QA team that pushes a series of branches, and you want to get the master branch and any of the QA team’s branches but nothing else, you can use a config section like this: -->
814
+
815
+ [remote "origin"]
816
+ url = git@github.com:schacon/simplegit-progit.git
817
+ fetch = +refs/heads/master:refs/remotes/origin/master
818
+ fetch = +refs/heads/qa/*:refs/remotes/origin/qa/*
819
+
820
+ Jeżeli masz bardziej złożony sposób współpracy, w którym zespół QA wypycha gałęzie, programiści wypychają gałęzie, oraz zespół integrujący również wypycha oraz współpracuje ze zdalnymi gałęziami, możesz stworzyć dla każdego z nich przestrzenie nazw w ten sposób.
821
+
822
+ <!-- If you have a complex workflow process that has a QA team pushing branches, developers pushing branches, and integration teams pushing and collaborating on remote branches, you can namespace them easily this way. -->
823
+
824
+ ### Wypychanie Refspecs ###
825
+
826
+ <!-- ### Pushing Refspecs ### -->
827
+
828
+ Fajnie, że w tym sposobem możesz pobrać referencje z konkretnych referencji, ale w jaki sposób zespół QA ma wstawiać swoje gałęzie do przestrzeni `qa/` w pierwszej kolejności? Możesz to osiągnąć, poprzez użycie refspec dla komendy push.
829
+
830
+ <!-- It’s nice that you can fetch namespaced references that way, but how does the QA team get their branches into a `qa/` namespace in the first place? You accomplish that by using refspecs to push. -->
831
+
832
+ Jeżeli zespół QA chce wypychać swoją gałąź `master` do `qa/master` na zdalnym serwerze, mogą oni uruchomić
833
+
834
+ <!-- If the QA team wants to push their `master` branch to `qa/master` on the remote server, they can run -->
835
+
836
+ $ git push origin master:refs/heads/qa/master
837
+
838
+ Jeżeli zechcą, aby Git robił to automatycznie za każdym razem po uruchomieniu `git push origin`, mogą dodać definicję `push` do swojego pliku konfiguracyjnego:
839
+
840
+ <!-- If they want Git to do that automatically each time they run `git push origin`, they can add a `push` value to their config file: -->
841
+
842
+ [remote "origin"]
843
+ url = git@github.com:schacon/simplegit-progit.git
844
+ fetch = +refs/heads/*:refs/remotes/origin/*
845
+ push = refs/heads/master:refs/heads/qa/master
846
+
847
+ I znowu, to spowoduje, że komenda `git push origin` będzie domyślnie wypychała lokalną gałąź `master` do zdalnej `qa/master`.
848
+
849
+ <!-- Again, this will cause a `git push origin` to push the local `master` branch to the remote `qa/master` branch by default. -->
850
+
851
+ ### Usuwanie referencji ###
852
+
853
+ <!-- ### Deleting References ### -->
854
+
855
+ Możesz również używać definicji refspec do usuwania referencji ze zdalnego serwera, poprzez uruchomienie komendy podobnej do:
856
+
857
+ <!-- You can also use the refspec to delete references from the remote server by running something like this: -->
858
+
859
+ $ git push origin :topic
860
+
861
+ Ponieważ refspec składa się z `<src>:<dst>`, przez opuszczenie części `<src>`, wskazujesz aby stworzyć nową pustą gałąź tematyczną, co ją kasuje.
862
+
863
+ <!-- Because the refspec is `<src>:<dst>`, by leaving off the `<src>` part, this basically says to make the topic branch on the remote nothing, which deletes it. -->
864
+
865
+ ## Protokoły transferu ##
866
+
867
+ <!-- ## Transfer Protocols ## -->
868
+
869
+ Git może przesyłać dane między repozytoriami na dwa główne sposoby: poprzez protokół HTTP oraz poprzez tak zwane inteligentne protokoły, używane transportach `file://`, `ssh://` oraz `git://`. Ten rodział szybko pokaże w jaki sposób te protokoły działają.
870
+
871
+ <!-- Git can transfer data between two repositories in two major ways: over HTTP and via the so-called smart protocols used in the `file://`, `ssh://`, and `git://` transports. This section will quickly cover how these two main protocols operate. -->
872
+
873
+ ### Protokół prosty ###
874
+
875
+ <!-- ### The Dumb Protocol ### -->
876
+
877
+ Transfer danych za pomocą protokołu HTTP jest często określany jako transfer prosty, ponieważ do jego działania nie jest wymagana obsługa Git na serwerze. Podczas pobierania danych za pomocą komendy "fetch", wykonywane są kolejno zapytania GET, z których program kliencki może odnaleźć strukturę repozytorium Git. Prześledźmy proces `http-fetch` dla biblioteki simplegit:
878
+
879
+ <!-- Git transport over HTTP is often referred to as the dumb protocol because it requires no Git-specific code on the server side during the transport process. The fetch process is a series of GET requests, where the client can assume the layout of the Git repository on the server. Let’s follow the `http-fetch` process for the simplegit library: -->
880
+
881
+ $ git clone http://github.com/schacon/simplegit-progit.git
882
+
883
+ Pierwszą rzeczą jaką wykonuje ta komenda, jest pobranie pliku `info/refs`. Plik ten jest zapisywany przez komendę `update-server-info`, dlatego też musisz włączyć komendę `post-receive`, aby przesyłanie danych przez HTTP działało poprawnie:
884
+
885
+ <!-- The first thing this command does is pull down the `info/refs` file. This file is written by the `update-server-info` command, which is why you need to enable that as a `post-receive` hook in order for the HTTP transport to work properly: -->
886
+
887
+ => GET info/refs
888
+ ca82a6dff817ec66f44342007202690a93763949 refs/heads/master
889
+
890
+ Masz teraz listę zdalnych referencji oraz ich sumy SHA. Następnie sprawdzasz co znajduje się w HEAD, tak aby było wiadomo jaką gałąź pobrać po zakończeniu:
891
+
892
+ <!-- Now you have a list of the remote references and SHAs. Next, you look for what the HEAD reference is so you know what to check out when you’re finished: -->
893
+
894
+ => GET HEAD
895
+ ref: refs/heads/master
896
+
897
+ Musisz pobrać gałąź `master` po ukończeniu całego procesu.
898
+ W tym momencie możesz rozpocząć proces odnajdowania struktury repozytorium. Elementem początkowym jest commit `ca82a6`, który zobaczyłeś w pliku `info/refs`, pobierz go jako pierwszego:
899
+
900
+ <!-- You need to check out the `master` branch when you’ve completed the process.
901
+ At this point, you’re ready to start the walking process. Because your starting point is the `ca82a6` commit object you saw in the `info/refs` file, you start by fetching that: -->
902
+
903
+ => GET objects/ca/82a6dff817ec66f44342007202690a93763949
904
+ (179 bytes of binary data)
905
+
906
+ Otrzymujesz w odpowiedzi obiekt - pobrany z serwera obiekt jest w luźnym formacie i został pobrany poprzez zapytanie HTTP GET. Możesz rozpakować ten plik, usunąć nagłówki i odczytać jego zawartość:
907
+
908
+ <!-- You get an object back — that object is in loose format on the server, and you fetched it over a static HTTP GET request. You can zlib-uncompress it, strip off the header, and look at the commit content: -->
909
+
910
+ $ git cat-file -p ca82a6dff817ec66f44342007202690a93763949
911
+ tree cfda3bf379e4f8dba8717dee55aab78aef7f4daf
912
+ parent 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
913
+ author Scott Chacon <schacon@gmail.com> 1205815931 -0700
914
+ committer Scott Chacon <schacon@gmail.com> 1240030591 -0700
915
+
916
+ changed the version number
917
+
918
+ W następnej kolejności masz dwa obiekty do pobrania - `cfda3b`, który jest obiektem tree z zawartością na którą wskazuje pobrany commit; oraz `085bb3`, który jest poprzednim commitem:
919
+
920
+ <!-- Next, you have two more objects to retrieve — `cfda3b`, which is the tree of content that the commit we just retrieved points to; and `085bb3`, which is the parent commit: -->
921
+
922
+ => GET objects/08/5bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
923
+ (179 bytes of data)
924
+
925
+ Otrzymałeś więc kolejny obiekt commit. Pobierz zawartość obiektu tree:
926
+
927
+ <!-- That gives you your next commit object. Grab the tree object: -->
928
+
929
+ => GET objects/cf/da3bf379e4f8dba8717dee55aab78aef7f4daf
930
+ (404 - Not Found)
931
+
932
+ Oops - wygląda na to, że obiekt tree nie jest w luźnym formacie na serwerze, dlatego otrzymałeś odpowiedź 404. Przyczyn takiego stanu rzeczy może być kilka - obiekt może być w alternatywnym repozytorium, lub może być w pliku packfile w tym samym repozytorium. Git najpierw sprawdza czy są jakieś alternatywne repozytoria dodane:
933
+
934
+ <!-- Oops — it looks like that tree object isn’t in loose format on the server, so you get a 404 response back. There are a couple of reasons for this — the object could be in an alternate repository, or it could be in a packfile in this repository. Git checks for any listed alternates first: -->
935
+
936
+ => GET objects/info/http-alternates
937
+ (empty file)
938
+
939
+ Jeżeli zwrócona zostanie lista alternatywnych adresów URL, Git sprawdzi czy istnieją w nich szukane pliki w luźnym formacie lub spakowane pliki packfile - jest to bardzo fajny mechanizm umożliwiający współdzielenie plików dla projektów które rozwidlają się (ang. fork) jeden od drugiego. Jednak, ze względu na to, że nie ma żadnych alternatywnych plików w tym przykładzie, szukany obiekt musi być w spakowanym pliku packfile. Aby zobaczyć jakie pliki packfile są dostępne na serwerze, musisz pobrać plik `objects/info/packs` zawierający ich listę (ten plik jest również tworzony przez `update-server-info`):
940
+
941
+ <!-- If this comes back with a list of alternate URLs, Git checks for loose files and packfiles there — this is a nice mechanism for projects that are forks of one another to share objects on disk. However, because no alternates are listed in this case, your object must be in a packfile. To see what packfiles are available on this server, you need to get the `objects/info/packs` file, which contains a listing of them (also generated by `update-server-info`): -->
942
+
943
+ => GET objects/info/packs
944
+ P pack-816a9b2334da9953e530f27bcac22082a9f5b835.pack
945
+
946
+ Jest tylko jeden plik packfile na serwerze, więc szukany obiekt jest na pewno w nim, sprawdź jednak plik indeks aby mieć pewność. Jest to również przydatne, gdy masz wiele plików packfile na serwerze, tak abyś mógł zobaczyć który z nich zawiera obiekt którego szukasz:
947
+
948
+ <!-- There is only one packfile on the server, so your object is obviously in there, but you’ll check the index file to make sure. This is also useful if you have multiple packfiles on the server, so you can see which packfile contains the object you need: -->
949
+
950
+ => GET objects/pack/pack-816a9b2334da9953e530f27bcac22082a9f5b835.idx
951
+ (4k of binary data)
952
+
953
+ Teraz, gdy pobrałeś już indeks pliku packfile, możesz zobaczyć jakie obiekty się w nim znajdują - ponieważ zawiera on listę sum SHA obiektów oraz informacje o tym w którym miejscu w pliku packfile ten obiekt się znajduje. Twój obiekt w nim jest, pobierz więc cały plik packfile:
954
+
955
+ <!-- Now that you have the packfile index, you can see if your object is in it — because the index lists the SHAs of the objects contained in the packfile and the offsets to those objects. Your object is there, so go ahead and get the whole packfile: -->
956
+
957
+ => GET objects/pack/pack-816a9b2334da9953e530f27bcac22082a9f5b835.pack
958
+ (13k of binary data)
959
+
960
+ Masz już obiekt tree, możesz więc kontynuować przechodzenie przez wszystkie zmiany. Wszystkie one zawarte są również w pliku packfile który właśnie pobrałeś, nie musisz więc wykonywać żadnych dodatkowych zapytań do serwera. Git pobierze kopię roboczą z gałęzi `master`, na którą wskazywała referencja pobrana z HEAD na początku całego procesu.
961
+
962
+ <!-- You have your tree object, so you continue walking your commits. They’re all also within the packfile you just downloaded, so you don’t have to do any more requests to your server. Git checks out a working copy of the `master` branch that was pointed to by the HEAD reference you downloaded at the beginning. -->
963
+
964
+ Wynik działania całego procesu wygląda tak:
965
+
966
+ <!-- The entire output of this process looks like this: -->
967
+
968
+ $ git clone http://github.com/schacon/simplegit-progit.git
969
+ Initialized empty Git repository in /private/tmp/simplegit-progit/.git/
970
+ got ca82a6dff817ec66f44342007202690a93763949
971
+ walk ca82a6dff817ec66f44342007202690a93763949
972
+ got 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
973
+ Getting alternates list for http://github.com/schacon/simplegit-progit.git
974
+ Getting pack list for http://github.com/schacon/simplegit-progit.git
975
+ Getting index for pack 816a9b2334da9953e530f27bcac22082a9f5b835
976
+ Getting pack 816a9b2334da9953e530f27bcac22082a9f5b835
977
+ which contains cfda3bf379e4f8dba8717dee55aab78aef7f4daf
978
+ walk 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
979
+ walk a11bef06a3f659402fe7563abf99ad00de2209e6
980
+
981
+ ### Protokół Inteligentny ###
982
+
983
+ <!-- ### The Smart Protocol ### -->
984
+
985
+ Metoda pobierania za pomocą HTTP jest prosta, ale nieefektywna. Używanie protokołów inteligentnych jest znacznie częstszym sposobem do transferu danych. Te protokołu posiadają uruchomiony program na drugim końcu połączenia, który zna działanie Gita - może on odczytywać lokalne dane, oraz może wygenerować dane dla konkretnego klienta na podstawie tego jakie informacje on już posiada. Są dwa rodzaje procesów do przesyłania danych: para procesów do wgrywania danych, oraz para do pobierania.
986
+
987
+ <!-- The HTTP method is simple but a bit inefficient. Using smart protocols is a more common method of transferring data. These protocols have a process on the remote end that is intelligent about Git — it can read local data and figure out what the client has or needs and generate custom data for it. There are two sets of processes for transferring data: a pair for uploading data and a pair for downloading data. -->
988
+
989
+ #### Wgrywanie Danych ####
990
+
991
+ <!-- #### Uploading Data #### -->
992
+
993
+ Aby wgrać dane do zdalnego repozytorium, Git używa procesów `send-pack` oraz `receive-pack`. Proces `send-pack` uruchomiony jest po stronie klienta i łączy się do procesu `receive-pack` uruchomionego na zdalnym serwerze.
994
+
995
+ <!-- To upload data to a remote process, Git uses the `send-pack` and `receive-pack` processes. The `send-pack` process runs on the client and connects to a `receive-pack` process on the remote side. -->
996
+
997
+ Na przykład, załóżmy że uruchamiasz `git push origin master` w swoim projekcie, a `origin` jest zdefiniowany jako URL używający protokołu ssh. Git uruchamia proces `send-pack`, który zainicjuje połączenie przez SSH do Twojego serwera. Uruchamia on komendę na zdalnym serwerze przez SSH, podobną do:
998
+
999
+ <!-- For example, say you run `git push origin master` in your project, and `origin` is defined as a URL that uses the SSH protocol. Git fires up the `send-pack` process, which initiates a connection over SSH to your server. It tries to run a command on the remote server via an SSH call that looks something like this: -->
1000
+
1001
+ $ ssh -x git@github.com "git-receive-pack 'schacon/simplegit-progit.git'"
1002
+ 005bca82a6dff817ec66f4437202690a93763949 refs/heads/master report-status delete-refs
1003
+ 003e085bb3bcb608e1e84b2432f8ecbe6306e7e7 refs/heads/topic
1004
+ 0000
1005
+
1006
+ Komenda `git-receive-pack` od razu odpowiada jedną linią dla każdej referencji którą aktualnie zawiera - w tym przypadku, tylko gałąź `master` oraz jej SHA. Pierwsza linia zawiera również listę funkcji serwera (tutaj `report-status` i `delete-refs`).
1007
+
1008
+ <!-- The `git-receive-pack` command immediately responds with one line for each reference it currently has — in this case, just the `master` branch and its SHA. The first line also has a list of the server’s capabilities (here, `report-status` and `delete-refs`). -->
1009
+
1010
+ Każda linia rozpoczyna się 4-bajtową wartością hex wskazującą na to, jak długa jest reszta linii. Pierwsza linia rozpoczyna się 005b, co daje 91 w hex, co oznacza że 91 bajtów pozostało w tej linii. Następna linia rozpoczyna się od 003e, czyli 62, odczytujesz więc pozostałe 62 bajty. Kolejna linia to 0000, oznaczająca że serwer zakończył listowanie referencji.
1011
+
1012
+ <!-- Each line starts with a 4-byte hex value specifying how long the rest of the line is. Your first line starts with 005b, which is 91 in hex, meaning that 91 bytes remain on that line. The next line starts with 003e, which is 62, so you read the remaining 62 bytes. The next line is 0000, meaning the server is done with its references listing. -->
1013
+
1014
+ Teraz, gdy zna on już stan który jest na serwerze, Twój proces `send-pack` ustala które z posiadanych commitów nie istnieją na serwerze. Dla każdej referencji która zostanie zaktualizowana podczas tego pusha, proces `send-pack` przekazuje `receive-pack` te informacje. Na przykład, jeżeli aktualizujesz gałąź `master` oraz dodajesz gałąź `experiment`, odpowiedź `send-pack` może wyglądać tak:
1015
+
1016
+ <!-- Now that it knows the server’s state, your `send-pack` process determines what commits it has that the server doesn’t. For each reference that this push will update, the `send-pack` process tells the `receive-pack` process that information. For instance, if you’re updating the `master` branch and adding an `experiment` branch, the `send-pack` response may look something like this: -->
1017
+
1018
+ 0085ca82a6dff817ec66f44342007202690a93763949 15027957951b64cf874c3557a0f3547bd83b3ff6 refs/heads/master report-status
1019
+ 00670000000000000000000000000000000000000000 cdfdb42577e2506715f8cfeacdbabc092bf63e8d refs/heads/experiment
1020
+ 0000
1021
+
1022
+ Wartość SHA-1 składająca się z samych '0' oznacza że nic nie było wcześniej - ponieważ dodajesz referencję experiment. Jeżeli usuwasz referencję, zobaczyć sytuację odwrotną: same zera po prawej stronie.
1023
+
1024
+ <!-- The SHA-1 value of all '0's means that nothing was there before — because you’re adding the experiment reference. If you were deleting a reference, you would see the opposite: all '0's on the right side. -->
1025
+
1026
+ Git wysyła linię dla każdej referencji którą aktualizujesz z starą sumą SHA, nową sumą SHA, oraz referencję. Pierwsza linia zawiera również funkcje obsługiwane prze klienta. Następnie, program kliencki wysyła plik packfile zawierający wszystkie obiekty których nie ma na serwerze. Na końcu, serwer wysyła odpowiedź wskazująca na poprawne lub błędne zakończenie:
1027
+
1028
+ <!-- Git sends a line for each reference you’re updating with the old SHA, the new SHA, and the reference that is being updated. The first line also has the client’s capabilities. Next, the client uploads a packfile of all the objects the server doesn’t have yet. Finally, the server responds with a success (or failure) indication: -->
1029
+
1030
+ 000Aunpack ok
1031
+
1032
+ #### Pobieranie Danych ####
1033
+
1034
+ <!-- #### Downloading Data #### -->
1035
+
1036
+ Podczas pobierania danych, procesy `fetch-pack` oraz `upload-pack` są używane. Po stronie klienta uruchamiany jest proces `fetch-pack`, łączący się do `upload-pack` na drugim końcu, w celu ustalenia które dane mają być pobrane.
1037
+
1038
+ <!-- When you download data, the `fetch-pack` and `upload-pack` processes are involved. The client initiates a `fetch-pack` process that connects to an `upload-pack` process on the remote side to negotiate what data will be transferred down. -->
1039
+
1040
+ Istnieją różne sposoby na zainicjowanie procesu `upload-pack` na zdalnym repozytorium. Możesz uruchomić przez SSH, w sposób podobny do procesu `receive-pack`. Możesz również zainicjować ten proces przez demona Git, który domyślnie nasłuchuje na serwerze na porcie 9418. Proces `fetch-pack` wysyła dane, które wyglądają tak jak te, po połączeniu:
1041
+
1042
+ <!-- There are different ways to initiate the `upload-pack` process on the remote repository. You can run via SSH in the same manner as the `receive-pack` process. You can also initiate the process via the Git daemon, which listens on a server on port 9418 by default. The `fetch-pack` process sends data that looks like this to the daemon after connecting: -->
1043
+
1044
+ 003fgit-upload-pack schacon/simplegit-progit.git\0host=myserver.com\0
1045
+
1046
+ Rozpoczyna się ona 4 bajtami wskazującymi na to, ile danych będzie przesłanych, następnie komenda do uruchomienia zakończona znakiem null, a następnie nazwa domenowa serwera zakończona końcowym znakiem null. Demon Git sprawdza czy komenda może zostać uruchomiona, oraz czy repozytorium istnieje i ma publiczne uprawnienia. Jeżeli wszystko jest poprawnie, uruchamia proces `upload-pack` i przekazuje do niego zapytanie.
1047
+
1048
+ <!-- It starts with the 4 bytes specifying how much data is following, then the command to run followed by a null byte, and then the server’s hostname followed by a final null byte. The Git daemon checks that the command can be run and that the repository exists and has public permissions. If everything is cool, it fires up the `upload-pack` process and hands off the request to it. -->
1049
+
1050
+ jeżeli wykonujesz komendę fetch przez SSH, `fetch-pack` uruchamia komendę podobną do:
1051
+
1052
+ <!-- If you’re doing the fetch over SSH, `fetch-pack` instead runs something like this: -->
1053
+
1054
+ $ ssh -x git@github.com "git-upload-pack 'schacon/simplegit-progit.git'"
1055
+
1056
+ W każdym z tym przypadków, po połączeniu `fetch-pack`, `upload-pack` zwraca wyniki podobny do:
1057
+
1058
+ <!-- In either case, after `fetch-pack` connects, `upload-pack` sends back something like this: -->
1059
+
1060
+ 0088ca82a6dff817ec66f44342007202690a93763949 HEAD\0multi_ack thin-pack \
1061
+ side-band side-band-64k ofs-delta shallow no-progress include-tag
1062
+ 003fca82a6dff817ec66f44342007202690a93763949 refs/heads/master
1063
+ 003e085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 refs/heads/topic
1064
+ 0000
1065
+
1066
+ jest to bardzo podobna odpowiedź to tej którą zwrócił `receive-pack`, ale z innymi obsługiwanymi funkcjami. Dodatkowo, zwracana jest referencja HEAD, tak aby klient wiedział co ma pobrać w przypadku klonowania repozytorium.
1067
+
1068
+ <!-- This is very similar to what `receive-pack` responds with, but the capabilities are different. In addition, it sends back the HEAD reference so the client knows what to check out if this is a clone. -->
1069
+
1070
+ W tym momencie, proces `fetch-pack` sprawdza jakie obiekty posiada i wysyła odpowiedź z obiektami które potrzebuje za pomocą "want" oraz sumy SHA. Wysyła informację o tym jakie obiekty już posiada za pomocą "have" oraz SHA. Na końcu listy, wypisuje "done", aby proces `upload-pack` wiedział że ma rozpocząć wysyłanie spakowanych plików packfile z danymi które są potrzebne:
1071
+
1072
+ <!-- At this point, the `fetch-pack` process looks at what objects it has and responds with the objects that it needs by sending "want" and then the SHA it wants. It sends all the objects it already has with "have" and then the SHA. At the end of this list, it writes "done" to initiate the `upload-pack` process to begin sending the packfile of the data it needs: -->
1073
+
1074
+ 0054want ca82a6dff817ec66f44342007202690a93763949 ofs-delta
1075
+ 0032have 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
1076
+ 0000
1077
+ 0009done
1078
+
1079
+ To są bardzo proste przykłady protokołów przesyłania danych. W bardziej skomplikowanych, program kliencki wspiera funkcje `multi_pack` lub `side-band`; ale ten przykład pokazuje Ci podstawowe działanie inteligentnych protokołów.
1080
+
1081
+ <!-- That is a very basic case of the transfer protocols. In more complex cases, the client supports `multi_ack` or `side-band` capabilities; but this example shows you the basic back and forth used by the smart protocol processes. -->
1082
+
1083
+ ## Konserwacja i Odzyskiwanie Danych ##
1084
+
1085
+ <!-- ## Maintenance and Data Recovery ## -->
1086
+
1087
+ Czasami będziesz musiał zrobić jakieś porządki - sprawić, aby repozytorium zajmowało mniej miejsca, oczyścić zaimportowane repozytorium, lub odtworzyć utracone zmiany. Ten rozdział zawiera opis postępowania w tych scenariuszach.
1088
+
1089
+ <!-- Occasionally, you may have to do some cleanup — make a repository more compact, clean up an imported repository, or recover lost work. This section will cover some of these scenarios. -->
1090
+
1091
+ ### Konserwacja ###
1092
+
1093
+ <!-- ### Maintenance ### -->
1094
+
1095
+ Sporadycznie Git uruchamia automatycznie komendę nazywaną "auto gc". Najczęściej ta komenda nic nie robi. Jednak, jeżeli istnieje za dużo luźnych obiektów (obiektów które nie są w plikach packfile), lub za dużo plików packfile, Git uruchamia pełną komendę `git gc`. Komenda `gc` (od ang. garbage collect) wykonuje różne operacje: gromadzi ona wszystkie luźne obiekty i umieszcza je w plikach packfile, łączy pliki packfile w jeden duży, oraz usuwa obiekty które nie są osiągalne przez żaden z commitów i są starsze niż kilka miesięcy.
1096
+
1097
+ <!-- Occasionally, Git automatically runs a command called "auto gc". Most of the time, this command does nothing. However, if there are too many loose objects (objects not in a packfile) or too many packfiles, Git launches a full-fledged `git gc` command. The `gc` stands for garbage collect, and the command does a number of things: it gathers up all the loose objects and places them in packfiles, it consolidates packfiles into one big packfile, and it removes objects that aren’t reachable from any commit and are a few months old. -->
1098
+
1099
+ Możesz uruchomić "auto gc" ręcznie w ten sposób:
1100
+
1101
+ <!-- You can run auto gc manually as follows: -->
1102
+
1103
+ $ git gc --auto
1104
+
1105
+ I znowu, ona generalnie nic nie robi. Musisz mieć około 7000 luźnych obiektów, lub więcej niż 50 plików packfile, aby Git odpalił pełną komendę gc. Możesz zmienić te limity za pomocą ustawień konfiguracyjnych `gc.auto` oraz `gc.autopacklimit`.
1106
+
1107
+ <!-- Again, this generally does nothing. You must have around 7,000 loose objects or more than 50 packfiles for Git to fire up a real gc command. You can modify these limits with the `gc.auto` and `gc.autopacklimit` config settings, respectively. -->
1108
+
1109
+ Inną rzeczą którą komenda `gc` zrobi, jest spakowanie referencji do pojedynczego pliku. Załóżmy, że Twoje repozytorium zawiera następujące gałęzie i tagi:
1110
+
1111
+ <!-- The other thing `gc` will do is pack up your references into a single file. Suppose your repository contains the following branches and tags: -->
1112
+
1113
+ $ find .git/refs -type f
1114
+ .git/refs/heads/experiment
1115
+ .git/refs/heads/master
1116
+ .git/refs/tags/v1.0
1117
+ .git/refs/tags/v1.1
1118
+
1119
+ jeżeli uruchomisz `git gc`, nie będziesz miał już tych plików w katalogu `refs`. Git przeniesie je, w celu poprawienia wydajności do pliku `.git/packed-refs`, który wygląda tak:
1120
+
1121
+ <!-- If you run `git gc`, you’ll no longer have these files in the `refs` directory. Git will move them for the sake of efficiency into a file named `.git/packed-refs` that looks like this: -->
1122
+
1123
+ $ cat .git/packed-refs
1124
+ # pack-refs with: peeled
1125
+ cac0cab538b970a37ea1e769cbbde608743bc96d refs/heads/experiment
1126
+ ab1afef80fac8e34258ff41fc1b867c702daa24b refs/heads/master
1127
+ cac0cab538b970a37ea1e769cbbde608743bc96d refs/tags/v1.0
1128
+ 9585191f37f7b0fb9444f35a9bf50de191beadc2 refs/tags/v1.1
1129
+ ^1a410efbd13591db07496601ebc7a059dd55cfe9
1130
+
1131
+ Jeżeli zaktualizujesz referencje, Git nie będzie zmieniał tego pliku, ale zamiast tego stworzy nowy plik w `refs/heads`. Aby pobrać właściwą sumę SHA dla danej referencji, Git sprawdzi czy istnieje ona w katalogu `refs`, a następnie sprawdzi plik `packed-refs`. Jeżeli nie możesz znaleźć referencji w katalogu `refs`, jest ona prawdopodobnie w pliku `packed-refs`.
1132
+
1133
+ <!-- If you update a reference, Git doesn’t edit this file but instead writes a new file to `refs/heads`. To get the appropriate SHA for a given reference, Git checks for that reference in the `refs` directory and then checks the `packed-refs` file as a fallback. However, if you can’t find a reference in the `refs` directory, it’s probably in your `packed-refs` file. -->
1134
+
1135
+ Zauważ, że ostatnia linia w tym pliku zaczyna się od `^`. Oznacza to, że dana etykieta jest etykietą opisaną, a ta linia jest commit-em na który on wskazuje.
1136
+
1137
+ <!-- Notice the last line of the file, which begins with a `^`. This means the tag directly above is an annotated tag and that line is the commit that the annotated tag points to. -->
1138
+
1139
+ ### Odzyskiwanie Danych ###
1140
+
1141
+ <!-- ### Data Recovery ### -->
1142
+
1143
+ W pewnym momencie swojej pracy z Git, możesz czasami przez przypadek stracić commit. Zazwyczaj dzieje się tak dlatego, ponieważ wymusisz usunięcie gałęzi która miała w sobie zmiany, a okazuje się że jednak ją potrzebowałeś; lub wykonujesz na gałęzi hard-reset, porzucając zmiany które teraz potrzebujesz. Zakładając że tak się stało, w jaki sposób możesz odzyskać swoje zmiany?
1144
+
1145
+ <!-- At some point in your Git journey, you may accidentally lose a commit. Generally, this happens because you force-delete a branch that had work on it, and it turns out you wanted the branch after all; or you hard-reset a branch, thus abandoning commits that you wanted something from. Assuming this happens, how can you get your commits back? -->
1146
+
1147
+ Mamy tutaj przykład, na którym zobaczymy odzyskiwanie danych z testowego repozytorium na którym wykonano hard-reset na gałęzi master. Na początek, zobaczmy jak wygląda repozytorium w takiej sytuacji:
1148
+
1149
+ <!-- Here’s an example that hard-resets the master branch in your test repository to an older commit and then recovers the lost commits. First, let’s review where your repository is at this point: -->
1150
+
1151
+ $ git log --pretty=oneline
1152
+ ab1afef80fac8e34258ff41fc1b867c702daa24b modified repo a bit
1153
+ 484a59275031909e19aadb7c92262719cfcdf19a added repo.rb
1154
+ 1a410efbd13591db07496601ebc7a059dd55cfe9 third commit
1155
+ cac0cab538b970a37ea1e769cbbde608743bc96d second commit
1156
+ fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit
1157
+
1158
+ Teraz cofnij gałąź `master` do środkowej zmiany:
1159
+
1160
+ <!-- Now, move the `master` branch back to the middle commit: -->
1161
+
1162
+ $ git reset --hard 1a410efbd13591db07496601ebc7a059dd55cfe9
1163
+ HEAD is now at 1a410ef third commit
1164
+ $ git log --pretty=oneline
1165
+ 1a410efbd13591db07496601ebc7a059dd55cfe9 third commit
1166
+ cac0cab538b970a37ea1e769cbbde608743bc96d second commit
1167
+ fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit
1168
+
1169
+ W ten sposób, skutecznie utraciłeś dwa najnowsze commity - nie masz gałęzi z której można by się dostać do nich. Musisz znaleźć najnowszą sumę SHA, a potem dodać gałąź wskazującą na nią. Najtrudniejsze jest znalezienie ostatniej sumy SHA - przecież nie zapamiętałeś jej, prawda?
1170
+
1171
+ <!-- You’ve effectively lost the top two commits — you have no branch from which those commits are reachable. You need to find the latest commit SHA and then add a branch that points to it. The trick is finding that latest commit SHA — it’s not like you’ve memorized it, right? -->
1172
+
1173
+ Często, najszybszym sposobem jest użycie narzędzia `git reflog`. W czasie pracy, Git w tle zapisuje na co wskazuje HEAD po każdej zmianie. Za każdym razem gdy wykonujesz commit lub zmieniasz gałęzie, reflog jest aktualizowany. Reflog jest również aktualizowany przez komendę `git update-ref`, co jest kolejnym argumentem za tym, aby jej używać zamiast zapisywać bezpośrednio wartości SHA do plików ref, tak jak zostało to opisane wcześniej w sekcji "Referencje w Git". Możesz zobaczyć na jakim etapie był projekt w każdym momencie za pomocą komendy `git reflog`:
1174
+
1175
+ <!-- Often, the quickest way is to use a tool called `git reflog`. As you’re working, Git silently records what your HEAD is every time you change it. Each time you commit or change branches, the reflog is updated. The reflog is also updated by the `git update-ref` command, which is another reason to use it instead of just writing the SHA value to your ref files, as we covered in the "Git References" section of this chapter earlier. You can see where you’ve been at any time by running `git reflog`: -->
1176
+
1177
+ $ git reflog
1178
+ 1a410ef HEAD@{0}: 1a410efbd13591db07496601ebc7a059dd55cfe9: updating HEAD
1179
+ ab1afef HEAD@{1}: ab1afef80fac8e34258ff41fc1b867c702daa24b: updating HEAD
1180
+
1181
+ Widzimy tutaj dwa commity które pobraliśmy, jednak nie mamy za dużo informacji. Aby zobaczyć te same informacje w bardziej użytecznej formie, możemy uruchomić `git log -g`, która pokaże normalny wynik działania komendy log dla refloga:
1182
+
1183
+ <!-- Here we can see the two commits that we have had checked out, however there is not much information here. To see the same information in a much more useful way, we can run `git log -g`, which will give you a normal log output for your reflog. -->
1184
+
1185
+ $ git log -g
1186
+ commit 1a410efbd13591db07496601ebc7a059dd55cfe9
1187
+ Reflog: HEAD@{0} (Scott Chacon <schacon@gmail.com>)
1188
+ Reflog message: updating HEAD
1189
+ Author: Scott Chacon <schacon@gmail.com>
1190
+ Date: Fri May 22 18:22:37 2009 -0700
1191
+
1192
+ third commit
1193
+
1194
+ commit ab1afef80fac8e34258ff41fc1b867c702daa24b
1195
+ Reflog: HEAD@{1} (Scott Chacon <schacon@gmail.com>)
1196
+ Reflog message: updating HEAD
1197
+ Author: Scott Chacon <schacon@gmail.com>
1198
+ Date: Fri May 22 18:15:24 2009 -0700
1199
+
1200
+ modified repo a bit
1201
+
1202
+ Wygląda na to, że dolny commit to jeden z tych które utraciłeś, możesz go odzyskać przez stworzenie nowej gałęzi wskazującej na niego. Na przykład, możesz dodać gałąź `recover-branch` wskazującą na ten commit (ab1afef):
1203
+
1204
+ <!-- It looks like the bottom commit is the one you lost, so you can recover it by creating a new branch at that commit. For example, you can start a branch named `recover-branch` at that commit (ab1afef): -->
1205
+
1206
+ $ git branch recover-branch ab1afef
1207
+ $ git log --pretty=oneline recover-branch
1208
+ ab1afef80fac8e34258ff41fc1b867c702daa24b modified repo a bit
1209
+ 484a59275031909e19aadb7c92262719cfcdf19a added repo.rb
1210
+ 1a410efbd13591db07496601ebc7a059dd55cfe9 third commit
1211
+ cac0cab538b970a37ea1e769cbbde608743bc96d second commit
1212
+ fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit
1213
+
1214
+ Świetnie - masz teraz gałąź `recover-branch`, która wskazuje na miejsce w którym był `master`, pozwalając tym samym na dostęp do pierwszych dwóch commitów.
1215
+ Następnie, załóżmy że utracone zmiany z jakiegoś powodu nie były w reflogu - możesz to zasymulować poprzez usunięcie `recover-branch` i usunięcie refloga. Teraz pierwsze dwa commity nie są dostępne w żaden sposób:
1216
+
1217
+ <!-- Cool — now you have a branch named `recover-branch` that is where your `master` branch used to be, making the first two commits reachable again.
1218
+ Next, suppose your loss was for some reason not in the reflog — you can simulate that by removing `recover-branch` and deleting the reflog. Now the first two commits aren’t reachable by anything: -->
1219
+
1220
+ $ git branch -D recover-branch
1221
+ $ rm -Rf .git/logs/
1222
+
1223
+ Ponieważ dane reflog są przechowywane w katalogu `.git/logs/`, w rzeczywistości nie masz refloga. W jaki sposób odtworzyć ten commit w tym momencie? Jednym ze sposobów jest użycie narzędzia `git fsck`, które sprawdza zawartość bazy pod względem integralności danych. Jeżeli uruchomisz go z opcją `--full`, pokaże on wszystkie obiekty do których nie da się dotrzeć przez inne:
1224
+
1225
+ <!-- Because the reflog data is kept in the `.git/logs/` directory, you effectively have no reflog. How can you recover that commit at this point? One way is to use the `git fsck` utility, which checks your database for integrity. If you run it with the `-\-full` option, it shows you all objects that aren’t pointed to by another object: -->
1226
+
1227
+ $ git fsck --full
1228
+ dangling blob d670460b4b4aece5915caf5c68d12f560a9fe3e4
1229
+ dangling commit ab1afef80fac8e34258ff41fc1b867c702daa24b
1230
+ dangling tree aea790b9a58f6cf6f2804eeac9f0abbe9631e4c9
1231
+ dangling blob 7108f7ecb345ee9d0084193f147cdad4d2998293
1232
+
1233
+ W tym przypadku, możesz zobaczyć brakujący commit oznaczony jako opuszczony (ang. dangling). Możesz odtworzyć go w ten sam sposób, poprzez dodanie gałęzi wskazującej na jego SHA.
1234
+
1235
+ <!-- In this case, you can see your missing commit after the dangling commit. You can recover it the same way, by adding a branch that points to that SHA. -->
1236
+
1237
+ ### Usuwanie obiektów ###
1238
+
1239
+ <!-- ### Removing Objects ### -->
1240
+
1241
+ Można powiedzieć dużo dobrego o Gitcie, ale jedną z funkcjonalności która może powodować problemy jest fakt, że `git clone` pobiera całą historię projektu, włącznie z każdą wersją wszystkich plików. Jest to dobre rozwiązanie, jeżeli całość to kod źródłowy, ponieważ Git został przygotowany do tego aby efektywnie kompresować takie dane. Jednak, jeżeli w jakimś momencie trwania projektu, ktoś dodał pojedynczy duży plik, podczas klonowania repozytorium zawsze będzie on pobierany, nawet jeżeli został usunięty z projektu w następnym commicie. Ze względu na to, że można do niego dostać się przez historię projektu, zawsze tam będzie.
1242
+
1243
+ <!-- There are a lot of great things about Git, but one feature that can cause issues is the fact that a `git clone` downloads the entire history of the project, including every version of every file. This is fine if the whole thing is source code, because Git is highly optimized to compress that data efficiently. However, if someone at any point in the history of your project added a single huge file, every clone for all time will be forced to download that large file, even if it was removed from the project in the very next commit. Because it’s reachable from the history, it will always be there. -->
1244
+
1245
+ Może to być dużym problemem podczas konwersji repozytoriów Subversion lub Perforce do Gita. Ponieważ nie pobierasz w nich całej historii projektu, dodanie tak dużego pliku będzie powodowało pewne konsekwencje. Jeżeli wykonałeś import z innego systemu lub zobaczyłeś, że Twoje repozytorium jest dużo większej niż być powinno, poniżej prezentuję sposób na usunięcie dużych obiektów.
1246
+
1247
+ <!-- This can be a huge problem when you’re converting Subversion or Perforce repositories into Git. Because you don’t download the whole history in those systems, this type of addition carries few consequences. If you did an import from another system or otherwise find that your repository is much larger than it should be, here is how you can find and remove large objects. -->
1248
+
1249
+ Ale uwaga: ta technika działa destrukcyjnie na Twoją historię zmian. Nadpisuje ona każdy obiekt, począwszy od najwcześniejszego który trzeba zmodyfikować aby usunąć odwołanie do pliku. Jeżeli wykonasz to od razu po zaimportowaniu, zanim ktokolwiek rozpoczął pracę bazującą na nich, wszystko będzie w porządku - w przeciwnym wypadku, będziesz musiał poinformować wszystkich współpracowników o tym, że muszą wykonać "rebase" na nowe commity.
1250
+
1251
+ <!-- Be warned: this technique is destructive to your commit history. It rewrites every commit object downstream from the earliest tree you have to modify to remove a large file reference. If you do this immediately after an import, before anyone has started to base work on the commit, you’re fine — otherwise, you have to notify all contributors that they must rebase their work onto your new commits. -->
1252
+
1253
+ W celach demonstracyjnych, dodasz duży plik do swojego testowego repozytorium, usuniesz go w kolejnym commicie, odszukasz go i następnie usuniesz na stałe z repozytorium. Najpierw dodaj duży plik do repozytorium:
1254
+
1255
+ <!-- To demonstrate, you’ll add a large file into your test repository, remove it in the next commit, find it, and remove it permanently from the repository. First, add a large object to your history: -->
1256
+
1257
+ $ curl http://kernel.org/pub/software/scm/git/git-1.6.3.1.tar.bz2 > git.tbz2
1258
+ $ git add git.tbz2
1259
+ $ git commit -am 'added git tarball'
1260
+ [master 6df7640] added git tarball
1261
+ 1 files changed, 0 insertions(+), 0 deletions(-)
1262
+ create mode 100644 git.tbz2
1263
+
1264
+ Oops - nie chciałeś dodać tego dużego pliku do projekt. Najlepiej usuń go:
1265
+
1266
+ <!-- Oops — you didn’t want to add a huge tarball to your project. Better get rid of it: -->
1267
+
1268
+ $ git rm git.tbz2
1269
+ rm 'git.tbz2'
1270
+ $ git commit -m 'oops - removed large tarball'
1271
+ [master da3f30d] oops - removed large tarball
1272
+ 1 files changed, 0 insertions(+), 0 deletions(-)
1273
+ delete mode 100644 git.tbz2
1274
+
1275
+ Teraz, uruchom `gc` na bazie danych i zobacz jak dużo miejsca jest zajmowane:
1276
+
1277
+ <!-- Now, `gc` your database and see how much space you’re using: -->
1278
+
1279
+ $ git gc
1280
+ Counting objects: 21, done.
1281
+ Delta compression using 2 threads.
1282
+ Compressing objects: 100% (16/16), done.
1283
+ Writing objects: 100% (21/21), done.
1284
+ Total 21 (delta 3), reused 15 (delta 1)
1285
+
1286
+ Możesz uruchomić komendę `count-objects`, aby szybko zobaczyć jak dużo miejsca jest zajmowane:
1287
+
1288
+ <!-- You can run the `count-objects` command to quickly see how much space you’re using: -->
1289
+
1290
+ $ git count-objects -v
1291
+ count: 4
1292
+ size: 16
1293
+ in-pack: 21
1294
+ packs: 1
1295
+ size-pack: 2016
1296
+ prune-packable: 0
1297
+ garbage: 0
1298
+
1299
+ Wpis `size-pack` pokazuje wielkość plików packfile wyrażonych w kilobajtach, więc używasz 2MB. Przed ostatnim commitem, używałeś blisko 2K - a więc jasno widać, że usunięcie pliku w poprzednim commitcie nie usunęło go z historii. Za każdym razem, gdy ktoś sklonuje to repozytorium, będzie musiał pobrać całe 2MB aby pobrać ten malutki projekt, tylko dlatego że pochopnie dodałeś duży plik. Naprawmy to.
1300
+
1301
+ <!-- The `size-pack` entry is the size of your packfiles in kilobytes, so you’re using 2MB. Before the last commit, you were using closer to 2K — clearly, removing the file from the previous commit didn’t remove it from your history. Every time anyone clones this repository, they will have to clone all 2MB just to get this tiny project, because you accidentally added a big file. Let’s get rid of it. -->
1302
+
1303
+ Najpierw będzie musiał go znaleźć. W naszym wypadku, wiesz jaki plik to był. Ale załóżmy że nie wiesz; w jaki sposób dowiesz się jaki plik lub pliki zajmują tyle miejsca? Po uruchomieniu `git gc`, wszystkie obiekty są w plikach packfile; ale możesz zidentyfikować duże obiekty przez uruchomienie komendy `git verify-pack` i posortowanie wyniku po trzeciej kolumnie, oznaczającej rozmiar pliku. Możesz również przekazać wynik do komendy `tail` ponieważ jesteś zainteresowany tylko kilkoma największymi plikami:
1304
+
1305
+ <!-- First you have to find it. In this case, you already know what file it is. But suppose you didn’t; how would you identify what file or files were taking up so much space? If you run `git gc`, all the objects are in a packfile; you can identify the big objects by running another plumbing command called `git verify-pack` and sorting on the third field in the output, which is file size. You can also pipe it through the `tail` command because you’re only interested in the last few largest files: -->
1306
+
1307
+ $ git verify-pack -v .git/objects/pack/pack-3f8c0...bb.idx | sort -k 3 -n | tail -3
1308
+ e3f094f522629ae358806b17daf78246c27c007b blob 1486 734 4667
1309
+ 05408d195263d853f09dca71d55116663690c27c blob 12908 3478 1189
1310
+ 7a9eb2fba2b1811321254ac360970fc169ba2330 blob 2056716 2056872 5401
1311
+
1312
+ Duży obiekt jest na samym dole: 2MB. Aby dowiedzieć się jaki to jest plik, użyjesz komendy `rev-list`, której miałeś okazję już poznać w rozdziale 7. Jeżeli przekażesz opcję `--objects` do `rev-list`, w wyniku pokazane zostaną sumy SHA commitów oraz obiektów blob z przyporządkowanymi do nich nazwami plików. Możesz użyć tej komendy, aby odnaleźć nazwę obiektu blob:
1313
+
1314
+ <!-- The big object is at the bottom: 2MB. To find out what file it is, you’ll use the `rev-list` command, which you used briefly in Chapter 7. If you pass `-\-objects` to `rev-list`, it lists all the commit SHAs and also the blob SHAs with the file paths associated with them. You can use this to find your blob’s name: -->
1315
+
1316
+ $ git rev-list --objects --all | grep 7a9eb2fb
1317
+ 7a9eb2fba2b1811321254ac360970fc169ba2330 git.tbz2
1318
+
1319
+ Teraz, musisz usunąć ten plik ze wszystkich starszych rewizji. W łaty sposób możesz zobaczyć jakie commity modyfikowały ten plik:
1320
+
1321
+ <!-- Now, you need to remove this file from all trees in your past. You can easily see what commits modified this file: -->
1322
+
1323
+ $ git log --pretty=oneline --branches -- git.tbz2
1324
+ da3f30d019005479c99eb4c3406225613985a1db oops - removed large tarball
1325
+ 6df764092f3e7c8f5f94cbe08ee5cf42e92a0289 added git tarball
1326
+
1327
+ Musisz nadpisać wszystkie commity starsze niż `6df76`, aby w pełni usunąć ten plik z historii projektu w Git. Aby to zrobić, użyjesz komendy `filter-branch`, poznanej w rozdziale 6.
1328
+
1329
+ <!-- You must rewrite all the commits downstream from `6df76` to fully remove this file from your Git history. To do so, you use `filter-branch`, which you used in Chapter 6: -->
1330
+
1331
+ $ git filter-branch --index-filter \
1332
+ 'git rm --cached --ignore-unmatch git.tbz2' -- 6df7640^..
1333
+ Rewrite 6df764092f3e7c8f5f94cbe08ee5cf42e92a0289 (1/2)rm 'git.tbz2'
1334
+ Rewrite da3f30d019005479c99eb4c3406225613985a1db (2/2)
1335
+ Ref 'refs/heads/master' was rewritten
1336
+
1337
+ Opcja `--index-filter` jest podobna do opcji `--tree-filter` opisanej w rozdziale 6, z tą różnicą, że zamiast przekazywać komendę, która modyfikuje pobrane pliki na dysku, modyfikuje przechowalnię lub indeks za każdym razem. Zamiast usuwać konkretny plik za pomocą `rm file`, musisz usunąć go za pomocą `git rm --cached` - musisz usunąć go z indeksu, nie z dysku. Powodem do takiego zachowania jest prędkość - ponieważ Git nie musi pobrać każdej rewizji na dysk przed uruchomieniem filtra, cały proces może być dużo szybszy. Możesz osiągnąć taki sam efekt za pomocą `--tree-filter`, jeżeli chcesz. Opcja `--ignore-unmatch` do `git rm` wskazuje, aby nie pokazywać błędu w przypadku, gdy szukana ścieżka nie istnieje. Na koniec, wskazujesz `filter-branch`, aby przepisana została historia począwszy od `6df7640`, ponieważ wiesz że właśnie tam problem powstał. W przeciwnym razie, rozpocznie ona działanie od początku i przez to będzie trwała niepotrzebnie dłużej.
1338
+
1339
+ <!-- The `-\-index-filter` option is similar to the `-\-tree-filter` option used in Chapter 6, except that instead of passing a command that modifies files checked out on disk, you’re modifying your staging area or index each time. Rather than remove a specific file with something like `rm file`, you have to remove it with `git rm -\-cached` — you must remove it from the index, not from disk. The reason to do it this way is speed — because Git doesn’t have to check out each revision to disk before running your filter, the process can be much, much faster. You can accomplish the same task with `-\-tree-filter` if you want. The `-\-ignore-unmatch` option to `git rm` tells it not to error out if the pattern you’re trying to remove isn’t there. Finally, you ask `filter-branch` to rewrite your history only from the `6df7640` commit up, because you know that is where this problem started. Otherwise, it will start from the beginning and will unnecessarily take longer. -->
1340
+
1341
+ Twoja historia nie zawiera już odwołań do tego pliku. Ale reflog i nowe referencje które zostały dodane, wtedy gdy uruchomiłeś `filter-branch` w `.git/refs/original` nadal tak, musisz więc je usunąć i przepakować bazę danych. Musisz pozbyć się wszystkiego co wskazuje na te stare commity przed przepakowaniem:
1342
+
1343
+ <!-- Your history no longer contains a reference to that file. However, your reflog and a new set of refs that Git added when you did the `filter-branch` under `.git/refs/original` still do, so you have to remove them and then repack the database. You need to get rid of anything that has a pointer to those old commits before you repack: -->
1344
+
1345
+ $ rm -Rf .git/refs/original
1346
+ $ rm -Rf .git/logs/
1347
+ $ git gc
1348
+ Counting objects: 19, done.
1349
+ Delta compression using 2 threads.
1350
+ Compressing objects: 100% (14/14), done.
1351
+ Writing objects: 100% (19/19), done.
1352
+ Total 19 (delta 3), reused 16 (delta 1)
1353
+
1354
+ Zobaczmy ile miejsce udało się zaoszczędzić.
1355
+
1356
+ <!-- Let’s see how much space you saved. -->
1357
+
1358
+ $ git count-objects -v
1359
+ count: 8
1360
+ size: 2040
1361
+ in-pack: 19
1362
+ packs: 1
1363
+ size-pack: 7
1364
+ prune-packable: 0
1365
+ garbage: 0
1366
+
1367
+ Wielkość spakowanego repozytorium to teraz 7K, co jest dużo lepszym wynikiem niż 2MB. Możesz odczytać z wartości "size", że ten duży obiekt nadal znajduje się w repozytorium, nie został więc całkowicie usunięty; jednak co najważniejsze, nie będzie już przesyłany podczas wykonywania push lub klonowania. Jeżeli mocno chcesz, możesz usunąć ten obiekt całkowicie przez uruchomienie komendy `git prune --expire`.
1368
+
1369
+ <!-- The packed repository size is down to 7K, which is much better than 2MB. You can see from the size value that the big object is still in your loose objects, so it’s not gone; but it won’t be transferred on a push or subsequent clone, which is what is important. If you really wanted to, you could remove the object completely by running `git prune -\-expire`. -->
1370
+
1371
+ ## Podsumowanie ##
1372
+
1373
+ <!-- ## Summary ## -->
1374
+
1375
+ Powinieneś już dość dobrze wiedzieć co Git robi w tle, oraz w pewnym stopniu, w jaki sposób jest to zaimplementowane. Ten rozdział objął kilka niskopoziomowych komend - typu plumbing, komend które są działają na niższym poziomie i są prostsze niż komendy normalnie dostępne dla użytkownika i opisane w pozostałej części książki. Zrozumienie w jaki sposób Git działa powinno ułatwić Ci pisanie własnych komend i skryptów, ułatwiając tym samym pracę.
1376
+
1377
+ <!-- You should have a pretty good understanding of what Git does in the background and, to some degree, how it’s implemented. This chapter has covered a number of plumbing commands — commands that are lower level and simpler than the porcelain commands you’ve learned about in the rest of the book. Understanding how Git works at a lower level should make it easier to understand why it’s doing what it’s doing and also to write your own tools and helping scripts to make your specific workflow work for you. -->
1378
+
1379
+ Git jako system plików ukierunkowany na treść jest bardzo potężnym narzędziem, które może robić znacznie więcej niż tylko zadania związane z kontrolą wersji. Mam nadzieję, że użyjesz tej nowo nabytej wiedzy o wewnętrznych mechanizmach Gita podczas implementacji swojej własnej aplikacji i będziesz czuł się komfortowo podczas używania go w sposób bardziej zaawansowany.
1380
+
1381
+ <!-- Git as a content-addressable filesystem is a very powerful tool that you can easily use as more than just a VCS. I hope you can use your newfound knowledge of Git internals to implement your own cool application of this technology and feel more comfortable using Git in more advanced ways. -->
1382
+