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,1167 @@
1
+ # Nástroje systému Git #
2
+
3
+ Do této chvíle jste stačili poznat většinu každodenních příkazů a pracovních postupů, které budete při práci se zdrojovým kódem potřebovat k ovládání a správě repozitáře Git. Zvládli jste základní úkony sledování a zapisování souborů a pochopili jste přednosti přípravy souborů k zapsání i snadného vytváření a začleňování větví.
4
+
5
+ Nyní poznáte několik velmi účinných nástrojů, které vám Git nabízí. Pravděpodobně je nebudete používat každý den, ale přesto se vám mohou čas od času hodit.
6
+
7
+ ## Výběr revize ##
8
+
9
+ Systém Git umožňuje určit jednotlivé revize nebo interval revizí několika způsoby. Není nezbytně nutné, abyste je všechny znali, ale mohou být užitečné.
10
+
11
+ ### Jednotlivé revize ###
12
+
13
+ Revizi můžete samozřejmě specifikovat na základě otisku SHA-1, jenž jí byl přidělen. Existují však i uživatelsky příjemnější způsoby, jak označit konkrétní revizi. Tato část uvede několik různých způsobů, jak lze určit jednu konkrétní revizi.
14
+
15
+ ### Zkrácená hodnota SHA ###
16
+
17
+ Git je dostatečně chytrý na to, aby pochopil, jakou revizi jste měli na mysli, zadáte-li pouze prvních několik znaků. Tento neúplný otisk SHA-1 musí mít alespoň čtyři znaky a musí být jednoznačný, tj. žádný další objekt v aktuálním repozitáři nesmí začínat stejnou zkrácenou hodnotou SHA-1.
18
+
19
+ Pokud si chcete například prohlédnout konkrétní revizi, řekněme, že spustíte příkaz `git log` a určíte revizi, do níž jste vložili určitou funkci:
20
+
21
+ $ git log
22
+ commit 734713bc047d87bf7eac9674765ae793478c50d3
23
+ Author: Scott Chacon <schacon@gmail.com>
24
+ Date: Fri Jan 2 18:32:33 2009 -0800
25
+
26
+ fixed refs handling, added gc auto, updated tests
27
+
28
+ commit d921970aadf03b3cf0e71becdaab3147ba71cdef
29
+ Merge: 1c002dd... 35cfb2b...
30
+ Author: Scott Chacon <schacon@gmail.com>
31
+ Date: Thu Dec 11 15:08:43 2008 -0800
32
+
33
+ Merge commit 'phedders/rdocs'
34
+
35
+ commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b
36
+ Author: Scott Chacon <schacon@gmail.com>
37
+ Date: Thu Dec 11 14:58:32 2008 -0800
38
+
39
+ added some blame and merge stuff
40
+
41
+ V tomto případě vyberte `1c002dd....`. Pokud chcete na revizi použít příkaz `git show`, budou všechny následující příkazy ekvivalentní (za předpokladu, že jsou zkrácené verze jednoznačné):
42
+
43
+ $ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b
44
+ $ git show 1c002dd4b536e7479f
45
+ $ git show 1c002d
46
+
47
+ Git dokáže identifikovat krátkou, jednoznačnou zkratku hodnoty SHA-1. Zadáte-li k příkazu `git log` parametr `--abbrev-commit`, výstup bude používat kratší hodnoty, ale pouze v jednoznačném tvaru. Standardně se používá sedm znaků, avšak je-li to kvůli jednoznačnosti hodnoty SHA-1 nezbytné, bude použito znaků více:
48
+
49
+ $ git log --abbrev-commit --pretty=oneline
50
+ ca82a6d changed the version number
51
+ 085bb3b removed unnecessary test code
52
+ a11bef0 first commit
53
+
54
+ Osm až deset znaků většinou bohatě stačí, aby byla hodnota v rámci projektu jednoznačná. V jednom z největších projektů Git, v jádru Linuxu, začíná být nutné zadávat pro jednoznačné určení už 12 znaků z celkových 40 možných.
55
+
56
+ ### Krátká poznámka k hodnotě SHA-1 ###
57
+
58
+ Někteří uživatelé bývají zmateni, že mohou mít v repozitáři – shodou okolností – dva objekty, které mají stejnou hodnotu SHA-1 otisku. Co teď?
59
+
60
+ Pokud náhodou zapíšete objekt, který má stejnou hodnotu SHA-1 otisku jako předchozí objekt ve vašem repozitáři, Git už uvidí předchozí objekt v databázi Git a bude předpokládat, že už byl zapsán. Pokud se někdy v budoucnosti pokusíte znovu provést checkout tohoto objektu, vždy dostanete data prvního objektu.
61
+
62
+ Měli bychom však také říci, jak moc je nepravděpodobné, že taková situace nastane. Otisk SHA-1 má 20 bytů, neboli 160 bitů. Počet objektů s náhodným otiskem, které bychom potřebovali k 50% pravděpodobnosti, že nastane jediná kolize, je asi 2^80 (vzorec k určení pravděpodobnosti kolize je `p = (n(n-1)/2) * (1/2^160)`). 2^80 je 1,2 * 10^24, neboli 1 milion miliard miliard. To je 1200násobek počtu všech zrnek písku na celé Zemi.
63
+
64
+ Abyste si udělali představu, jak je nepravděpodobné, že dojde ke kolizi hodnot SHA-1, připojujeme jeden malý příklad. Kdyby 6,5 miliardy lidí na zemi programovalo a každý by každou sekundu vytvořil kód odpovídající celé historii linuxového jádra (1 milion objektů Git) a odesílal ho do jednoho obřího repozitáře Git, trvalo by 5 let, než by repozitář obsahoval dost objektů na to, aby existovala 50% pravděpodobnost, že dojde ke kolizi jediného objektu SHA-1. To už je pravděpodobnější, že všichni členové vašeho programovacího týmu budou během jedné noci v navzájem nesouvisejících incidentech napadeni a zabiti smečkou vlků.
65
+
66
+ ### Reference větví ###
67
+
68
+ Nejčistší způsob, jak určit konkrétní revizi, vyžaduje, aby měla revize referenci větve, která na ni ukazuje. V takovém případě můžete použít název větve v libovolném příkazu Git, který vyžaduje objekt revize nebo hodnotu SHA-1. Pokud chcete například zobrazit objekt poslední revize větve, můžete využít některý z následujících příkazů (za předpokladu, že větev `topic1` ukazuje na `ca82a6d`):
69
+
70
+ $ git show ca82a6dff817ec66f44342007202690a93763949
71
+ $ git show topic1
72
+
73
+ Jestliže vás zajímá, na kterou konkrétní hodnotu SHA větev ukazuje, nebo chcete-li zjistit, jak bude některý z těchto příkladů vypadat v podobě SHA, můžete použít jeden z nízkoúrovňových nástrojů systému Git: `rev-parse`. Více o nízkoúrovňových nástrojích najdete v kapitole 9. Nástroj `rev-parse` se používá v podstatě pouze pro operace na nižších úrovních a není koncipován pro každodenní používání. Může se však hodit, až budete jednou potřebovat zjistit, co se doopravdy odehrává. Tehdy můžete na svou větev spustit příkaz `rev-parse`:
74
+
75
+ $ git rev-parse topic1
76
+ ca82a6dff817ec66f44342007202690a93763949
77
+
78
+ ### Zkrácené názvy v záznamu RefLog ###
79
+
80
+ Jednou z věcí, které probíhají na pozadí systému Git, zatímco vy pracujete, je uchovávání záznamu reflog, v němž se ukládají pozice referencí HEAD a všech vašich větví za několik posledních měsíců.
81
+
82
+ Svůj reflog si můžete nechat zobrazit příkazem `git reflog`:
83
+
84
+ $ git reflog
85
+ 734713b HEAD@{0}: commit: fixed refs handling, added gc auto, updated
86
+ d921970 HEAD@{1}: merge phedders/rdocs: Merge made by recursive.
87
+ 1c002dd HEAD@{2}: commit: added some blame and merge stuff
88
+ 1c36188 HEAD@{3}: rebase -i (squash): updating HEAD
89
+ 95df984 HEAD@{4}: commit: # This is a combination of two commits.
90
+ 1c36188 HEAD@{5}: rebase -i (squash): updating HEAD
91
+ 7e05da5 HEAD@{6}: rebase -i (pick): updating HEAD
92
+
93
+ Pokaždé, když je z nějakého důvodu aktualizován vrchol větve, Git tuto informaci uloží v dočasné historii reflog. Pomocí těchto dat lze rovněž specifikovat starší revize. Chcete-li zobrazit pátou poslední hodnotu ukazatele HEAD svého repozitáře, použijte referenci `@{n}` z výstupu reflog:
94
+
95
+ $ git show HEAD@{5}
96
+
97
+ Tuto syntaxi můžete použít také k zobrazení pozice, na níž se větev nacházela před určitou dobou. Chcete-li například zjistit, kde byla vaše větev `master` včera (yesterday), můžete zadat příkaz:
98
+
99
+ $ git show master@{yesterday}
100
+
101
+ Git vám ukáže, kde se vrchol větve nacházel včera. Tato možnost funguje pouze pro data, jež jsou dosud v záznamu reflog. Nemůžete ji proto použít pro revize starší než několik měsíců.
102
+
103
+ Chcete-li zobrazit informace záznamu reflog ve formátu výstupu `git log`, zadejte příkaz `git log -g`:
104
+
105
+ $ git log -g master
106
+ commit 734713bc047d87bf7eac9674765ae793478c50d3
107
+ Reflog: master@{0} (Scott Chacon <schacon@gmail.com>)
108
+ Reflog message: commit: fixed refs handling, added gc auto, updated
109
+ Author: Scott Chacon <schacon@gmail.com>
110
+ Date: Fri Jan 2 18:32:33 2009 -0800
111
+
112
+ fixed refs handling, added gc auto, updated tests
113
+
114
+ commit d921970aadf03b3cf0e71becdaab3147ba71cdef
115
+ Reflog: master@{1} (Scott Chacon <schacon@gmail.com>)
116
+ Reflog message: merge phedders/rdocs: Merge made by recursive.
117
+ Author: Scott Chacon <schacon@gmail.com>
118
+ Date: Thu Dec 11 15:08:43 2008 -0800
119
+
120
+ Merge commit 'phedders/rdocs'
121
+
122
+ Měli bychom také doplnit, že informace záznamu reflog jsou čistě lokální, vztahují se pouze na to, co jste provedli ve svém repozitáři. V kopii repozitáře na počítači kohokoli jiného se budou tyto reference lišit. Bezprostředně poté, co poprvé naklonujete repozitář, bude váš reflog prázdný, protože ve vašem repozitáři ještě nebyla provedena žádná operace. Příkaz `git show HEAD@{2.months.ago}` bude fungovat, pouze pokud jste projekt naklonovali minimálně před dvěma měsíci (tedy „2 months ago“). Pokud jste jej naklonovali před pěti minutami, neobdržíte žádný výsledek.
123
+
124
+ ### Reference podle původu ###
125
+
126
+ Další základní způsob, jak specifikovat konkrétní revizi, je na základě jejího původu. Umístíte-li na konec reference znak `^`, Git bude referenci chápat tak, že označuje rodiče dané revize.
127
+ Můžete mít například takovouto historii projektu:
128
+
129
+ $ git log --pretty=format:'%h %s' --graph
130
+ * 734713b fixed refs handling, added gc auto, updated tests
131
+ * d921970 Merge commit 'phedders/rdocs'
132
+ |\
133
+ | * 35cfb2b Some rdoc changes
134
+ * | 1c002dd added some blame and merge stuff
135
+ |/
136
+ * 1c36188 ignore *.gem
137
+ * 9b29157 add open3_detach to gemspec file list
138
+
139
+ Zobrazit předchozí revizi pak můžete pomocí `HEAD^`, což doslova znamená „rodič revize HEAD“:
140
+
141
+ $ git show HEAD^
142
+ commit d921970aadf03b3cf0e71becdaab3147ba71cdef
143
+ Merge: 1c002dd... 35cfb2b...
144
+ Author: Scott Chacon <schacon@gmail.com>
145
+ Date: Thu Dec 11 15:08:43 2008 -0800
146
+
147
+ Merge commit 'phedders/rdocs'
148
+
149
+ Za znakem `^` můžete zadat také číslo, např. `d921970^2` označuje „druhého rodiče revize d921970“. Tato syntaxe má význam pouze u revizí vzniklých sloučením, které mají více než jednoho rodiče. První rodič je větev, na níž jste se během začlenění nacházeli, druhým rodičem je větev, kterou jste začleňovali:
150
+
151
+ $ git show d921970^
152
+ commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b
153
+ Author: Scott Chacon <schacon@gmail.com>
154
+ Date: Thu Dec 11 14:58:32 2008 -0800
155
+
156
+ added some blame and merge stuff
157
+
158
+ $ git show d921970^2
159
+ commit 35cfb2b795a55793d7cc56a6cc2060b4bb732548
160
+ Author: Paul Hedderly <paul+git@mjr.org>
161
+ Date: Wed Dec 10 22:22:03 2008 +0000
162
+
163
+ Some rdoc changes
164
+
165
+ Další základní možností označení původu je znak `~`. Také tento znak označuje prvního rodiče, výrazy `HEAD~` a `HEAD^` jsou proto ekvivalentní. Rozdíl mezi nimi je patrný při zadání čísla. `HEAD~2` označuje „prvního rodiče prvního rodiče“, tedy „prarodiče“. Příkaz překročí prvního rodiče tolikrát, kolikrát udává číselná hodnota. Například v historii naznačené výše by `HEAD~3` znamenalo:
166
+
167
+ $ git show HEAD~3
168
+ commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d
169
+ Author: Tom Preston-Werner <tom@mojombo.com>
170
+ Date: Fri Nov 7 13:47:59 2008 -0500
171
+
172
+ ignore *.gem
173
+
174
+ Totéž by bylo možné označit výrazem `HEAD^^^`, který opět udává prvního rodiče prvního rodiče prvního rodiče:
175
+
176
+ $ git show HEAD^^^
177
+ commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d
178
+ Author: Tom Preston-Werner <tom@mojombo.com>
179
+ Date: Fri Nov 7 13:47:59 2008 -0500
180
+
181
+ ignore *.gem
182
+
183
+ Tyto syntaxe můžete také kombinovat. Druhého rodiče předchozí reference (jestliže se jednalo o revizi sloučením) lze získat výrazem `HEAD~3^2` atd.
184
+
185
+ ### Intervaly revizí ###
186
+
187
+ Nyní, když umíte určit jednotlivé revize, podíváme se, jak lze určovat celé intervaly revizí. To využijete zejména při správě větví. Máte-li větší množství větví, pomůže vám označení intervalu revizí dohledat odpovědi na otázky typu: „Jaká práce je obsažena v této větvi, kterou jsem ještě nezačlenil do hlavní větve?“
188
+
189
+ #### Dvě tečky ####
190
+
191
+ Nejčastěji se při označení intervalu používá dvojtečková syntaxe. Pomocí ní systému Git v podstatě říkáte, aby uvažoval celý interval revizí, které jsou dostupné z jedné revize, ale nejsou dostupné z jiné. Předpokládejme tedy, že máte historii revizí jako na obrázku 6-1.
192
+
193
+ Insert 18333fig0601.png
194
+ Obrázek 6-1. Příklad historie revizí pro výběr intervalu
195
+
196
+ Vy chcete vidět, co všechno obsahuje vaše experimentální větev, kterou jste ještě nezačlenili do hlavní větve. Pomocí výrazu `master..experiment` můžete systému Git zadat příkaz, aby vám zobrazil log právě s těmito revizemi, doslova „všemi revizemi dostupnými z větve experiment a nedostupnými z hlavní větve“. V zájmu stručnosti a názornosti použiji v těchto příkladech místo skutečného výstupu logu písmena objektů revizí z diagramu v pořadí, jak by se zobrazily:
197
+
198
+ $ git log master..experiment
199
+ D
200
+ C
201
+
202
+ A samozřejmě si můžete nechat zobrazit i pravý opak, všechny revize ve větvi `master`, které nejsou ve větvi `experiment`. K tomu stačí obrátit pořadí názvů větví v příkazu. Výraz `experiment..master` zobrazí vše ve větvi `master`, co není dostupné ve větvi `experiment`:
203
+
204
+ $ git log experiment..master
205
+ F
206
+ E
207
+
208
+ Tento log využijete, pokud chcete udržovat větev `experiment` stále aktuální a zjistit, co hodláte začlenit. Tato syntaxe se velmi často používá také ke zjištění, co hodláte odeslat do vzdálené větve:
209
+
210
+ $ git log origin/master..HEAD
211
+
212
+ Tento příkaz zobrazí všechny revize ve vaší aktuální větvi, které nejsou obsaženy ve větvi `master` vzdáleného repozitáře `origin`. Spustíte-li příkaz `git push` a vaše aktuální větev sleduje větev `origin/master`, budou na server přesunuty revize, které lze zobrazit příkazem `git log origin/master..HEAD`.
213
+ Jednu stranu intervalu můžete zcela vynechat, Git na její místo automaticky dosadí HEAD. Stejné výsledky jako v předchozím příkladu dostanete zadáním příkazu `git log origin/master..` – Git dosadí na prázdnou stranu výraz HEAD.
214
+
215
+ #### Několik bodů ####
216
+
217
+ Dvojtečková syntaxe je užitečná jako zkrácený výraz. Možná ale budete chtít k označení revize určit více než dvě větve, např. až budete chtít zjistit, které revize jsou obsaženy ve všech ostatních větvích a zároveň nejsou obsaženy ve větvi, na níž se právě nacházíte. V systému Git to můžete provést buď zadáním znaku `^` nebo parametru `--not` před referencí, jejíž dostupné revize si nepřejete zobrazit. Tyto tři příkazy jsou tedy ekvivalentní:
218
+
219
+ $ git log refA..refB
220
+ $ git log ^refA refB
221
+ $ git log refB --not refA
222
+
223
+ Tato syntaxe je užitečná zejména proto, že pomocí ní můžete zadat více než dvě reference, což není pomocí dvojtečkové syntaxe možné. Pokud chcete zobrazit například všechny revize, které jsou dostupné ve větvi `refA` nebo `refB`, ale nikoli ve větvi `refC`, zadejte jeden z následujících příkazů:
224
+
225
+ $ git log refA refB ^refC
226
+ $ git log refA refB --not refC
227
+
228
+ Tím máte v rukou velmi efektivní systém vyhledávání revizí, který vám pomůže zjistit, co vaše větve obsahují.
229
+
230
+ #### Tři tečky ####
231
+
232
+ Poslední významnou syntaxí k určení intervalu je trojtečková syntaxe, která vybere všechny revize dostupné ve dvou referencích, ale ne v obou zároveň. Podívejme se ještě jednou na příklad historie revizí na obrázku 6-1.
233
+ Chcete-li zjistit, co je ve větvi `master` nebo `experiment`, ale nechcete vidět jejich společné reference, zadejte příkaz:
234
+
235
+ $ git log master...experiment
236
+ F
237
+ E
238
+ D
239
+ C
240
+
241
+ Výstupem příkazu bude běžný výpis příkazu `log`, ale zobrazí se pouze informace o těchto čtyřech revizích, uspořádané v tradičním pořadí podle data zapsání.
242
+
243
+ Přepínačem, který se v tomto případě běžně používá v kombinaci s příkazem `log`, je parametr `--left-right`. Příkaz pak zobrazí, na jaké straně intervalu se ta která revize nachází. Díky tomu získáte k datům další užitečné informace:
244
+
245
+ $ git log --left-right master...experiment
246
+ < F
247
+ < E
248
+ > D
249
+ > C
250
+
251
+ Pomocí těchto nástrojů můžete v systému Git daleko snáze specifikovat, kterou revizi nebo které revize chcete zobrazit.
252
+
253
+ ## Interaktivní příprava k zapsání ##
254
+
255
+ Git nabízí také celou řadu skriptů, které vám mohou usnadnit provádění příkazů zadávaných v příkazovém řádku. V této části se podíváme na několik interaktivních příkazů, které vám mohou pomoci snadno určit, na jaké kombinace a části souborů má být omezena konkrétní revize. Tyto nástroje se vám mohou velmi hodit, jestliže upravujete několik souborů a rozhodnete se, že tyto změny zapíšete raději do několika specializovaných revizí než do jedné velké nepřehledné. Tímto způsobem zajistíte, že budou vaše revize logicky oddělenými sadami změn, jež mohou vaši spolupracovníci snadno zkontrolovat.
256
+ Spustíte-li příkaz `git add` s parametrem `-i` nebo `--interactive`, přejde Git do interaktivního režimu shellu a zobrazí zhruba následující:
257
+
258
+ $ git add -i
259
+ staged unstaged path
260
+ 1: unchanged +0/-1 TODO
261
+ 2: unchanged +1/-1 index.html
262
+ 3: unchanged +5/-1 lib/simplegit.rb
263
+
264
+ *** Commands ***
265
+ 1: status 2: update 3: revert 4: add untracked
266
+ 5: patch 6: diff 7: quit 8: help
267
+ What now>
268
+
269
+ Vidíte, že tento příkaz vám poskytne podstatně odlišný pohled na vaši oblast připravených změn. Stejné informace, i když o něco stručnější a hutnější, získáte také příkazem `git status`. Tento příkaz vypíše všechny změny, které jste připravili k zapsání, na levé straně, nepřipravené změny na pravé.
270
+
271
+ Za seznamem změn následuje část Commands (Příkazy). Tady můžete provádět celou řadu věcí, včetně přípravy souborů k zapsání, vracení připravených souborů, přípravy částí souborů, přidávání nesledovaných souborů a prohlížení změn v připravených souborech.
272
+
273
+ ### Příprava souborů k zapsání a jejich vracení ###
274
+
275
+ Zadáte-li na výzvu `What now>` (Co teď) odpověď `2` nebo `u`, skript se vás zeptá, které soubory chcete připravit k zapsání:
276
+
277
+ What now> 2
278
+ staged unstaged path
279
+ 1: unchanged +0/-1 TODO
280
+ 2: unchanged +1/-1 index.html
281
+ 3: unchanged +5/-1 lib/simplegit.rb
282
+ Update>>
283
+
284
+ Jestliže chcete připravit k zapsání soubory TODO a index.html, zadejte příslušná čísla:
285
+
286
+ Update>> 1,2
287
+ staged unstaged path
288
+ * 1: unchanged +0/-1 TODO
289
+ * 2: unchanged +1/-1 index.html
290
+ 3: unchanged +5/-1 lib/simplegit.rb
291
+ Update>>
292
+
293
+ Znak `*` vedle souborů znamená, že je soubor vybrán jako připravený k zapsání. Jestliže na výzvu `Update>>` nic nezadáte a stisknete klávesu Enter, Git vezme všechny vybrané soubory a připraví je k zapsání:
294
+
295
+ Update>>
296
+ updated 2 paths
297
+
298
+ *** Commands ***
299
+ 1: status 2: update 3: revert 4: add untracked
300
+ 5: patch 6: diff 7: quit 8: help
301
+ What now> 1
302
+ staged unstaged path
303
+ 1: +0/-1 nothing TODO
304
+ 2: +1/-1 nothing index.html
305
+ 3: unchanged +5/-1 lib/simplegit.rb
306
+
307
+ Jak vidíte, soubory TODO a index.html jsou připraveny k zapsání, soubor simplegit.rb nikoli. Chcete-li v tuto chvíli vrátit soubor TODO z oblasti připravených změn, použijte parametr `3` nebo `r` (jako „revert“ neboli „vrátit“):
308
+
309
+ *** Commands ***
310
+ 1: status 2: update 3: revert 4: add untracked
311
+ 5: patch 6: diff 7: quit 8: help
312
+ What now> 3
313
+ staged unstaged path
314
+ 1: +0/-1 nothing TODO
315
+ 2: +1/-1 nothing index.html
316
+ 3: unchanged +5/-1 lib/simplegit.rb
317
+ Revert>> 1
318
+ staged unstaged path
319
+ * 1: +0/-1 nothing TODO
320
+ 2: +1/-1 nothing index.html
321
+ 3: unchanged +5/-1 lib/simplegit.rb
322
+ Revert>> [enter]
323
+ reverted one path
324
+
325
+ Pokud se nyní znovu podíváte na stav Git souboru TODO, uvidíte, že už není připraven k zapsání:
326
+
327
+ *** Commands ***
328
+ 1: status 2: update 3: revert 4: add untracked
329
+ 5: patch 6: diff 7: quit 8: help
330
+ What now> 1
331
+ staged unstaged path
332
+ 1: unchanged +0/-1 TODO
333
+ 2: +1/-1 nothing index.html
334
+ 3: unchanged +5/-1 lib/simplegit.rb
335
+
336
+ Chcete-li zobrazit výpis diff připravených souborů, použijte příkaz `6` nebo `d` (jako „diff“). Příkaz zobrazí seznam připravených souborů. Můžete vybrat ty soubory, pro něž chcete zobrazit rozdíly připravených změn. Je to prakticky totéž, jako byste na příkazovém řádku zadali příkaz `git diff --cached`:
337
+
338
+ *** Commands ***
339
+ 1: status 2: update 3: revert 4: add untracked
340
+ 5: patch 6: diff 7: quit 8: help
341
+ What now> 6
342
+ staged unstaged path
343
+ 1: +1/-1 nothing index.html
344
+ Review diff>> 1
345
+ diff --git a/index.html b/index.html
346
+ index 4d07108..4335f49 100644
347
+ --- a/index.html
348
+ +++ b/index.html
349
+ @@ -16,7 +16,7 @@ Date Finder
350
+
351
+ <p id="out">...</p>
352
+
353
+ -<div id="footer">contact : support@github.com</div>
354
+ +<div id="footer">contact : email.support@github.com</div>
355
+
356
+ <script type="text/javascript">
357
+
358
+ Pomocí těchto základních příkazů můžete použít režim interaktivního přidávání, a snáze tak ovládat svou oblast připravených změn.
359
+
360
+ ### Příprava záplat ###
361
+
362
+ Git také může připravit k zapsání pouze určité části souborů a ignorovat jejich zbytek. Pokud například provedete dvě změny v souboru simplegit.rb a chcete k zapsání připravit pouze jednu z nich, není to v systému Git žádný problém. Na interaktivní výzvu zadejte příkaz `5` nebo `p` (jako „patch“ – tedy záplata). Git se vás zeptá, které soubory chcete částečně připravit. Pro každou část vybraných souborů pak zobrazí komplexy (hunks) rozdílů diff daného souboru a u každého z nich se vás zeptá, jestli si ho přejete připravit k zapsání:
363
+
364
+ diff --git a/lib/simplegit.rb b/lib/simplegit.rb
365
+ index dd5ecc4..57399e0 100644
366
+ --- a/lib/simplegit.rb
367
+ +++ b/lib/simplegit.rb
368
+ @@ -22,7 +22,7 @@ class SimpleGit
369
+ end
370
+
371
+ def log(treeish = 'master')
372
+ - command("git log -n 25 #{treeish}")
373
+ + command("git log -n 30 #{treeish}")
374
+ end
375
+
376
+ def blame(path)
377
+ Stage this hunk [y,n,a,d,/,j,J,g,e,?]?
378
+
379
+ V tomto se nabízí celá řada možností. Zadáte-li znak `?`, zobrazí se seznam možností, které máte k dispozici.
380
+
381
+ Stage this hunk [y,n,a,d,/,j,J,g,e,?]? ?
382
+ y - stage this hunk
383
+ n - do not stage this hunk
384
+ a - stage this and all the remaining hunks in the file
385
+ d - do not stage this hunk nor any of the remaining hunks in the file
386
+ g - select a hunk to go to
387
+ / - search for a hunk matching the given regex
388
+ j - leave this hunk undecided, see next undecided hunk
389
+ J - leave this hunk undecided, see next hunk
390
+ k - leave this hunk undecided, see previous undecided hunk
391
+ K - leave this hunk undecided, see previous hunk
392
+ s - split the current hunk into smaller hunks
393
+ e - manually edit the current hunk
394
+ ? - print help
395
+
396
+ V českém překladu:
397
+
398
+ Připravit tento soubor změn [y,n,a,d,/,j,J,g,e,?]? ?
399
+ y - připravit soubor změn k zapsání
400
+ n - nepřipravovat soubor změn k zapsání
401
+ a - připravit tento soubor změn i všechny ostatní komplexy v souboru
402
+ d - nepřipravovat tento soubor změn ani žádné další komplexy v souboru
403
+ g - vybrat soubor změn, k němuž má systém přejít
404
+ / - najít soubor změn odpovídající danému regulárnímu výrazu
405
+ j - nechat tento soubor změn nerozhodnutý, zobrazit další nerozhodnutý
406
+ J - nechat tento soubor změn nerozhodnutý, zobrazit další komplex
407
+ j - nechat tento soubor změn nerozhodnutý, zobrazit předchozí nerozhodnutý
408
+ J - nechat tento soubor změn nerozhodnutý, zobrazit předchozí komplex
409
+ s - rozdělit aktuální soubor změn do menších komplexů
410
+ e - ručně editovat aktuální soubor změn
411
+ ? - nápověda
412
+
413
+ Chcete-li připravit k zapsání jednotlivé komplexy, většinou zadáte `y` nebo `n`. Přesto se vám může někdy hodit i možnost připravit všechny komplexy v určitých souborech nebo přeskočení komplexu, k němuž se vrátíte později. Připravíte-li k zapsání jednu část souboru a druhou nikoli, bude výstup příkazu status vypadat asi takto:
414
+
415
+ What now> 1
416
+ staged unstaged path
417
+ 1: unchanged +0/-1 TODO
418
+ 2: +1/-1 nothing index.html
419
+ 3: +1/-1 +4/-0 lib/simplegit.rb
420
+
421
+ Zajímavý je stav souboru simplegit.rb. Oznamuje vám, že několik řádků je připravených k zapsání a několik není. Soubor je částečně připraven k zapsání. V tomto okamžiku můžete ukončit skript interaktivního přidávání a spustit příkaz `git commit`, jímž zapíšete částečně připravené soubory.
422
+
423
+ K částečné přípravě souboru ostatně nemusíte být nutně v režimu interaktivního přidávání. Stejný skript spustíte také příkazem `git add -p` nebo `git add --patch` z příkazového řádku.
424
+
425
+ ## Odložení ##
426
+
427
+ Až budete pracovat na některé části svého projektu, často vám může připadat, že je vaše práce poněkud neuspořádaná a vy budete třeba chtít přepnout větve a pracovat na chvíli na něčem jiném. Problém je, že nebudete chtít zapsat revizi nehotové práce, budete se k ní chtít vrátit později. Řešením této situace je odložení (stashing) příkazem `git stash`.
428
+
429
+ Odložení vezme neuspořádaný stav vašeho pracovního adresáře – tj. změněné sledované soubory a změny připravené k zapsání – a uloží ho do zásobníku nehotových změn, který můžete kdykoli znovu aplikovat.
430
+
431
+ ### Odložení práce ###
432
+
433
+ Pro názornost uvažujme situaci, že ve svém projektu začnete pracovat na několika souborech a jednu z provedených změn připravíte k zapsání. Spustíte-li příkaz `git status`, uvidíte neuspořádaný stav svého projektu:
434
+
435
+ $ git status
436
+ # On branch master
437
+ # Changes to be committed:
438
+ # (use "git reset HEAD <file>..." to unstage)
439
+ #
440
+ # modified: index.html
441
+ #
442
+ # Changes not staged for commit:
443
+ # (use "git add <file>..." to update what will be committed)
444
+ #
445
+ # modified: lib/simplegit.rb
446
+ #
447
+
448
+ Nyní chcete přepnout na jinou větev, ale nechcete zapsat změny, na nichž jste dosud pracovali – proto změny odložíte. Chcete-li do zásobníku odeslat nový odklad, spusťte příkaz `git stash`:
449
+
450
+ $ git stash
451
+ Saved working directory and index state \
452
+ "WIP on master: 049d078 added the index file"
453
+ HEAD is now at 049d078 added the index file
454
+ (To restore them type "git stash apply")
455
+
456
+ Váš pracovní adresář se vyčistil:
457
+
458
+ $ git status
459
+ # On branch master
460
+ nothing to commit, working directory clean
461
+
462
+ Nyní můžete bez obav přepnout větve a pracovat na jiném úkolu, vaše změny byly uloženy do zásobníku. Chcete-li se podívat, které soubory jste odložili, spusťte příkaz `git stash list`:
463
+
464
+ $ git stash list
465
+ stash@{0}: WIP on master: 049d078 added the index file
466
+ stash@{1}: WIP on master: c264051 Revert "added file_size"
467
+ stash@{2}: WIP on master: 21d80a5 added number to log
468
+
469
+ V tomto případě byly už dříve provedeny dva další odklady, a máte tak k dispozici tři různé odklady. Naposledy odložené soubory můžete znovu aplikovat příkazem, který byl uveden už v nápovědě ve výstupu původního příkazu stash: `git stash apply`. Chcete-li aplikovat některý ze starších odkladů, můžete ho určit na základě jeho označení, např. `git stash apply stash@{2}`. Pokud u příkazu neoznačíte konkrétní odklad, Git se automaticky pokusí aplikovat ten nejnovější:
470
+
471
+ $ git stash apply
472
+ # On branch master
473
+ # Changes not staged for commit:
474
+ # (use "git add <file>..." to update what will be committed)
475
+ #
476
+ # modified: index.html
477
+ # modified: lib/simplegit.rb
478
+ #
479
+
480
+ Jak vidíte, Git se pokusí obnovit změněné soubory, které jste nezapsali a uložili při odkladu. V tomto případě jste měli čistý pracovní adresář, když jste se pokusili odklad aplikovat. Pokusili jste se ho aplikovat na stejnou větev, z níž jste ho uložili. K úspěšnému odkladu však není nezbytně nutné, aby byl pracovní adresář čistý ani abyste ho aplikovali na stejnou větev. Odklad můžete uložit na jedné větvi, později přepnout na jinou větev a aplikovat změny tam. Když aplikujete odklad, můžete mít v pracovním adresáři také změněné a nezapsané soubory. Nebude-li něco aplikováno čistě, Git vám oznámí konflikty při slučování.
481
+
482
+ Změny byly znovu aplikovány na vaše soubory, ale soubor, který jste předtím připravili k zapsání, nebyl znovu připraven. Chcete-li, aby se příkaz pokusil znovu aplikovat i změny připravené k zapsání, musíte zadat příkaz `git stash apply` s parametrem `--index`. Pokud jste spustili příkaz v této podobě, vrátili jste se zpět na svou původní pozici:
483
+
484
+ $ git stash apply --index
485
+ # On branch master
486
+ # Changes to be committed:
487
+ # (use "git reset HEAD <file>..." to unstage)
488
+ #
489
+ # modified: index.html
490
+ #
491
+ # Changes not staged for commit:
492
+ # (use "git add <file>..." to update what will be committed)
493
+ #
494
+ # modified: lib/simplegit.rb
495
+ #
496
+
497
+ Parametr apply se pouze pokusí aplikovat odloženou práci, ta zůstává uložena ve vašem zásobníku. Chcete-li ji odstranit, spusťte příkaz `git stash drop` s názvem odkladu, který má být odstraněn:
498
+
499
+ $ git stash list
500
+ stash@{0}: WIP on master: 049d078 added the index file
501
+ stash@{1}: WIP on master: c264051 Revert "added file_size"
502
+ stash@{2}: WIP on master: 21d80a5 added number to log
503
+ $ git stash drop stash@{0}
504
+ Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43)
505
+
506
+ Můžete také spustit příkaz `git stash pop`, jímž odklad aplikujete a současně ho odstraníte ze zásobníku.
507
+
508
+ ### Odvolání odkladu ###
509
+
510
+ V některých případech můžete chtít aplikovat odložené změny, udělat nějakou práci, a pak odvolat změny, které byly v odkladu původně. Git nenabízí žádný příkaz ve smyslu `stash unapply`, ovšem je možné použít reverzní aplikaci patche reprezentujícího odklad:
511
+
512
+ $ git stash show -p stash@{0} | git apply -R
513
+
514
+ Jestliže nespecifikujete konkrétní odklad, Git předpokládá odklad poslední:
515
+
516
+ $ git stash show -p | git apply -R
517
+
518
+ Můžete si také vytvořit alias a do svého gitu přidat například příkaz `stash-unapply`:
519
+
520
+ $ git config --global alias.stash-unapply '!git stash show -p | git apply -R'
521
+ $ git stash apply
522
+ $ #... work work work
523
+ $ git stash-unapply
524
+
525
+ ### Vytvoření větve z odkladu ###
526
+
527
+ Jestliže odložíte část své práce, necháte ji určitou dobu v zásobníku a budete pokračovat ve větvi, z níž jste práci odložili, můžete mít problémy s opětovnou aplikací odkladu. Pokud se příkaz apply pokusí změnit soubor, který jste mezitím ručně změnili jinak, dojde ke konfliktu při slučování, který budete muset vyřešit. Pokud byste uvítali jednodušší způsob, jak znovu otestovat odložené změny, můžete spustit příkaz `git stash branch`, který vytvoří novou větev, stáhne do ní revizi, na níž jste se nacházeli při odložení práce, a aplikuje na ni vaši práci. Proběhne-li aplikace úspěšně, Git odklad odstraní:
528
+
529
+ $ git stash branch testchanges
530
+ Switched to a new branch "testchanges"
531
+ # On branch testchanges
532
+ # Changes to be committed:
533
+ # (use "git reset HEAD <file>..." to unstage)
534
+ #
535
+ # modified: index.html
536
+ #
537
+ # Changes not staged for commit:
538
+ # (use "git add <file>..." to update what will be committed)
539
+ #
540
+ # modified: lib/simplegit.rb
541
+ #
542
+ Dropped refs/stash@{0} (f0dfc4d5dc332d1cee34a634182e168c4efc3359)
543
+
544
+ Jedná se o příjemný a jednoduchý způsob, jak obnovit odloženou práci a pokračovat na ní v nové větvi.
545
+
546
+ ## Přepis historie ##
547
+
548
+ Při práci se systémem Git možná budete z nějakého důvodu čas od času potřebovat poopravit historii revizí. Jednou ze skvělých možností, které vám Git nabízí, jsou rozhodnutí na poslední chvíli. Jaké soubory budou součástí jaké revize? To můžete rozhodnout až těsně před tím, než soubory zapíšete z oblasti připravených změn. Můžete se rozmyslet, že jste na něčem ještě nechtěli pracovat, a použít možnost odložení. A stejně tak můžete přepsat už jednou zapsané revize. Budou vypadat, jako by byly zapsány v jiné podobě. K této možnosti patří změna pořadí revizí, změny ve zprávách nebo úprava souborů v revizích, komprimace i dělení revizí nebo třeba jejich úplné odstranění. Všechno toto můžete provést, dokud nezačnete sdílet revize s ostatními.
549
+
550
+ V této části se dozvíte, jak se tyto velmi užitečné úkony provádějí, abyste mohli svou historii revizí před zveřejněním upravit podle svých představ.
551
+
552
+ ### Změna poslední revize ###
553
+
554
+ Změna poslední revize je pravděpodobně nejobvyklejším způsobem přepsání historie, který budete provádět. Na poslední revizi budete často chtít měnit dvě věci: zprávu k revizi nebo čerstvě zapsaný snímek, v němž budete chtít přidat, změnit nebo odstranit soubory.
555
+
556
+ Chcete-li pouze změnit zprávu k poslední revizi, je to velmi jednoduché:
557
+
558
+ $ git commit --amend
559
+
560
+ Tím se přesunete do textového editoru, v němž bude otevřena vaše poslední zpráva k revizi. Nyní ji můžete upravit. Po uložení změn a zavření editoru zapíše editor novou revizi, která bude obsahovat upravenou zprávu a která bude vaší novou poslední revizí.
561
+
562
+ Pokud jste zapsali revizi a uvědomíte si, že jste např. zapomněli přidat nově vytvořený soubor, a proto byste chtěli zapsaný snímek změnit (tedy přidat nebo změnit soubory), je postup ke změně v podstatě stejný. Změny, které chcete zapsat, připravíte tím způsobem, že upravíte příslušné soubory a použijete na ně příkaz `git add`, resp. `git rm`. Příkaz `git commit --amend` poté vezme vaši oblast připravených změn v aktuální podobě a vytvoří snímek nové revize.
563
+
564
+ Tady byste měli být opatrní, protože oprava revize změní také její hodnotu SHA-1. Je to něco jako malé přeskládání – neopravujte poslední revizi, pokud jste ji už odeslali.
565
+
566
+ ### Změna několika zpráv k revizím ###
567
+
568
+ Chcete-li změnit revizi, která leží hlouběji ve vaší historii, budete muset sáhnout po složitějších nástrojích. Git nemá zvláštní nástroj k úpravě historie, ale můžete využít nástroje přeskládání, jímž přeskládáte sérii revizí na revizi HEAD, na níž se původně zakládaly. Revize není třeba přesouvat jinam. S interaktivním nástrojem přeskládání pak můžete zastavit po každé revizi, kterou chcete upravit, a změnit u ní zprávu, přidat soubory nebo cokoli dalšího. Interaktivní režim přeskládání spustíte příkazem `git rebase` s parametrem `-i`. Musíte specifikovat, jak hluboko do historie se chcete vrátit a přepisovat revize. K příkazu proto musíte zadat, na jakou revizi si přejete přeskládání provést.
569
+
570
+ Pokud chcete například změnit zprávy u posledních tří revizí nebo jakoukoli zprávu k revizi z této skupiny, přidejte jako parametr k příkazu `git rebase -i` rodiče poslední revize, kterou chcete upravovat, v tomto případě tedy `HEAD~2^` nebo `HEAD~3`. Snazší k zapamatování je varianta s výrazem `~3`, neboť se pokoušíte upravit poslední tři revize. Nezapomeňte ale, že tím ve skutečnosti označujete čtvrtou revizi od konce, tedy rodiče poslední revize, kterou chcete upravit:
571
+
572
+ $ git rebase -i HEAD~3
573
+
574
+ Mějte na paměti, že se stále jedná o příkaz přeskládání a každá revize zahrnutá v intervalu `HEAD~3..HEAD` bude přepsána, ať už její zprávu změníte, nebo ponecháte. Neměňte tímto způsobem žádné revize, které už jste odeslali na centrální server, způsobili byste tím problémy ostatním vývojářům, kteří by se museli potýkat s jinou verzí téže změny.
575
+
576
+ Spuštěním tohoto příkazu otevřete textový editor se seznamem revizí zhruba v této podobě:
577
+
578
+ pick f7f3f6d changed my name a bit
579
+ pick 310154e updated README formatting and added blame
580
+ pick a5f4a0d added cat-file
581
+
582
+ # Rebase 710f0f8..a5f4a0d onto 710f0f8
583
+ #
584
+ # Commands:
585
+ # p, pick = use commit
586
+ # r, reword = use commit, but edit the commit message
587
+ # e, edit = use commit, but stop for amending
588
+ # s, squash = use commit, but meld into previous commit
589
+ # f, fixup = like "squash", but discard this commit's log message
590
+ # x, exec = run command (the rest of the line) using shell
591
+ #
592
+ # These lines can be re-ordered; they are executed from top to bottom.
593
+ #
594
+ # If you remove a line here THAT COMMIT WILL BE LOST.
595
+ #
596
+ # However, if you remove everything, the rebase will be aborted.
597
+ #
598
+ # Note that empty commits are commented out
599
+
600
+ Tady bychom chtěli upozornit, že revize jsou uvedeny v opačném pořadí, než jste zvyklí v případě příkazu `log`. Po spuštění příkazu `log` by se zobrazilo následující:
601
+
602
+ $ git log --pretty=format:"%h %s" HEAD~3..HEAD
603
+ a5f4a0d added cat-file
604
+ 310154e updated README formatting and added blame
605
+ f7f3f6d changed my name a bit
606
+
607
+ Všimněte si, že se pořadí obrátilo. V interaktivním režimu přeskládání se nyní spustí skript. Začne na revizi, kterou jste označili na příkazovém řádku (`HEAD~3`), a přehraje změny provedené v každé z těchto revizí od shora dolů. Seznam uvádí nejstarší revizi nahoře z toho důvodu, že to bude první revize, kterou příkaz přehraje.
608
+
609
+ Skript je třeba upravit tak, aby zastavil na revizi, v níž chcete provést změny. Změňte proto slovo pick na edit pro každou z revizí, po níž má skript zastavit. Chcete-li například změnit pouze zprávu ke třetí revizi, změňte soubor následovně:
610
+
611
+ edit f7f3f6d changed my name a bit
612
+ pick 310154e updated README formatting and added blame
613
+ pick a5f4a0d added cat-file
614
+
615
+ Po uložení změn a zavření editoru vás Git vrátí zpět na poslední revizi v seznamu a zobrazí vám příkazový řádek s touto zprávou:
616
+
617
+ <!-- This is actually weird, as the SHA-1 of 7482e0d is not present in the list,
618
+ nor is the commit message. Please review
619
+ -->
620
+
621
+ $ git rebase -i HEAD~3
622
+ Stopped at 7482e0d... updated the gemspec to hopefully work better
623
+ You can amend the commit now, with
624
+
625
+ git commit --amend
626
+
627
+ Once you’re satisfied with your changes, run
628
+
629
+ git rebase --continue
630
+
631
+ Tyto instrukce vám sdělují, že nyní můžete upravit revizi příkazem git commit --amend, a až budete se změnami hotovi, spustit příkaz git rebase --continue. Zadejme tedy:
632
+
633
+ $ git commit --amend
634
+
635
+ Změňte zprávu k revizi a zavřete textový editor. Poté spusťte příkaz:
636
+
637
+ $ git rebase --continue
638
+
639
+ Tento příkaz automaticky aplikuje zbývající dvě revize. Tím je celý proces dokončen. Změníte-li výraz pick na edit na více řádcích, můžete tyto kroky opakovat pro každou revizi, u níž jste změnu provedli. Git pokaždé zastaví, nechá vás revizi upravit, a až budete hotovi, bude pokračovat.
640
+
641
+ ### Změna pořadí revizí ###
642
+
643
+ Interaktivní přeskládání můžete použít rovněž ke změně pořadí revizí nebo k jejich odstranění. Budete-li chtít odstranit revizi „added cat-file“ a současně změnit pořadí, v němž se vyskytují zbývající dvě revize, změňte skript přeskládání z podoby:
644
+
645
+ pick f7f3f6d changed my name a bit
646
+ pick 310154e updated README formatting and added blame
647
+ pick a5f4a0d added cat-file
648
+
649
+ na:
650
+
651
+ pick 310154e updated README formatting and added blame
652
+ pick f7f3f6d changed my name a bit
653
+
654
+ Jakmile uložíte změny a zavřete editor, Git vrátí vaši větev zpět na rodiče těchto revizí, aplikuje revizi `310154e`, po ní revizi `f7f3f6d` a zastaví. Jednoduše jste změnili pořadí těchto revizí a zároveň jste zcela odstranili revizi „added cat-file“.
655
+
656
+ ### Komprimace revize ###
657
+
658
+ Další možností, jak lze využít interaktivního nástroje přeskládání, je komprimace série revizí do jediné revize. Skript vám ve zprávě k přeskládání podává užitečné instrukce:
659
+
660
+ #
661
+ # Commands:
662
+ # p, pick = use commit
663
+ # r, reword = use commit, but edit the commit message
664
+ # e, edit = use commit, but stop for amending
665
+ # s, squash = use commit, but meld into previous commit
666
+ # f, fixup = like "squash", but discard this commit's log message
667
+ # x, exec = run command (the rest of the line) using shell
668
+ #
669
+ # These lines can be re-ordered; they are executed from top to bottom.
670
+ #
671
+ # If you remove a line here THAT COMMIT WILL BE LOST.
672
+ #
673
+ # However, if you remove everything, the rebase will be aborted.
674
+ #
675
+ # Note that empty commits are commented out
676
+
677
+ Zadáte-li místo pick nebo edit instrukci pro komprimaci squash, Git aplikuje změnu na tomto řádku a změnu těsně před ní a zároveň sloučí dohromady obě zprávy k revizím. Chcete-li tedy vytvořit jedinou revizi z těchto tří revizí, bude skript vypadat takto:
678
+
679
+ pick f7f3f6d changed my name a bit
680
+ squash 310154e updated README formatting and added blame
681
+ squash a5f4a0d added cat-file
682
+
683
+ Po uložení změn a zavření editoru aplikuje Git všechny tři změny a znovu otevře textový editor, abyste sloučili všechny zprávy k revizím:
684
+
685
+ # This is a combination of 3 commits.
686
+ # The first commit's message is:
687
+ changed my name a bit
688
+
689
+ # This is the 2nd commit message:
690
+
691
+ updated README formatting and added blame
692
+
693
+ # This is the 3rd commit message:
694
+
695
+ added cat-file
696
+
697
+ Po uložení zprávy budete mít jedinou revizi, která bude obsahovat všechny změny předchozích tří revizí.
698
+
699
+ ### Rozdělení revize ###
700
+
701
+ Rozdělení revize vrátí všechny změny v revizi obsažené a po částech je znovu připraví a zapíše do tolika revizí, kolik určíte jako konečný počet. Řekněme, že chcete rozdělit třeba prostřední ze svých tří revizí. Revizi „updated README formatting and added blame“ chcete rozdělit do dvou jiných: „updated README formatting“ jako první a „added blame“ jako druhou. Můžete to provést pomocí skriptu `rebase -i`. U revize, kterou si přejete rozdělit, změňte instrukci na edit:
702
+
703
+ pick f7f3f6d changed my name a bit
704
+ edit 310154e updated README formatting and added blame
705
+ pick a5f4a0d added cat-file
706
+
707
+ Až vás poté skript přesune na příkazový řádek, resetujete revizi, vezmete změny, které jste resetovali, a vytvoříte z nich několik dílčích revizí. Až uložíte změny a zavřete editor, Git se vrátí na rodiče první revize ve vašem seznamu, aplikuje první revizi (`f7f3f6d`), aplikuje druhou revizi (`310154e`) a přesune vás na konzoli. Tam můžete vytvořit smíšený reset této revize pomocí příkazu `git reset HEAD^`, který efektivně vrátí všechny změny v revizi a ponechá změněné soubory nepřipraveny k zapsání. Nyní můžete připravit a zapsat soubory. Až budete mít jednotlivé revize hotové a budete spokojeni s jejich podobou, zadejte příkaz `git rebase --continue`:
708
+
709
+ $ git reset HEAD^
710
+ $ git add README
711
+ $ git commit -m 'updated README formatting'
712
+ $ git add lib/simplegit.rb
713
+ $ git commit -m 'added blame'
714
+ $ git rebase --continue
715
+
716
+ Git aplikuje poslední revizi (`a5f4a0d`) ve skriptu. Vaše historie bude vypadat takto:
717
+
718
+ $ git log -4 --pretty=format:"%h %s"
719
+ 1c002dd added cat-file
720
+ 9b29157 added blame
721
+ 35cfb2b updated README formatting
722
+ f3cc40e changed my name a bit
723
+
724
+ Také v tomto případě se změní hodnoty SHA všech revizí v seznamu, a proto se nejprve ujistěte, že seznam neobsahuje žádné revize, které jste už odeslali do sdíleného repozitáře.
725
+
726
+ ### Pitbul mezi příkazy: filter-branch ###
727
+
728
+ Existuje ještě další možnost přepisu historie, kterou vám Git nabízí pro případy, kdy potřebujete skriptovatelným způsobem přepsat větší počet revizí, např. globálně změnit e-mailovou adresu nebo odstranit jeden soubor ze všech revizí. Příkaz pro tento případ je `filter-branch`. Dokáže přepsat velké části vaší historie, a proto byste ho určitě neměli používat, pokud už byl váš projekt zveřejněn a ostatní uživatelé už založili svou práci na revizích, které hodláte přepsat. Příkaz přesto může být velmi užitečný. Dále poznáte několik běžných situací, v nichž ho lze použít, a získáte tak představu, co všechno příkaz dovede.
729
+
730
+ #### Odstranění souboru ze všech revizí ####
731
+
732
+ Toto je opravdu velmi častá situace. Někdo příkazem `git add .` bezmyšlenkovitě zapsal obří binární soubor a vy ho chcete odstranit ze všech revizí. Nebo jste omylem zapsali soubor obsahující vaše heslo, ale chcete, aby byl váš projekt veřejný. Nástrojem, který hledáte k opravení celé historie, je `filter-branch`. Pro odstranění souboru s názvem passwords.txt z celé historie můžete použít parametr `--tree-filter`, který přidáte k příkazu `filter-branch`:
733
+
734
+ $ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD
735
+ Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21)
736
+ Ref 'refs/heads/master' was rewritten
737
+
738
+ Parametr `--tree-filter` spustí zadaný příkaz po každém checkoutu projektu a znovu zapíše jeho výsledky. V tomto případě odstraníte soubor s názvem passwords.txt ze všech snímků, ať v nich existuje, nebo neexistuje. Chcete-li odstranit všechny nedopatřením zapsané záložní soubory editoru, můžete spustit zhruba toto: `git filter-branch --tree-filter "rm -f *~" HEAD`.
739
+
740
+ Uvidíte, jak Git přepisuje stromy a revize a poté přemístí ukazatel větve na konec. Většinou se vyplatí provádět toto všechno v testovací větvi a k tvrdému resetu hlavní větve přistoupit až poté, co se ujistíte, že výsledek odpovídá vašim očekáváním. Chcete-li spustit příkaz `filter-branch` na všech větvích, zadejte k příkazu parametr `--all`.
741
+
742
+ #### Povýšení podadresáře na nový kořenový adresář ####
743
+
744
+ Předpokládejme, že jste dokončili import z jiného systému ke správě zdrojového kódu a máte podadresáře, které nedávají žádný smysl (trunk, tags apod.). Chcete-li udělat z podadresáře `trunk` nový kořenový adresář projektu pro všechny revize, i s tím vám pomůže příkaz `filter-branch`:
745
+
746
+ $ git filter-branch --subdirectory-filter trunk HEAD
747
+ Rewrite 856f0bf61e41a27326cdae8f09fe708d679f596f (12/12)
748
+ Ref 'refs/heads/master' was rewritten
749
+
750
+ Vaším nový kořenovým adresářem je nyní obsah podadresáře `trunk`. Git také automaticky odstraní revize, které nemají na podadresář žádný vliv.
751
+
752
+ #### Globální změna e-mailové adresy ####
753
+
754
+ Dalším častým případem bývá, že uživatel zapomene spustit příkaz `git config` a nastavit své jméno a e-mailovou adresu, než začne se systémem Git pracovat. Stejně tak se může stát, že budete chtít převést pracovní projekt na otevřený zdrojový kód a změnit všechny své pracovní e-mailové adresy na soukromé. V obou těchto případech můžete změnit e-mailové adresy v několika revizích hromadně příkazem `filter-branch`. Měli byste být opatrní, abyste změnili jen e-mailové adresy, které jsou opravdu vaše. Použijte proto parametr `--commit-filter`:
755
+
756
+ $ git filter-branch --commit-filter '
757
+ if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ];
758
+ then
759
+ GIT_AUTHOR_NAME="Scott Chacon";
760
+ GIT_AUTHOR_EMAIL="schacon@example.com";
761
+ git commit-tree "$@";
762
+ else
763
+ git commit-tree "$@";
764
+ fi' HEAD
765
+
766
+ Příkaz projde a přepíše všechny revize tak, aby obsahovaly novou adresu. Protože revize obsahují hodnoty SHA-1 svých rodičů, změní tento příkaz SHA všech revizí ve vaší historii, ne pouze těch, které mají odpovídající e-mailovou adresu.
767
+
768
+ ### Velmi rychlá a nebezpečná zbraň: Big Friendly Giant Repo Cleaner (BFG) ###
769
+
770
+ [Roberto Tyley](https://github.com/rtyley) vytvořil nástroj, který se funkčností podobá `filter-branch` a nazval jej BFG. (Celý název lze doslova přeložit jako Velký, přátelský, obří čistič repozitáře --- představte si pod tím, co chcete.) BFG neumí tolik věcí jako `filter-branch`, ale je *velmi* rychlý. Pro velké repozitáře to může být zásadní rozdíl. Pokud lze vámi zamýšlenou změnu pomocí BFG provést a pokud máte problémy s výkonností prostředí, pak byste o použití tohoto nástroje měli uvažovat.
771
+
772
+ Podrobnosti naleznete na stránkách [BFG](http://rtyley.github.io/bfg-repo-cleaner/).
773
+
774
+ ## Ladění v systému Git ##
775
+
776
+ Git také nabízí několik nástrojů, které vám pomohou ladit problémy v projektech. Protože je Git navržen tak, aby pracoval téměř s jakýmkoli typem projektu, jsou tyto nástroje velmi univerzální. Často vám mohou pomoci odhalit vzniklou chybu nebo problém.
777
+
778
+ ### Anotace souboru ###
779
+
780
+ Zjistíte-li ve svém zdrojovém kódu chybu a chcete vědět, kdy a jak vznikla, je často nejlepším nástrojem anotace souboru (file annotation). Ukáže vám, při které revizi byly jednotlivé řádky každého souboru naposledy změněny. Pokud zjistíte, že některá metoda ve vašem kódu obsahuje chybu, můžete soubor anotovat příkazem `git blame`, který u každého řádku metody zobrazí, kdo a kdy ho naposledy upravil. Následující příklad používá parametr `-L`, který omezí výstup na řádky 12 až 22:
781
+
782
+ $ git blame -L 12,22 simplegit.rb
783
+ ^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 12) def show(tree = 'master')
784
+ ^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 13) command("git show #{tree}")
785
+ ^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 14) end
786
+ ^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 15)
787
+ 9f6560e4 (Scott Chacon 2008-03-17 21:52:20 -0700 16) def log(tree = 'master')
788
+ 79eaf55d (Scott Chacon 2008-04-06 10:15:08 -0700 17) command("git log #{tree}")
789
+ 9f6560e4 (Scott Chacon 2008-03-17 21:52:20 -0700 18) end
790
+ 9f6560e4 (Scott Chacon 2008-03-17 21:52:20 -0700 19)
791
+ 42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 20) def blame(path)
792
+ 42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 21) command("git blame #{path}")
793
+ 42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 22) end
794
+
795
+ Všimněte si, že první pole je část hodnoty SHA-1 revize, v níž byl řádek naposled změněn. Další dvě pole jsou hodnoty získané z revize: jméno autora a datum, zapsané u této revize. Z toho vyčtete, kdo a kdy tento řádek upravil. Za tímto údajem následuje číslo řádku a obsah souboru. Všimněte si také řádků revize `^4832fe2`, které oznamují, že tyto řádky byly obsaženy v originální revizi tohoto souboru. Tato revize vznikla prvním přidáním tohoto souboru do projektu a tyto řádky zůstaly od té doby nezměněny. Je to trochu matoucí, protože jsme před chvílí viděli minimálně tři různé způsoby, jak Git používá znak `^` k modifikaci hodnoty SHA revize. Tady má tento znak jiný význam.
796
+
797
+ Další skvělou věcí na systému Git je, že explicitně nesleduje přejmenování souboru. Zaznamenává snímky a poté se snaží zjistit, co bylo později implicitně přejmenováno. Zajímavou funkcí je také to, že můžete systému Git zadat, aby zjistil všechny druhy přesouvání kódu. Zadáte-li k příkazu `git blame` parametr `-C`, Git zanalyzuje soubor, který anotujete, a pokud jednotlivé kousky kódu v něm obsažené pocházejí původně odjinud, pokusí se Git zjistit odkud. Nedávno jsem refaktoroval soubor s názvem `GITServerHandler.m` do několika jiných souborů, jeden z nich se jmenoval `GITPackUpload.m`. Když jsem zadal příkaz `GITPackUpload.m` s parametrem `-C`, dostal jsem informace, odkud původně pocházejí jednotlivé kousky kódu:
798
+
799
+ $ git blame -C -L 141,153 GITPackUpload.m
800
+ f344f58d GITServerHandler.m (Scott 2009-01-04 141)
801
+ f344f58d GITServerHandler.m (Scott 2009-01-04 142) - (void) gatherObjectShasFromC
802
+ f344f58d GITServerHandler.m (Scott 2009-01-04 143) {
803
+ 70befddd GITServerHandler.m (Scott 2009-03-22 144) //NSLog(@"GATHER COMMI
804
+ ad11ac80 GITPackUpload.m (Scott 2009-03-24 145)
805
+ ad11ac80 GITPackUpload.m (Scott 2009-03-24 146) NSString *parentSha;
806
+ ad11ac80 GITPackUpload.m (Scott 2009-03-24 147) GITCommit *commit = [g
807
+ ad11ac80 GITPackUpload.m (Scott 2009-03-24 148)
808
+ ad11ac80 GITPackUpload.m (Scott 2009-03-24 149) //NSLog(@"GATHER COMMI
809
+ ad11ac80 GITPackUpload.m (Scott 2009-03-24 150)
810
+ 56ef2caf GITServerHandler.m (Scott 2009-01-05 151) if(commit) {
811
+ 56ef2caf GITServerHandler.m (Scott 2009-01-05 152) [refDict setOb
812
+ 56ef2caf GITServerHandler.m (Scott 2009-01-05 153)
813
+
814
+ Tato funkce je opravdu užitečná. Normálně se jako původní revize zobrazí ta, kam jste kód zkopírovali, protože to bylo poprvé, kdy jste v daném souboru sáhli do těchto řádků. Git vám vyhledá původní revizi, kde jste tyto řádky napsali, dokonce i když jsou v jiném souboru.
815
+
816
+ ### Binární vyhledávání ###
817
+
818
+ Anotace souboru má smysl, pokud víte, kde problém hledat. Pokud nemáte ponětí, co může chybu způsobovat, a od posledního zaručeně funkčního stavu kódu byly zapsány desítky nebo stovky revizí, možná budete pomoc hledat raději u příkazu `git bisect`. Příkaz `bisect` zahájí binární vyhledávání ve vaší historii revizí a pomůže vám co nejrychleji identifikovat, která revize je původcem problému.
819
+
820
+ Řekněme, že jste právě odeslali vydání svého zdrojového kódu do produkčního prostředí, ale dostanete hlášení o chybě, která se ve vašem vývojovém prostředí nevyskytovala, a nemáte tušení, proč kód takto zlobí. Vrátíte se zpět ke svému kódu, a ukáže se, že dokážete problém reprodukovat, ne však identifikovat. K odhalení problému můžete použít příkaz bisect (tedy „rozpůlit“). Nejprve spustíte příkaz `git bisect start`, jímž celý proces zahájíte, a poté použijete příkaz `git bisect bad`, jímž systému oznámíte, že aktuální revize, na níž se právě nacházíte, obsahuje chybu. Poté musíte nástroji bisect sdělit, kdy byl kód naposled nepochybně funkční. K tomu použijete příkaz `git bisect good [good_commit]`:
821
+
822
+ $ git bisect start
823
+ $ git bisect bad
824
+ $ git bisect good v1.0
825
+ Bisecting: 6 revisions left to test after this
826
+ [ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo
827
+
828
+ Git zjistil, že mezi revizí, kterou jste označili jako poslední dobrou (v1.0), a aktuální problémovou verzí je asi 12 revizí, a provedl checkout prostřední revize. Nyní můžete provést testování a vyzkoušet, zda problém existuje i v této revizi. Pokud ano, vznikla chyba někdy před touto prostřední revizí; pokud ne, pak je problém záležitostí revizí zapsaných až po této prostřední revizi. Ukáže se, že na této revizi k problému nedochází, a tak to systému Git sdělíte příkazem `git bisect good` a budete v hledání pokračovat:
829
+
830
+ $ git bisect good
831
+ Bisecting: 3 revisions left to test after this
832
+ [b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing
833
+
834
+ Nyní jste na jiné revizi, na půl cesty mezi revizí, kterou jste právě otestovali, a problémovou revizí. Znovu provedete svůj test a zjistíte, že tato revize vykazuje chybu. Systému Git to sdělíte příkazem `git bisect bad`:
835
+
836
+ $ git bisect bad
837
+ Bisecting: 1 revisions left to test after this
838
+ [f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table
839
+
840
+ Tato revize je v pořádku, a Git tak má nyní všechny informace, které potřebuje k určení, kde problém vznikl. Sdělí vám SHA-1 první revize s chybou a zobrazí některé další informace o revizi a o tom, které soubory byly v této revizi změněny. Zjistíte tak, co bylo součástí revize a co může způsobovat hledanou chybu:
841
+
842
+ $ git bisect good
843
+ b047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commit
844
+ commit b047b02ea83310a70fd603dc8cd7a6cd13d15c04
845
+ Author: PJ Hyett <pjhyett@example.com>
846
+ Date: Tue Jan 27 14:48:32 2009 -0800
847
+
848
+ secure this thing
849
+
850
+ :040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730
851
+ f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M config
852
+
853
+ Až vyhledávání dokončíte, měli byste použít příkaz `git bisect reset`, abyste se vrátili do jednoznačného stavu. Příkaz vrátí váš ukazatel HEAD na pozici, z níž jste vyhledávání zahajovali:
854
+
855
+ $ git bisect reset
856
+
857
+ bisect je výkonný nástroj, který vám může pomoci zkontrolovat za pár minut i stovky revizí s neurčitou chybou. A máte-li skript, jehož výstupem bude 0, pokud je projekt v pořádku, nebo nenulovou hodnotu, pokud je v projektu chyba, můžete příkaz `git bisect` dokonce plně automatizovat. Nejprve opět zadáte poslední známé revize s chybou a bez ní, jimiž vytyčíte cílovou oblast pro příkaz bisect. Chcete-li, můžete to provést příkazem `bisect start` – jako první uvedete známou revizi s chybou, jako druhá bude následovat poslední známá dobrá revize:
858
+
859
+ $ git bisect start HEAD v1.0
860
+ $ git bisect run test-error.sh
861
+
862
+ Automaticky se spustí `test-error.sh` na všech načtených revizích, dokud Git nenajde první revizi s chybou. Podobně můžete spustit také příkaz `make` nebo `make tests` či cokoli jiného, čím spouštíte automatické testování.
863
+
864
+ ## Submoduly ##
865
+
866
+ Často se stává, že pracujete na jednom projektu, ale na chvíli si potřebujete odskočit do jiného. Jedná se třeba o knihovnu, kterou vyvinula třetí strana, nebo kterou vyvíjíte odděleně a používáte ji v několika nadřazených projektech. V obou případech se budete potýkat se stejným problémem: oba projekty chcete zachovat samostatné, a přesto potřebujete používat jeden v rámci druhého.
867
+
868
+ Uveďme malý příklad. Programujete webové stránky a vytváříte kanály Atom. Místo abyste psali vlastní zdrojový kód ke kanálům Atom, rozhodnete se použít knihovnu. Pravděpodobně budete muset použít tento kód ze sdílené knihovny, jako CPAN install nebo Ruby gem, nebo zkopírovat zdrojový kód do vlastního stromu projektu. Problém s použitím knihovny je ten, že je obtížné knihovnu jakýmkoli způsobem upravit a často ještě těžší ji nasadit, protože se musíte ujistit, že ji má k dispozici každý klient. Problémem s převzetím zdrojového kódu do vlastního projektu bývá, že jakékoli uživatelské změny, které provedete, se obtížně začleňují, pokud se objeví novější změny.
869
+
870
+ Git nabízí jako řešení tohoto problému nástroj submodulů. Submoduly umožňují uchovávat repozitář Git jako podadresář jiného repozitáře Git. Do svého projektu tak můžete naklonovat jiný repozitář a uchovávat revize oddělené.
871
+
872
+ ### Začátek práce se submoduly ###
873
+
874
+ Předpokládejme, že budete chtít vložit do svého projektu knihovnu Rack (rozhraní brány webového serveru Ruby), udržovat v ní vlastní změny, ale nadále začleňovat i změny ze serveru. První věcí, kterou byste měli udělat, je naklonovat externí repozitář do vlastního podadresáře. Externí projekty přidáte do svého projektu jako submoduly příkazem `git submodule add`:
875
+
876
+ $ git submodule add git://github.com/chneukirchen/rack.git rack
877
+ Initialized empty Git repository in /opt/subtest/rack/.git/
878
+ remote: Counting objects: 3181, done.
879
+ remote: Compressing objects: 100% (1534/1534), done.
880
+ remote: Total 3181 (delta 1951), reused 2623 (delta 1603)
881
+ Receiving objects: 100% (3181/3181), 675.42 KiB | 422 KiB/s, done.
882
+ Resolving deltas: 100% (1951/1951), done.
883
+
884
+ Nyní máte projekt Rack uložen ve svém projektu v podadresáři `rack`. Můžete přejít do tohoto podadresáře, provést změny, přidat vlastní vzdálený repozitář s oprávněním k zápisu, kam budete změny odesílat, vyzvednout a začlenit data z původního repozitáře atd. Pokud byste bezprostředně po přidání submodulu spustili příkaz `git status`, viděli byste dvě věci:
885
+
886
+ $ git status
887
+ # On branch master
888
+ # Changes to be committed:
889
+ # (use "git reset HEAD <file>..." to unstage)
890
+ #
891
+ # new file: .gitmodules
892
+ # new file: rack
893
+ #
894
+
895
+ Zaprvé si všimnete souboru `.gitmodules`. Jedná se o konfigurační soubor, v němž je uloženo mapování mezi adresou URL projektu a lokálním podadresářem, do nějž jste stáhli repozitář.
896
+
897
+ $ cat .gitmodules
898
+ [submodule "rack"]
899
+ path = rack
900
+ url = git://github.com/chneukirchen/rack.git
901
+
902
+ Máte-li submodulů více, bude v tomto souboru několik záznamů. Za zmínku stojí, že je tento soubor verzován spolu s ostatními soubory, podobně jako třeba soubor `.gitignore`. Soubor se odesílá a stahuje se zbytkem projektu. Ostatní uživatelé, kteří budou tento projekt klonovat, díky tomu zjistí, kde najdou projekty submodulů.
903
+
904
+ Tím dalším, co se objevuje ve výstupu příkazu `git status`, je položka rack. Pokud na ni použijete příkaz `git diff`, uvidíte zajímavou věc:
905
+
906
+ $ git diff --cached rack
907
+ diff --git a/rack b/rack
908
+ new file mode 160000
909
+ index 0000000..08d709f
910
+ --- /dev/null
911
+ +++ b/rack
912
+ @@ -0,0 +1 @@
913
+ +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433
914
+
915
+ Ačkoli je `rack` podadresářem ve vašem pracovním adresáři, Git ví, že se jedná o submodul, a dokud se v tomto adresáři nenacházíte, nesleduje jeho obsah. Místo toho zaznamenává Git konkrétní revizi z tohoto adresáře. Provedete-li v tomto podadresáři změny a zapíšete revizi, superprojekt (tedy celkový, nadřízený projekt) zjistí, že se tu ukazatel HEAD změnil, a zaznamená přesnou revizi, na níž právě pracujete. Pokud pak tento projekt naklonují jiní uživatelé, budou schopni přesně obnovit původní prostředí.
916
+
917
+ Toto je důležitá vlastnost submodulů: zaznamenáváte je jako přesné revize, na nichž se nacházejí. Submodul nelze zaznamenat na větvi `master` nebo na jiné symbolické referenci.
918
+
919
+ Jestliže zapíšete revizi, zobrazí se přibližně toto:
920
+
921
+ $ git commit -m 'first commit with submodule rack'
922
+ [master 0550271] first commit with submodule rack
923
+ 2 files changed, 4 insertions(+), 0 deletions(-)
924
+ create mode 100644 .gitmodules
925
+ create mode 160000 rack
926
+
927
+ Všimněte si režimu (mode) 160000 u záznamu rack. Jedná se o speciální režim systému Git, který udává, že revizi zaznamenáváte jako adresář, ne jako podadresář nebo soubor.
928
+
929
+ S adresářem `rack` můžete pracovat jako se samostatným projektem a čas od času aktualizovat superprojekt ukazatelem na nejnovější revizi v tomto subprojektu. Všechny příkazy Git pracují v obou adresářích nezávisle:
930
+
931
+ $ git log -1
932
+ commit 0550271328a0038865aad6331e620cd7238601bb
933
+ Author: Scott Chacon <schacon@gmail.com>
934
+ Date: Thu Apr 9 09:03:56 2009 -0700
935
+
936
+ first commit with submodule rack
937
+ $ cd rack/
938
+ $ git log -1
939
+ commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433
940
+ Author: Christian Neukirchen <chneukirchen@gmail.com>
941
+ Date: Wed Mar 25 14:49:04 2009 +0100
942
+
943
+ Document version change
944
+
945
+ ### Klonování projektu se submoduly ###
946
+
947
+ Nyní naklonujeme projekt, jehož součástí je submodul. Pokud takový projekt obdržíte, získáte adresáře, které tyto submoduly obsahují, ale zatím žádný soubor:
948
+
949
+ $ git clone git://github.com/schacon/myproject.git
950
+ Initialized empty Git repository in /opt/myproject/.git/
951
+ remote: Counting objects: 6, done.
952
+ remote: Compressing objects: 100% (4/4), done.
953
+ remote: Total 6 (delta 0), reused 0 (delta 0)
954
+ Receiving objects: 100% (6/6), done.
955
+ $ cd myproject
956
+ $ ls -l
957
+ total 8
958
+ -rw-r--r-- 1 schacon admin 3 Apr 9 09:11 README
959
+ drwxr-xr-x 2 schacon admin 68 Apr 9 09:11 rack
960
+ $ ls rack/
961
+ $
962
+
963
+ Máte sice adresář `rack`, ten je však prázdný. Budete muset použít dva příkazy: `git submodule init` k inicializaci lokálního konfiguračního souboru a `git submodule update` k vyzvednutí všech dat z tohoto projektu a checkoutu příslušné revize uvedené ve vašem superprojektu:
964
+
965
+ $ git submodule init
966
+ Submodule 'rack' (git://github.com/chneukirchen/rack.git) registered for path 'rack'
967
+ $ git submodule update
968
+ Initialized empty Git repository in /opt/myproject/rack/.git/
969
+ remote: Counting objects: 3181, done.
970
+ remote: Compressing objects: 100% (1534/1534), done.
971
+ remote: Total 3181 (delta 1951), reused 2623 (delta 1603)
972
+ Receiving objects: 100% (3181/3181), 675.42 KiB | 173 KiB/s, done.
973
+ Resolving deltas: 100% (1951/1951), done.
974
+ Submodule path 'rack': checked out '08d709f78b8c5b0fbeb7821e37fa53e69afcf433'
975
+
976
+ Váš podadresář `rack` je nyní přesně ve stejném stavu, jako když jste předtím zapisovali revizi. Jestliže jiný vývojář provede změny v kódu adresáře rack a zapíše je do revize a vy poté tuto referenci stáhnete a začleníte, dostanete něco, co bude vypadat poněkud zvláštně:
977
+
978
+ $ git merge origin/master
979
+ Updating 0550271..85a3eee
980
+ Fast forward
981
+ rack | 2 +-
982
+ 1 files changed, 1 insertions(+), 1 deletions(-)
983
+ [master*]$ git status
984
+ # On branch master
985
+ # Changes not staged for commit:
986
+ # (use "git add <file>..." to update what will be committed)
987
+ # (use "git checkout -- <file>..." to discard changes in working directory)
988
+ #
989
+ # modified: rack
990
+ #
991
+
992
+ Začlenili jste něco, co je v podstatě změna ukazatele vašeho submodulu. Neaktualizovali jste tím však zdrojový kód v adresáři submodulu, takže to vypadá, jako že je váš pracovní adresář v chaotickém stavu:
993
+
994
+ $ git diff
995
+ diff --git a/rack b/rack
996
+ index 6c5e70b..08d709f 160000
997
+ --- a/rack
998
+ +++ b/rack
999
+ @@ -1 +1 @@
1000
+ -Subproject commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0
1001
+ +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433
1002
+
1003
+ A tak to opravdu je. Ukazatel, který máte pro submodul, není to, co máte skutečně v adresáři submodulu. Abyste tento problém vyřešili, spusťte ještě jednou příkaz `git submodule update`:
1004
+
1005
+ $ git submodule update
1006
+ remote: Counting objects: 5, done.
1007
+ remote: Compressing objects: 100% (3/3), done.
1008
+ remote: Total 3 (delta 1), reused 2 (delta 0)
1009
+ Unpacking objects: 100% (3/3), done.
1010
+ From git@github.com:schacon/rack
1011
+ 08d709f..6c5e70b master -> origin/master
1012
+ Submodule path 'rack': checked out '6c5e70b984a60b3cecd395edd5b48a7575bf58e0'
1013
+
1014
+ To budete muset udělat pokaždé, když stáhnete změnu v submodulu v hlavním projektu. Je to sice trochu zvláštní, ale opravdu to tak funguje.
1015
+
1016
+ K tradičním problémům dochází, jestliže vývojář provede lokální změnu v submodulu, ale neodešle ji na veřejný server. Poté zapíše ukazatel do tohoto neveřejného stavu a superprojekt odešle na server. Když se pak ostatní vývojáři pokusí spustit příkaz `git submodule update`, systém submodulu nemůže najít revizi, k níž se vztahuje jedna z referencí, protože existuje pouze v prvním systému vývojáře. Pokud dojde k něčemu takovému, zobrazí se následující chyba:
1017
+
1018
+ $ git submodule update
1019
+ fatal: reference isn’t a tree: 6c5e70b984a60b3cecd395edd5b48a7575bf58e0
1020
+ Unable to checkout '6c5e70b984a60b3cecd395edd5ba7575bf58e0' in submodule path 'rack'
1021
+
1022
+ Musíte zjistit, kdo změnil submodul jako poslední:
1023
+
1024
+ $ git log -1 rack
1025
+ commit 85a3eee996800fcfa91e2119372dd4172bf76678
1026
+ Author: Scott Chacon <schacon@gmail.com>
1027
+ Date: Thu Apr 9 09:19:14 2009 -0700
1028
+
1029
+ added a submodule reference I will never make public. hahahahaha!
1030
+
1031
+ Nyní znáte provinilcovu e-mailovou adresu a můžete mu vyčinit.
1032
+
1033
+ ### Superprojekty ###
1034
+
1035
+ Vývojáři někdy chtějí získat kombinaci podadresářů velkého projektu podle toho, v jakém týmu pracují. K tomu může dojít, pokud přecházíte ze systému CVS nebo Subversion, kde jste definovali modul nebo několik podadresářů, a chcete v tomto typu pracovního postupu pokračovat.
1036
+
1037
+ Dobrým způsobem, jak to v systému Git provést, je učinit ze všech podsložek oddělené repozitáře Git a vytvořit repozitáře superprojektu Git, které budou obsahovat několik submodulů. Výhodou tohoto postupu je, že můžete podrobněji definovat vztah mezi projekty se značkami a větvemi v superprojektech.
1038
+
1039
+ ### Problémy se submoduly ###
1040
+
1041
+ Používání submodulů se však vždy neobejde bez zádrhelů. Zaprvé je třeba, abyste si v adresáři submodulu počínali opatrně. Spustíte-li příkaz `git submodule update`, provedete tím checkout konkrétní verze projektu, avšak nikoli v rámci větve. Říká se tomu oddělená hlava (detached head) – znamená to, že soubor HEAD ukazuje přímo na revizi, ne na symbolickou referenci. Problém je, že většinou nechcete pracovat v prostředí oddělené hlavy, protože byste tak velmi snadno mohli přijít o provedené změny. Jestliže nejprve spustíte příkaz `submodule update`, zapíšete v adresáři tohoto submodulu revizi, aniž byste na tuto práci vytvořili novou větev, a poté ze superprojektu znovu spustíte příkaz `git submodule update`, aniž byste mezitím zapisovali revize, Git vaše revize bez varování přepíše. Technicky vzato práci neztratíte, ale nebude žádná větev, která by na ni ukazovala, a tak bude poněkud obtížené získat práci zpět.
1042
+
1043
+ Aby ve vašem projektu k tomuto problému nedošlo, vytvořte během práce v adresáři submodulu příkazem `git checkout -b work` nebo podobným novou větev. Až budete podruhé provádět příkaz submodule update, i tentokrát sice vrátí vaši práci, ale přinejmenším budete mít ukazatel, k němuž se budete moci vrátit.
1044
+
1045
+ Problematické může být také přepínání větví obsahujících submoduly. Vytvoříte-li novou větev, přidáte do ní submodul a poté přepnete zpět na větev bez tohoto submodulu, není adresář submodulu stále ještě sledován:
1046
+
1047
+ $ git checkout -b rack
1048
+ Switched to a new branch "rack"
1049
+ $ git submodule add git@github.com:schacon/rack.git rack
1050
+ Initialized empty Git repository in /opt/myproj/rack/.git/
1051
+ ...
1052
+ Receiving objects: 100% (3184/3184), 677.42 KiB | 34 KiB/s, done.
1053
+ Resolving deltas: 100% (1952/1952), done.
1054
+ $ git commit -am 'added rack submodule'
1055
+ [rack cc49a69] added rack submodule
1056
+ 2 files changed, 4 insertions(+), 0 deletions(-)
1057
+ create mode 100644 .gitmodules
1058
+ create mode 160000 rack
1059
+ $ git checkout master
1060
+ Switched to branch "master"
1061
+ $ git status
1062
+ # On branch master
1063
+ # Untracked files:
1064
+ # (use "git add <file>..." to include in what will be committed)
1065
+ #
1066
+ # rack/
1067
+
1068
+ Budete ho muset buď přemístit, nebo odstranit. V druhém případě ho budete muset znovu naklonovat, až přepnete zpět, navíc hrozí, že ztratíte lokální změny nebo větve, které jste neodeslali.
1069
+
1070
+ Poslední velký problém s nímž se uživatelé často setkávají, souvisí s přepínáním z podadresářů na submoduly. Pokud jste ve svém projektu sledovali soubory a chcete je přesunout do submodulu, musíte být velmi opatrní, abyste si Git proti sobě nepoštvali. Řekněme, že máte soubory rack v podadresáři svého projektu a chcete ho přepnout do submodulu. Jestliže odstraníte podadresář a spustíte příkaz `submodule add`, Git vám vynadá:
1071
+
1072
+ $ rm -Rf rack/
1073
+ $ git submodule add git@github.com:schacon/rack.git rack
1074
+ 'rack' already exists in the index
1075
+
1076
+ Adresář `rack` už byl připraven k zapsání. Proto ho musíte nejprve vrátit, až potom můžete přidat submodul:
1077
+
1078
+ $ git rm -r rack
1079
+ $ git submodule add git@github.com:schacon/rack.git rack
1080
+ Initialized empty Git repository in /opt/testsub/rack/.git/
1081
+ remote: Counting objects: 3184, done.
1082
+ remote: Compressing objects: 100% (1465/1465), done.
1083
+ remote: Total 3184 (delta 1952), reused 2770 (delta 1675)
1084
+ Receiving objects: 100% (3184/3184), 677.42 KiB | 88 KiB/s, done.
1085
+ Resolving deltas: 100% (1952/1952), done.
1086
+
1087
+ Nyní předpokládejme, že toto vše se odehrálo ve větvi. Pokud se pokusíte přepnout zpět do větve, kde jsou tyto soubory v aktuálním stromu, a ne v submodulu, zobrazí se tato chyba:
1088
+
1089
+ $ git checkout master
1090
+ error: Untracked working tree file 'rack/AUTHORS' would be overwritten by merge.
1091
+
1092
+ Nejprve budete muset přemístit adresář submodulu `rack`, než vám Git dovolí přepnout na větev, která adresář neobsahuje:
1093
+
1094
+ $ mv rack /tmp/
1095
+ $ git checkout master
1096
+ Switched to branch "master"
1097
+ $ ls
1098
+ README rack
1099
+
1100
+ Až poté přepnete zpět, bude adresář `rack` prázdný. Buď můžete spustit příkaz `git submodule update` a provést nové klonování, nebo můžete přesunout adresář `/tmp/rack` zpět do prázdného adresáře.
1101
+
1102
+ ## Začlenění podstromu ##
1103
+
1104
+ Nyní, když jsme poznali obtíže spojené se systémem submodulů, podívejme se na jedno alternativní řešení tohoto problému. Git se vždy při slučování nejprve podívá, co a kam začleňuje, a podle toho zvolí vhodnou strategii začlenění. Pokud slučujete dvě větve, používá Git *rekurzivní* strategii. Pokud slučujete více než dvě větve, zvolí Git tzv. strategii *chobotnice* (octopus strategy). Git vybírá tyto strategie automaticky. Rekurzivní strategie zvládá složité třícestné slučování (např. s více než jedním společným předkem), ale nedokáže sloučit více než dvě větve. Chobotnicové sloučení dokáže naproti tomu sloučit několik větví, ale je opatrnější při předcházení složitým konfliktům. Proto je ostatně nastaveno jako výchozí strategie při slučování více než dvou větví.
1105
+
1106
+ Existují však ještě další strategie. Jednou z nich je tzv. začlenění *podstromu* (subtree merge), které lze použít jako řešení problémů se subprojektem. Ukažme si, jak se dá začlenit stejný adresář rack jako v předchozí části, tentokrát však s využitím strategie začlenění podstromu.
1107
+
1108
+ Začlenění podstromu spočívá v tom, že máte dva projekty a jeden z projektů se promítá do podadresáře druhého projektu a naopak. Pokud určíte strategii začlenění podstromu, je Git natolik inteligentní, aby zjistil, že je jeden podstromem druhého, a provedl sloučení odpovídajícím způsobem – počíná si opravdu sofistikovaně.
1109
+
1110
+ Nejprve přidáte aplikaci Rack do svého projektu. Projekt Rack přidáte ve vlastním projektu jako vzdálenou referenci a provedete jeho checkout do vlastní větve:
1111
+
1112
+ $ git remote add rack_remote git@github.com:schacon/rack.git
1113
+ $ git fetch rack_remote
1114
+ warning: no common commits
1115
+ remote: Counting objects: 3184, done.
1116
+ remote: Compressing objects: 100% (1465/1465), done.
1117
+ remote: Total 3184 (delta 1952), reused 2770 (delta 1675)
1118
+ Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, done.
1119
+ Resolving deltas: 100% (1952/1952), done.
1120
+ From git@github.com:schacon/rack
1121
+ * [new branch] build -> rack_remote/build
1122
+ * [new branch] master -> rack_remote/master
1123
+ * [new branch] rack-0.4 -> rack_remote/rack-0.4
1124
+ * [new branch] rack-0.9 -> rack_remote/rack-0.9
1125
+ $ git checkout -b rack_branch rack_remote/master
1126
+ Branch rack_branch set up to track remote branch refs/remotes/rack_remote/master.
1127
+ Switched to a new branch "rack_branch"
1128
+
1129
+ Nyní máte kořenový adresář s projektem Rack ve větvi `rack_branch` a vlastní projekt ve větvi `master`. Provedete-li checkout jedné a posléze druhé větve, uvidíte, že mají jiné kořenové adresáře:
1130
+
1131
+ $ ls
1132
+ AUTHORS KNOWN-ISSUES Rakefile contrib lib
1133
+ COPYING README bin example test
1134
+ $ git checkout master
1135
+ Switched to branch "master"
1136
+ $ ls
1137
+ README
1138
+
1139
+ Projekt Rack chcete do projektu `master` natáhnout jako podadresář. V systému Git k tomu slouží příkaz `git read-tree`. O příkazu `read-tree` a jeho příbuzných se více dočtete v kapitole 9, nyní však vězte, že načte kořenový strom jedné větve do vaší aktuální oblasti připravených změn a do pracovního adresáře. Přepnuli jste zpět na větev `master` a větev `rack_branch` natáhnete do podadresáře `rack` své větve `master` hlavního projektu:
1140
+
1141
+ $ git read-tree --prefix=rack/ -u rack_branch
1142
+
1143
+ Až zapíšete revizi, bude to vypadat, jako byste měli všechny soubory Rack v tomto podadresáři, jako byste je zkopírovali z tarballu. Je zajímavé, že tak lze opravdu jednoduše začlenit změny z jedné větve do druhé. Pokud je proto projekt Rack aktualizován, můžete natáhnout novější změny přepnutím na tuto větev a jejím natažením:
1144
+
1145
+ $ git checkout rack_branch
1146
+ $ git pull
1147
+
1148
+ Tyto změny pak můžete začlenit zpět do hlavní větve. Můžete použít příkaz `git merge -s subtree` a začlenění proběhne úspěšně. Git však sloučí také obě historie, což pravděpodobně nebylo vaším záměrem. Chcete-li natáhnout změny a předběžně vyplnit zprávu k revizi, použijte parametry `--squash`, `--no-commit` a také parametr strategie `-s subtree`:
1149
+
1150
+ $ git checkout master
1151
+ $ git merge --squash -s subtree --no-commit rack_branch
1152
+ Squash commit -- not updating HEAD
1153
+ Automatic merge went well; stopped before committing as requested
1154
+
1155
+ Všechny změny z projektu Rack budou začleněny a budete je moci lokálně zapsat. Můžete ale postupovat také opačně – provést změny v podadresáři `rack` vaší hlavní větve, poté je začlenit do větve `rack_branch` a poslat je správcům nebo je odeslat do repozitáře.
1156
+
1157
+ Chcete-li se podívat na výpis „diff“ s rozdíly mezi tím, co máte v podadresáři `rack`, a kódem ve větvi `rack_branch` (abyste věděli, jestli je nutné je slučovat), nelze použít běžný příkaz `diff`. V tomto případě je třeba zadat příkaz `git diff-tree` a větev, s níž chcete srovnání provést:
1158
+
1159
+ $ git diff-tree -p rack_branch
1160
+
1161
+ Popřípadě chcete-li porovnat, co je ve vašem podadresáři `rack`, s tím, co bylo ve větvi `master` na serveru v okamžiku, kdy jste naposledy vyzvedávali data, spusťte příkaz:
1162
+
1163
+ $ git diff-tree -p rack_remote/master
1164
+
1165
+ ## Shrnutí ##
1166
+
1167
+ V této kapitole jste poznali několik pokročilých nástrojů umožňujících preciznější manipulaci s revizemi a oblastí připravených změn. Vyskytnou-li se jakékoli problémy, měli byste být schopni snadno odhalit závadnou revizi, kdo je jejím autorem a kdy byla zapsána. Chcete-li ve svém projektu využívat subprojekty, znáte nyní několik způsobů, jak to provést. V této chvíli byste měli v systému Git zvládat většinu úkonů, které se běžně používají na příkazovém řádku, a neměly by vám činit větší potíže.