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,914 @@
1
+ # Distribuovaný charakter systému Git #
2
+
3
+ Nyní máte vytvořen vzdálený repozitář Git jako místo, kde mohou všichni vývojáři sdílet zdrojový kód, a znáte základní příkazy systému Git pro práci v lokálním prostředí. Je čas podívat se na využití některých distribuovaných postupů, které vám Git nabízí.
4
+
5
+ V této kapitole se dozvíte, jak pracovat se systémem Git v distribuovaném prostředí jako přispěvatel a zprostředkovatel integrace. Naučíte se tedy, jak úspěšně přispívat svým kódem do projektů a jak to učinit co nejjednodušeji pro vás i správce projektu. Dále se dozvíte, jak efektivně spravovat projekt, do nějž přispívá velký počet vývojářů.
6
+
7
+ ## Distribuované pracovní postupy ##
8
+
9
+ Na rozdíl od centralizovaných systémů správy verzí (CVCS) umožňuje distribuovaný charakter systému Git mnohem větší flexibilitu při spolupráci vývojářů na projektech. V centralizovaných systémech představuje každý vývojář samostatný uzel, pracující více či méně na stejné úrovni vůči centrálnímu úložišti. Naproti tomu je v systému Git každý vývojář potenciálním uzlem i úložištěm, každý vývojář může přispívat kódem do jiných repozitářů i spravovat veřejný repozitář, na němž mohou ostatní založit svou práci a do nějž mohou přispívat. Tím se pro váš projekt a váš tým otvírá široké spektrum pracovních postupů. Zkusíme se tedy podívat na pár častých přístupů, které tato flexibilita umožňuje. Uvedeme jejich přednosti i eventuální slabiny. Budete si moci vybrat některý z postupů nebo je navzájem kombinovat a spojovat jejich vlastnosti.
10
+
11
+ ### Centralizovaný pracovní postup ###
12
+
13
+ V centralizovaných systémech je většinou možný pouze jediný model spolupráce, tzv. centralizovaný pracovní postup. Jedno centrální úložiště (hub) nebo repozitář přijímá zdrojový kód a každý podle něj synchronizuje svou práci. Několik vývojářů představuje jednotlivé uzly (nodes) – uživatele centrálního místa – které se podle tohoto místa synchronizují (viz obrázek 5-1).
14
+
15
+ Insert 18333fig0501.png
16
+ Obrázek 5-1. Centralizovaný pracovní postup
17
+
18
+ To znamená, že pokud dva vývojáři klonují z centrálního úložiště a oba provedou změny, jen první z nich, který odešle své změny, to může provést bez komplikací. Druhý vývojář musí před odesláním svých změn začlenit práci prvního vývojáře do své, aby nepřepsal jeho změny. Tento koncept platí jak pro Git, tak pro Subversion (popř. jakýkoli CVCS). I v systému Git funguje bez problémů.
19
+
20
+ Pokud pracujete v malém týmu nebo už jste ve své společnosti nebo ve svém týmu zvyklí na centralizovaný pracovní postup, můžete v něm beze všeho pokračovat. Jednoduše vytvořte repozitář a přidělte všem ze svého týmu oprávnění k odesílání dat. Git neumožní uživatelům, aby se navzájem přepisovali. Pokud některý z vývojářů naklonuje data, provede změny a poté se je pokusí odeslat, a jiný vývojář mezitím odeslal svoje revize, server tyto změny odmítne. Git vývojáři při odmítnutí sdělí, že se pokouší odeslat změny, které nesměřují „rychle vpřed“, což není možné provést, dokud nevyzvedne a nezačlení (fetch and merge) stávající data z repozitáře.
21
+ Tento pracovní postup může být pro mnoho lidí zajímavý, protože je to schéma, které jsou zvyklí používat a jsou s ním spokojeni.
22
+
23
+ ### Pracovní postup s integračním manažerem ###
24
+
25
+ Protože Git umožňuje, abyste měli několik vzdálených repozitářů, lze použít pracovní postup, kdy má každý vývojář oprávnění k zápisu do vlastního veřejného repozitáře a oprávnění pro čtení k repozitářům všech ostatních. Tento scénář často zahrnuje jeden standardní repozitář, který reprezentuje „oficiální“ projekt. Chcete-li do tohoto projektu přispívat, vytvořte vlastní veřejný klon projektu a odešlete do něj změny, které jste provedli. Poté odešlete správci hlavního projektu žádost, aby do projektu natáhl vaše změny. Správce může váš repozitář přidat jako vzdálený repozitář, lokálně otestovat vaše změny, začlenit je do své větve a odeslat zpět do svého repozitáře. Postup práce je následující (viz obrázek 5-2):
26
+
27
+ 1. Správce projektu odešle data do svého veřejného repozitáře.
28
+ 2. Přispěvatel naklonuje tento repozitář a provede změny.
29
+ 3. Přispěvatel odešle změny do své vlastní veřejné kopie.
30
+ 4. Přispěvatel pošle správci e-mail s žádostí, aby natáhl změny do projektu.
31
+ 5. Správce přidá repozitář přispěvatele jako vzdálený repozitář a provede lokální začlenění.
32
+ 6. Správce odešle začleněné změny do hlavního repozitáře.
33
+
34
+ Insert 18333fig0502.png
35
+ Obrázek 5-2. Pracovní postup s integračním manažerem
36
+
37
+ Tento pracovní postup je velmi rozšířený na serverech jako je GitHub, kde je snadné rozštěpit projekt a odeslat změny do své odštěpené části, kde jsou pro každého k nahlédnutí. Jednou z hlavních předností tohoto postupu je, že můžete pracovat bez přerušení a správce hlavního repozitáře může natáhnout vaše změny do projektu, kdykoli uzná za vhodné. Přispěvatelé nemusí čekat, až budou jejich změny začleněny do projektu – každá strana může pracovat svým tempem.
38
+
39
+ ### Pracovní postup s diktátorem a poručíky ###
40
+
41
+ Jedná se o variantu pracovního postupu s více repozitáři. Většinou se používá u obřích projektů se stovkami spolupracovníků. Možná nejznámějším příkladem je vývoj jádra Linuxu. Několik různých integračních manažerů odpovídá za konkrétní části repozitáře – říká se jím poručíci (lieutenants). Všichni poručíci mají jednoho integračního manažera, kterému se říká „benevolentní diktátor“. Repozitář benevolentního diktátora slouží jako referenční repozitář, z nějž všichni spolupracovníci musí stahovat data. Postup práce je následující (viz obrázek 5-3):
42
+
43
+ 1. Stálí vývojáři pracují na svých tematických větvích a přeskládávají svou práci na vrchol hlavní větve. Hlavní větev je větev diktátora.
44
+ 2. Poručíci začleňují tematické větve vývojářů do svých hlavních větví.
45
+ 3. Diktátor začleňuje hlavní větve poručíků do své hlavní větve.
46
+ 4. Diktátor odesílá svou hlavní větev do referenčního repozitáře, aby si na jeho základě mohli ostatní vývojáři přeskládat data.
47
+
48
+ Insert 18333fig0503.png
49
+ Obrázek 5-3. Pracovní postup s benevolentním diktátorem
50
+
51
+ Tento typ pracovního postupu není sice obvyklý, ale může být užitečný u velmi velkých projektů nebo v silně hierarchizovaných prostředích, neboť umožňuje, aby vedoucí projektu (diktátor) velkou část práce delegoval. Pak sbírá velké kusy kódu, které integruje.
52
+
53
+ Toto jsou tedy některé z běžně používaných pracovních postupů, které můžete využít v distribuovaných systémech, jako je například Git. Uvidíte ale, že na pozadí vašich konkrétních potřeb v reálných situacích lze vytvořit celou řadu variací na tyto postupy. Nyní, když už se (jak doufám) dokážete rozhodnout, která kombinace postupů pro vás bude ta nejvhodnější, ukážeme si některé konkrétní příklady, jak lze rozdělit hlavní role, z nichž vyplývají jednotlivé postupy práce.
54
+
55
+ ## Přispívání do projektu ##
56
+
57
+ V tuto chvíli už znáte různé pracovní postupy a na velmi solidní úrovni byste měli ovládat základy systému Git. V této části ukážeme několik běžných schémat, podle nichž může přispívání do projektů probíhat.
58
+
59
+ Popsat tento proces není právě jednoduché, protože existuje obrovské množství variací, jak lze do projektů přispívat. Vzhledem k velké flexibilitě systému Git mohou uživatelé spolupracovat mnoha různými způsoby, a není proto snadné popsat, jak byste měli do projektu přispívat. Každý projekt je trochu jiný. Mezi proměnné patří v tomto procesu počet aktivních přispěvatelů, zvolený pracovní postup, vaše oprávnění pro odesílání revizí a případně i metoda externího přispívání.
60
+
61
+ První proměnnou je počet aktivních přispěvatelů. Kolik uživatelů aktivně přispívá kódem do projektu a jak často? V mnoha případech budete mít dva nebo tři vývojáře přispívající několika málo revizemi denně, u projektů s nízkou prioritou možná i méně. V opravdu velkých společnostech a u velkých projektů se může počet vývojářů vyšplhat do tisíců a počet revizí se může pohybovat v desítkách i stovkách záplat denně. To je důležité zejména z toho hlediska, že s rostoucím počtem vývojářů se také zvětšují starosti s tím, aby byl kód aplikován čistě a aby ho bylo možné snadno začlenit. U změn, které postoupíte vyšší instanci, může docházet k zastarávání nebo vážnému narušení jinými daty, která byla začleněna během vaší práce nebo ve chvíli, kdy vaše změny čekaly na schválení či aplikaci. Jak lze důsledně udržovat kód aktuální a záplaty vždy platné?
62
+
63
+ Další proměnnou je pracovní postup, který se u projektu využívá. Probíhá vývoj centralizovaně, má každý vývojář stejné oprávnění pro zápis do hlavní linie kódu? Má projekt svého správce nebo integračního manažera, který kontroluje všechny záplaty? Jsou všechny záplaty odborně posuzovány a schvalovány? Jste součástí tohoto procesu? Jsou součástí systému poručíci a musíte všechnu svou práci odesílat nejprve jim?
64
+
65
+ Další otázkou je vaše oprávnění k zapisování revizí. Pracovní postup při přispívání do projektu se velmi liší podle toho, zda máte, či nemáte oprávnění k zápisu do projektu. Pokud oprávnění k zápisu nemáte, jakou metodu projekt zvolí pro přijímání příspěvků? Má k tomu vůbec vyvinutou metodiku? Kolik práce představuje jeden váš příspěvek? A jak často přispíváte?
66
+
67
+ Všechny tyto otázky mohou mít vliv na efektivní přispívání do projektu a určují, jaký pracovní postup je vůbec možný a který bude upřednostněn. Všem těmto aspektům bych se teď chtěl věnovat na sérii praktických příkladů, od těch jednodušších až po složité. Z uvedených příkladů byste si pak měli být schopni odvodit vlastní pracovní postup, který budete v praxi využívat.
68
+
69
+ ### Pravidla pro revize ###
70
+
71
+ Než se podíváme na konkrétní praktické příklady, přidávám malou poznámku o zprávách k revizím. Není od věci stanovit si a dodržovat kvalitní pravidla pro vytváření revizí. Výrazně vám mohou usnadnit práci v systému Git a spolupráci s kolegy. Projekt Git obsahuje dokument, v němž je navržena celá řada dobrých tipů pro vytváření revizí, z nichž se skládají jednotlivé záplaty. Dokument najdete ve zdrojovém kódu systému Git v souboru `Documentation/SubmittingPatches`.
72
+
73
+ Především nechcete, aby revize obsahovaly chyby způsobené prázdnými znaky. Git nabízí snadný způsob, jak tyto chyby zkontrolovat. Před zapsáním revize zadejte příkaz `git diff --check`, který zkontroluje prázdné znaky a vypíše vám jejich seznam. Zde uvádím jeden příklad, v němž jsem červenou barvu terminálu nahradil znaky `X`:
74
+
75
+ $ git diff --check
76
+ lib/simplegit.rb:5: trailing whitespace.
77
+ + @git_dir = File.expand_path(git_dir)XX
78
+ lib/simplegit.rb:7: trailing whitespace.
79
+ + XXXXXXXXXXX
80
+ lib/simplegit.rb:26: trailing whitespace.
81
+ + def command(git_cmd)XXXX
82
+
83
+ Spustíte-li tento příkaz před zapsáním revize, můžete se rozhodnout, zda chcete zapsat i problematické prázdné znaky, které mohou obtěžovat ostatní vývojáře.
84
+
85
+ Dále se snažte provádět každou revizi jako logicky samostatný soubor změn. Pokud je to možné, snažte se provádět stravitelné změny. Není právě ideální pracovat celý víkend na pěti různých problémech a v pondělí je všechny najednou odeslat v jedné velké revizi. I pokud nebudete během víkendu zapisovat revize, využijte v pondělí oblasti připravených změn a rozdělte svou práci alespoň do stejného počtu revizí, kolik je řešených problémů, a přidejte k nim vysvětlující zprávy. Pokud některé změny modifikují tentýž soubor, zkuste použít příkaz `git add --patch` a připravit soubory k zapsání po částech (podrobnosti v kapitole 6). Snímek projektu na vrcholu větve bude stejný, ať zapíšete jednu revizi, nebo pět (za předpokladu, že vložíte všechny změny). Snažte se proto usnadnit práci svým kolegům, kteří – možná – budou vaše změny kontrolovat. Díky tomuto přístupu také později snáze vyjmete nebo vrátíte některou z provedených změn, bude-li to třeba. Kapitola 6 popisuje několik užitečných triků, jak v systému Git přepsat historii a jak interaktivně připravovat soubory k zapsání. Používejte tyto nástroje k udržení čisté a srozumitelné historie.
86
+
87
+ Poslední věcí, na niž se vyplatí soustředit pozornost, jsou zprávy k revizím. Pokud si zvyknete vytvářet k revizím kvalitní zprávy, bude pro vás práce a kooperace v systému Git mnohem jednodušší. Zpráva by měla obvykle začínat samostatným řádkem o maximálně 50 znacích, v níž stručně popíšete soubor provedených změn. Za ním by měl následovat prázdný řádek a za ním podrobnější popis revize. Projekt Git vyžaduje, aby podrobnější popis revize obsahoval vaši motivaci ke změnám a vymezil jejich implementaci na pozadí předchozích kroků. Tuto zásadu je dobré dodržovat. Vytváříte-li zprávy k revizím v angličtině, často se také doporučuje používat rozkazovací způsob, tj. příkazy. Místo „I added tests for“ nebo „Adding tests for“ používejte raději „Add tests for“.
88
+ Zde uvádíme vzor, jehož autorem je Tim Pope a v originále je k nalezení na stránkách tpope.net:
89
+
90
+ Krátké (do 50 znaků) shrnutí změn
91
+
92
+ Podrobnější popis revize, je-li třeba. Snažte se nepřesáhnout
93
+ zhruba 72 znaků. V některých kontextech je první řádek koncipován
94
+ jako předmět e-mailu a zbytek textu jako jeho tělo. Prázdný řádek
95
+ oddělující shrnutí od těla zprávy je nezbytně nutný (pokud
96
+ nehodláte vypustit celé tělo). Spojení obou částí může zmást
97
+ některé nástroje, např. přeskládání.
98
+
99
+ Další odstavce následují za prázdným řádkem.
100
+
101
+ - Můžete používat i odrážky.
102
+
103
+ - Jako odrážka se nejčastěji používá pomlčka nebo hvězdička, před ně se vkládá
104
+ jedna mezera, mezi body výčtu prázdný řádek, avšak úzus tu není jednotný.
105
+
106
+ Budou-li takto vypadat všechny vaše zprávy k revizím, usnadníte tím práci sobě i svým spolupracovníkům. Projekt Git obsahuje kvalitně naformátované zprávy k revizím. Mohu vám doporučit, abyste v něm zkusili zadat příkaz `git log --no-merges` a podívali se, jak vypadá pěkně naformátovaná historie revizí projektu.
107
+
108
+ Já v následujících příkladech stejně jako ve většině případů v této knize v rámci zestručnění neformátuji zprávy podle uvedených zásad, naopak používám parametr `-m` za příkazem `git commit`. Řiďte se, prosím, podle toho, co říkám, ne podle toho, co dělám.
109
+
110
+ ### Malý soukromý tým ###
111
+
112
+ Nejjednodušší sestavou, s níž se pravděpodobně setkáte, je soukromý projekt, na němž kromě vás pracují ještě jeden nebo dva vývojáři. Soukromým projektem myslím uzavřený zdrojový kód – okolní svět k němu nemá oprávnění pro čtení. Vy a vaši ostatní vývojáři máte všichni oprávnění odesílat změny do repozitáře.
113
+
114
+ V takovém prostředí můžete uplatnit podobný pracovní postup, na jaký jste možná zvyklí ze systému Subversion nebo jiného centralizovaného systému. Se systémem Git ale budete stále ještě ve výhodě v takových ohledech, jako je zapisování revizí offline a podstatně snazší větvení a slučování. Pracovní postup však bude velmi podobný. Hlavním rozdílem je to, že slučování probíhá na straně klienta, ne během zapisování revize na straně serveru.
115
+ Podívejme se, jak to může vypadat, když dva vývojáři začnou spolupracovat na projektu se sdíleným repozitářem. První vývojář, John, naklonuje repozitář, provede změny a zapíše lokální revizi. (V následujících příkladech nahrazuji zprávy protokolů třemi tečkami, abych je trochu zkrátil.)
116
+
117
+ # John's Machine
118
+ $ git clone john@githost:simplegit.git
119
+ Initialized empty Git repository in /home/john/simplegit/.git/
120
+ ...
121
+ $ cd simplegit/
122
+ $ vim lib/simplegit.rb
123
+ $ git commit -am 'removed invalid default value'
124
+ [master 738ee87] removed invalid default value
125
+ 1 files changed, 1 insertions(+), 1 deletions(-)
126
+
127
+ Druhý vývojář, Jessica, učiní totéž – naklonuje repozitář a zapíše provedené změny:
128
+
129
+ # Jessica's Machine
130
+ $ git clone jessica@githost:simplegit.git
131
+ Initialized empty Git repository in /home/jessica/simplegit/.git/
132
+ ...
133
+ $ cd simplegit/
134
+ $ vim TODO
135
+ $ git commit -am 'add reset task'
136
+ [master fbff5bc] add reset task
137
+ 1 files changed, 1 insertions(+), 0 deletions(-)
138
+
139
+ Jessica nyní odešle svou práci na server:
140
+
141
+ # Jessica's Machine
142
+ $ git push origin master
143
+ ...
144
+ To jessica@githost:simplegit.git
145
+ 1edee6b..fbff5bc master -> master
146
+
147
+ Také John se pokusí odeslat své změny na server:
148
+
149
+ # John's Machine
150
+ $ git push origin master
151
+ To john@githost:simplegit.git
152
+ ! [rejected] master -> master (non-fast forward)
153
+ error: failed to push some refs to 'john@githost:simplegit.git'
154
+
155
+ John nyní nesmí odeslat revize, protože mezitím odeslala své změny Jessica. To je třeba si uvědomit, zejména pokud jste zvyklí na systém Subversion. Oba vývojáři totiž neupravovali stejný soubor. Přestože Subversion provádí takové sloučení na serveru automaticky, pokud byly upraveny různé soubory, v systému Git musíte provést sloučení lokálně. John musí vyzvednout změny, které provedla Jessica, a začlenit je do své práce, než ji bude moci odeslat:
156
+
157
+ $ git fetch origin
158
+ ...
159
+ From john@githost:simplegit
160
+ + 049d078...fbff5bc master -> origin/master
161
+
162
+ V tomto okamžiku vypadá Johnův lokální repozitář jako na obrázku 5-4.
163
+
164
+ Insert 18333fig0504.png
165
+ Obrázek 5-4. Johnův výchozí repozitář
166
+
167
+ John má referenci ke změnám, které odeslala Jessica, ale než bude moci sám odeslat svá data, bude muset začlenit její práci:
168
+
169
+ $ git merge origin/master
170
+ Merge made by recursive.
171
+ TODO | 1 +
172
+ 1 files changed, 1 insertions(+), 0 deletions(-)
173
+
174
+ Sloučení probíhá hladce, Johnova historie revizí teď vypadá jako na obrázku 5-5.
175
+
176
+ Insert 18333fig0505.png
177
+ Obrázek 5-5. Johnův repozitář po začlenění větve `origin/master`
178
+
179
+ John nyní může otestovat svůj kód, aby se ujistil, že stále pracuje správně, a pak může odeslat svou novou sloučenou práci na server:
180
+
181
+ $ git push origin master
182
+ ...
183
+ To john@githost:simplegit.git
184
+ fbff5bc..72bbc59 master -> master
185
+
186
+ Johnova historie revizí bude nakonec vypadat jako na obrázku 5-6.
187
+
188
+ Insert 18333fig0506.png
189
+ Obrázek 5-6. Johnova historie po odeslání revize na server origin
190
+
191
+ Jessica mezitím pracovala na tematické větvi. Vytvořila tematickou větev s názvem `issue54` a zapsala do ní tři revize. Zatím ještě nevyzvedla Johnovy změny, a proto její historie revizí vypadá jako na obrázku 5-7.
192
+
193
+ Insert 18333fig0507.png
194
+ Obrázek 5-7. Výchozí historie revizí – Jessica
195
+
196
+ Jessica chce synchronizovat svou práci s Johnem, a proto vyzvedne jeho data:
197
+
198
+ # Jessica's Machine
199
+ $ git fetch origin
200
+ ...
201
+ From jessica@githost:simplegit
202
+ fbff5bc..72bbc59 master -> origin/master
203
+
204
+ Tím stáhne práci, kterou mezitím odeslal John. Historie revizí Jessicy teď vypadá jako na obrázku 5-8.
205
+
206
+ Insert 18333fig0508.png
207
+ Obrázek 5-8. Historie Jessicy po vyzvednutí Johnových změn
208
+
209
+ Jessica považuje svou tematickou větev za dokončenou, ale chce vědět, do čeho má svou práci začlenit, aby mohla změny odeslat. Spustí proto příkaz `git log`:
210
+
211
+ $ git log --no-merges origin/master ^issue54
212
+ commit 738ee872852dfaa9d6634e0dea7a324040193016
213
+ Author: John Smith <jsmith@example.com>
214
+ Date: Fri May 29 16:01:27 2009 -0700
215
+
216
+ removed invalid default value
217
+
218
+ Jessica nyní může začlenit tematickou větev do své větve `master`, začlenit (merge) i Johnovu práci (`origin/master`) do své větve `master` a vše odeslat zpět na server. Nejprve se přepne zpět na svou větev `master`, aby do ní mohla vše integrovat:
219
+
220
+ $ git checkout master
221
+ Switched to branch "master"
222
+ Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.
223
+
224
+ Jako první může začlenit buď větev `origin/master` nebo `issue54`. Obě směřují vpřed, a tak jejich pořadí nehraje žádnou roli. Konečný snímek bude stejný, ať zvolí jakékoli pořadí, mírně se bude lišit jen historie revizí. Jessica se rozhodne začlenit jako první větev `issue54`:
225
+
226
+ $ git merge issue54
227
+ Updating fbff5bc..4af4298
228
+ Fast forward
229
+ README | 1 +
230
+ lib/simplegit.rb | 6 +++++-
231
+ 2 files changed, 6 insertions(+), 1 deletions(-)
232
+
233
+ Tento postup je bezproblémový. Jak vidíte, šlo o jednoduchý posun „rychle vpřed“. Nyní Jessica začlení Johnovu práci (`origin/master`):
234
+
235
+ $ git merge origin/master
236
+ Auto-merging lib/simplegit.rb
237
+ Merge made by recursive.
238
+ lib/simplegit.rb | 2 +-
239
+ 1 files changed, 1 insertions(+), 1 deletions(-)
240
+
241
+ Začlenění proběhne čistě a historie Jessicy bude vypadat jako na obrázku 5-9.
242
+
243
+ Insert 18333fig0509.png
244
+ Obrázek 5-9. Historie Jessicy po začlenění Johnových změn
245
+
246
+ Větev `origin/master` teď má Jessica dostupnou ze své větve `master`, takže může svou práci úspěšně odeslat (za předpokladu, že John mezitím neodeslal další revize):
247
+
248
+ $ git push origin master
249
+ ...
250
+ To jessica@githost:simplegit.git
251
+ 72bbc59..8059c15 master -> master
252
+
253
+ Všichni vývojáři zapsali několik revizí a úspěšně začlenili práci ostatních do své – viz obrázek 5-10.
254
+
255
+ Insert 18333fig0510.png
256
+ Obrázek 5-10. Historie Jessicy po odeslání všech změn zpět na server
257
+
258
+ Toto je jeden z nejjednodušších pracovních postupů. Po určitou dobu pracujete, obvykle na nějaké tematické větvi, a když je připravena k integraci, začleníte ji do své větve `master`. Chcete-li tuto práci sdílet, začleníte ji do své větve `master`. Poté vyzvednete (fetch) a začleníte (merge) větev `origin/master`, jestliže se změnila. Nakonec odešlete všechna data do větve `master` na serveru. Obecná posloupnost kroků je naznačena na obrázku 5-11.
259
+
260
+ Insert 18333fig0511.png
261
+ Obrázek 5-11. Obecná posloupnost kroků u jednoduchého pracovního postupu s více vývojáři v systému Git
262
+
263
+ ### Soukromý řízený tým ###
264
+
265
+ V následujícím scénáři se podíváme na role přispěvatelů ve větší soukromé skupině. Naučíte se, jak pracovat v prostředí, v němž na jednotlivých úkolech spolupracují malé skupiny a tyto týmové příspěvky jsou poté integrovány druhou stranou.
266
+
267
+ Řekněme, že John a Jessica spolupracují na jednom úkolu a Jessica a Josie spolupracují na jiném. Společnost v tomto případě používá typ pracovního postupu s integračním manažerem, kdy práci jednotlivých skupin integrují pouze někteří technici a větev `master` hlavního repozitáře mohou aktualizovat pouze oni. V tomto scénáři se veškerá práce provádí ve větvích jednotlivých týmů a později je spojována zprostředkovateli integrace.
268
+
269
+ Sledujme pracovní postup Jessicy pracující na dvou úkolech a spolupracující v tomto prostředí paralelně s dvěma různými vývojáři. Protože už má naklonovaný repozitář, rozhodne se pracovat nejprve na úkolu A – `featureA`. Vytvoří si pro něj novou větev a udělá v ní určité penzum práce.
270
+
271
+ # Jessica's Machine
272
+ $ git checkout -b featureA
273
+ Switched to a new branch "featureA"
274
+ $ vim lib/simplegit.rb
275
+ $ git commit -am 'add limit to log function'
276
+ [featureA 3300904] add limit to log function
277
+ 1 files changed, 1 insertions(+), 1 deletions(-)
278
+
279
+ V tomto okamžiku potřebuje sdílet svou práci s Johnem, a tak odešle revize své větve `featureA` na server. Jessica nemá oprávnění pro odesílání dat do větve `master` (ten mají pouze zprostředkovatelé integrace), a proto musí své revize odeslat do jiné větve, aby mohla s Johnem spolupracovat:
280
+
281
+ $ git push origin featureA
282
+ ...
283
+ To jessica@githost:simplegit.git
284
+ * [new branch] featureA -> featureA
285
+
286
+ Jessica pošle Johnovi e-mail s informací, že odeslala svou práci do větve pojmenované `featureA` a že se na ni může podívat. Zatímco čeká na zpětnou vazbu od Johna, rozhodne se, že začne pracovat spolu s Josie na úkolu `featureB`. Začne tím, že založí novou větev, která bude založena na větvi `master` ze serveru:
287
+
288
+ # Jessica's Machine
289
+ $ git fetch origin
290
+ $ git checkout -b featureB origin/master
291
+ Switched to a new branch "featureB"
292
+
293
+ Jessica nyní vytvoří několik revizí ve větvi `featureB`:
294
+
295
+ $ vim lib/simplegit.rb
296
+ $ git commit -am 'made the ls-tree function recursive'
297
+ [featureB e5b0fdc] made the ls-tree function recursive
298
+ 1 files changed, 1 insertions(+), 1 deletions(-)
299
+ $ vim lib/simplegit.rb
300
+ $ git commit -am 'add ls-files'
301
+ [featureB 8512791] add ls-files
302
+ 1 files changed, 5 insertions(+), 0 deletions(-)
303
+
304
+ Repozitář Jessicy vypadá jako na obrázku 5-12.
305
+
306
+ Insert 18333fig0512.png
307
+ Obrázek 5-12. Výchozí historie revizí – Jessica
308
+
309
+ Jessica je připravena odeslat svou práci, ale dostane e-mail od Josie, že již na server odeslala větev `featureBee`, v níž už je část práce hotová. Než bude Jessica moci odeslat svou práci na server, bude do ní nejprve muset začlenit práci Josie. Změny, které Josie provedla, vyzvedne příkazem `git fetch`:
310
+
311
+ $ git fetch origin
312
+ ...
313
+ From jessica@githost:simplegit
314
+ * [new branch] featureBee -> origin/featureBee
315
+
316
+ Nyní může Jessica začlenit tyto změny do své práce pomocí příkazu `git merge`:
317
+
318
+ $ git merge origin/featureBee
319
+ Auto-merging lib/simplegit.rb
320
+ Merge made by recursive.
321
+ lib/simplegit.rb | 4 ++++
322
+ 1 files changed, 4 insertions(+), 0 deletions(-)
323
+
324
+ Tady nastává určitý problém. Musí odeslat práci začleněnou ve své větvi `featureB` do větve `featureBee` na serveru. Může tak učinit příkazem `git push` s určením lokální větve, za níž bude následovat dvojtečka (:) a za ní vzdálená větev:
325
+
326
+ $ git push origin featureB:featureBee
327
+ ...
328
+ To jessica@githost:simplegit.git
329
+ fba9af8..cd685d1 featureB -> featureBee
330
+
331
+ Říká se tomu *refspec*. Více o vzorcích refspec systému Git a různých možnostech, k nimž je lze využít, najdete v kapitole 9.
332
+
333
+ Poté pošle John Jessice e-mail, že odeslal několik změn do větve `featureA`, a poprosí ji, aby je ověřila. Jessica spustí příkaz `git fetch`, jímž tyto změny stáhne.
334
+
335
+ $ git fetch origin
336
+ ...
337
+ From jessica@githost:simplegit
338
+ 3300904..aad881d featureA -> origin/featureA
339
+
340
+ Poté si může příkazem `git log` prohlédnout, co všechno bylo změněno:
341
+
342
+ $ git log origin/featureA ^featureA
343
+ commit aad881d154acdaeb2b6b18ea0e827ed8a6d671e6
344
+ Author: John Smith <jsmith@example.com>
345
+ Date: Fri May 29 19:57:33 2009 -0700
346
+
347
+ changed log output to 30 from 25
348
+
349
+ Nakonec začlení Johnovu práci do své vlastní větve `featureA`:
350
+
351
+ $ git checkout featureA
352
+ Switched to branch "featureA"
353
+ $ git merge origin/featureA
354
+ Updating 3300904..aad881d
355
+ Fast forward
356
+ lib/simplegit.rb | 10 +++++++++-
357
+ 1 files changed, 9 insertions(+), 1 deletions(-)
358
+
359
+ Jessica by ráda něco vylepšila, a proto vytvoří novou revizi a odešle ji zpět na server:
360
+
361
+ $ git commit -am 'small tweak'
362
+ [featureA 774b3ed] small tweak
363
+ 1 files changed, 1 insertions(+), 1 deletions(-)
364
+ $ git push origin featureA
365
+ ...
366
+ To jessica@githost:simplegit.git
367
+ 3300904..774b3ed featureA -> featureA
368
+
369
+ Historie revizí Jessicy bude nyní vypadat jako na obrázku 5-13.
370
+
371
+ Insert 18333fig0513.png
372
+ Obrázek 5-13. Historie Jessicy po zapsání revizí do větve s úkolem
373
+
374
+ Jessica, Josie a John pošlou zprávu zprostředkovatelům integrace, že větve `featureA` a `featureBee` jsou na serveru připraveny k integraci do hlavní linie. Poté, co budou tyto větve do hlavní linie integrovány, vyzvednutím dat bude možné stáhnout nové revize vzniklé začleněním změn a historie revizí bude vypadat jako na obrázku 5-14.
375
+
376
+ Insert 18333fig0514.png
377
+ Obrázek 5-14. Historie Jessicy po začlenění obou jejích tematických větví
378
+
379
+ Mnoho skupin přechází na systém Git právě kvůli této možnosti paralelní spolupráce několika týmů a následného slučování různých linií práce. Možnost, aby několik menších podskupin jednoho týmu spolupracovalo prostřednictvím vzdálených větví a aby si práce nevyžádala účast celého týmu nebo nebránila ostatním v jiné práci, je velkou devízou systému Git. Posloupnost kroků vypadá v případě pracovního postupu, který jsme si právě ukázali, jako na obrázku 5-15.
380
+
381
+ Insert 18333fig0515.png
382
+ Obrázek 5-15. Základní posloupnost kroků u pracovního postupu v řízeném týmu
383
+
384
+ ### Malý veřejný projekt ###
385
+
386
+ Přispívání do veřejných projektů se poněkud liší. Protože nemáte oprávnění aktualizovat větve projektu přímo, musíte svou práci doručit správcům jinak. První příklad popisuje, jak se přispívá s využitím rozštěpení na hostitelských serverech Git, které podporují snadné štěpení. Jak server repo.or.cz, tak místa pro hostování podporují štěpení a mnoho správců projektů tento styl přispívání vyžaduje. Další část se pak zabývá projekty, u nichž je upřednostňováno doručování záplat e-mailem.
387
+
388
+ Nejprve patrně bude nutné, abyste naklonovali hlavní repozitář, vytvořili tematickou větev pro záplatu nebo sérii záplat, které hodláte vytvořit, a udělali v nich zamýšlenou práci. Posloupnost příkazů bude tedy následující:
389
+
390
+ $ git clone (url)
391
+ $ cd project
392
+ $ git checkout -b featureA
393
+ $ (work)
394
+ $ git commit
395
+ $ (work)
396
+ $ git commit
397
+
398
+ Možná budete chtít využít příkaz `rebase -i` a zkomprimovat svou práci do jediné revize nebo přeorganizovat práci v revizích tak, aby byla kontrola záplaty pro správce jednodušší – další informace o interaktivním přeskládání najdete v kapitole 6.
399
+
400
+ Až budete s prací ve větvi hotovi a budete ji chtít poslat zpět správcům, přejděte na původní stránku projektu a klikněte na tlačítko „Fork“, jímž vytvoříte vlastní odštěpenou větev projektu, do níž budete moci zapisovat. Poté bude třeba, abyste tuto novou adresu URL repozitáře přidali jako druhý vzdálený repozitář, v tomto případě pojmenovaný `myfork`:
401
+
402
+ $ git remote add myfork (url)
403
+
404
+ Do něj teď musíte odeslat svou práci. Lepším řešením bude odeslat vzdálenou větev, na níž pracujete, do svého repozitáře, než ji začlenit do hlavní větve a tu pak celou odeslat. Důvod je prostý: pokud nebude vaše práce přijata nebo bude převzata částečně, nebudete muset vracet změny začleněné do vaší hlavní větve. Pokud správci začlení či přeskládají vaši práci (nebo její část), získáte ji zpět stažením z repozitáře:
405
+
406
+ $ git push myfork featureA
407
+
408
+ Až svou práci odešlete do odštěpené větve, budete na ni muset upozornit správce. Tomu se říká „žádost o natažení“ (angl. pull request). Můžete ji vygenerovat buď na webové stránce – server GitHub má tlačítko „pull request“, které automaticky odešle správci upozornění – nebo můžete zadat příkaz `git request-pull` a jeho výstup e-mailem ručně odeslat správci projektu.
409
+
410
+ Příkaz `request-pull` vezme základní větev (základnu), do níž chcete natáhnout svou tematickou větev, a adresu URL repozitáře Git, z nějž chcete práci natáhnout, a vytvoří shrnutí všech změn, které by měl správce podle vaší žádosti natáhnout. Pokud chce například Jessica poslat Johnovi žádost o natažení a vytvořila předtím dvě revize v tematické větvi, kterou právě odeslala, může zadat tento příkaz:
411
+
412
+ $ git request-pull origin/master myfork
413
+ The following changes since commit 1edee6b1d61823a2de3b09c160d7080b8d1b3a40:
414
+ John Smith (1):
415
+ added a new function
416
+
417
+ are available in the git repository at:
418
+
419
+ git://githost/simplegit.git featureA
420
+
421
+ Jessica Smith (2):
422
+ add limit to log function
423
+ change log output to 30 from 25
424
+
425
+ lib/simplegit.rb | 10 +++++++++-
426
+ 1 files changed, 9 insertions(+), 1 deletions(-)
427
+
428
+ Výstup příkazu lze odeslat správci. Sdělí mu, odkud daná větev pochází, podá mu přehled o revizích a řekne mu, odkud lze práci stáhnout.
429
+
430
+ U projektů, u nichž nejste v roli správce, je většinou jednodušší, aby vaše větev `master` stále sledovala větev `origin/master` a abyste práci prováděli v tematických větvích, jichž se můžete beze všeho vzdát v případě, že budou odmítnuty. Jednotlivé úkoly izolované v tematických větvích mají také tu výhodu, že snáze přeskládáte svou práci, jestliže se průběžně posouvá konec hlavního repozitáře a vaše revize už nelze aplikovat čistě. Pokud například chcete do projektu přispět druhým tématem, nerozvíjejte svou práci v tematické větvi, kterou jste právě odeslali. Začněte znovu od začátku z větve `master` hlavního repozitáře:
431
+
432
+ $ git checkout -b featureB origin/master
433
+ $ (work)
434
+ $ git commit
435
+ $ git push myfork featureB
436
+ $ (email maintainer)
437
+ $ git fetch origin
438
+
439
+ Nyní mají obě vaše témata samostatný zásobník – podobně jako řada záplat – které můžete přepsat, přeskládat a upravit, aniž by se tím obě témata navzájem ovlivňovala nebo omezovala (viz obrázek 5-16).
440
+
441
+ Insert 18333fig0516.png
442
+ Obrázek 5-16. Výchozí historie revizí s větví featureB
443
+
444
+ Řekněme, že správce projektu natáhl do projektu několik jiných záplat a nyní vyzkoušel vaši první větev, jenže tu už nelze čistě začlenit. V takovém případě můžete zkusit přeskládat tuto větev na vrcholu větve `origin/master`, vyřešit za správce vzniklé konflikty a poté své změny ještě jednou odeslat:
445
+
446
+ $ git checkout featureA
447
+ $ git rebase origin/master
448
+ $ git push -f myfork featureA
449
+
450
+ Tím přepíšete svou historii, která teď bude vypadat jako na obrázku 5-17.
451
+
452
+ Insert 18333fig0517.png
453
+ Obrázek 5-17. Historie revizí s větví featureA
454
+
455
+ Protože jste větev přeskládali, musíte k příkazu git push přidat parametr `-f`, abyste mohli větev `featureA` na serveru nahradit revizí, která není jejím potomkem. Druhou možností je odeslat tuto novou práci do jiné větve na serveru (nazvané např. `featureAv2`).
456
+
457
+ Podívejme se ještě na jeden pravděpodobnější scénář: Správce se podíval na práci ve vaší druhé větvi, váš koncept se mu líbí, ale rád by, abyste změnili jeden implementační detail. Vy tuto příležitost využijete zároveň k tomu, abyste práci přesunuli tak, aby byla založena na aktuálním stavu projektu ve větvi `master`. Začnete vytvořením nové větve z aktuální větve `origin/master`, zkomprimujete do ní změny z větve `featureB`, vyřešíte všechny konflikty, provedete změnu v implementaci a to vše odešlete jako novou větev:
458
+
459
+ $ git checkout -b featureBv2 origin/master
460
+ $ git merge --no-commit --squash featureB
461
+ $ (change implementation)
462
+ $ git commit
463
+ $ git push myfork featureBv2
464
+
465
+ Parametr `--squash` (komprimovat) vezme všechnu vaši práci v začleněné větvi a zkomprimuje ji do jedné revize, která nevznikla jako výsledek sloučení a leží na vrcholu větve, na níž se právě nacházíte. Parametr `--no-commit` říká systému Git, aby revizi automaticky nezaznamenával. To vám umožní provést všechny změny z jiné větve a poté udělat více změn, než zaznamenáte novou revizi.
466
+
467
+ Nyní můžete správci oznámit, že jste provedli požadované změny a že je najde ve vaší větvi `featureBv2` (viz obrázek 5-18).
468
+
469
+ Insert 18333fig0518.png
470
+ Obrázek 5-18. Historie revizí s větví featureBv2
471
+
472
+ ### Velký veřejný projekt ###
473
+
474
+ Mnoho větších projektů si vytvořilo vlastní, odlišné procedury k doručování záplat. U každého projektu se tak budete muset informovat o konkrétních pravidlech. U mnoha větších veřejných projektů se však záplaty doručují na základě poštovní konference vývojářů, a proto se teď zaměřím na tento případ.
475
+
476
+ Pracovní postup je podobný jako v předchozím případě. Pro každou sérii záplat, na níž pracujete, vytvoříte samostatnou tematickou větev. Liší se to, jak je budete doručovat do projektu. Místo toho, abyste rozštěpili projekt a odeslali své změny do vlastní zapisovatelné verze, vygenerujete e-mailovou verzi každé série revizí a pošlete je e-mailem do poštovní konference vývojářů:
477
+
478
+ $ git checkout -b topicA
479
+ $ (work)
480
+ $ git commit
481
+ $ (work)
482
+ $ git commit
483
+
484
+ Nyní máte dvě revize, které chcete odeslat do poštovní konference. Pro vygenerování emailových zpráv ve formátu mbox použijte příkaz `git format-patch`. Každá revize se přetransformuje na e-mailovou zprávu, jejíž předmět bude tvořit první řádek zprávy k revizi a tělo e-mailu bude tvořeno zbytkem zprávy a samotnou záplatou. Výhodou tohoto postupu je, že aplikace záplaty z e-mailu, který byl vygenerován příkazem `format-patch`, v pořádku uchová všechny informace o revizi. Podrobněji si to ukážeme v následující části, až budeme aplikovat tyto revize:
485
+
486
+ $ git format-patch -M origin/master
487
+ 0001-add-limit-to-log-function.patch
488
+ 0002-changed-log-output-to-30-from-25.patch
489
+
490
+ Příkaz `format-patch` vypíše názvy souborů záplaty, kterou vytváří. Přepínač `-M` řekne systému Git, aby zkontroloval případné přejmenování. Soubory nakonec vypadají takto:
491
+
492
+ $ cat 0001-add-limit-to-log-function.patch
493
+ From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001
494
+ From: Jessica Smith <jessica@example.com>
495
+ Date: Sun, 6 Apr 2008 10:17:23 -0700
496
+ Subject: [PATCH 1/2] add limit to log function
497
+
498
+ Limit log functionality to the first 20
499
+
500
+ ---
501
+ lib/simplegit.rb | 2 +-
502
+ 1 files changed, 1 insertions(+), 1 deletions(-)
503
+
504
+ diff --git a/lib/simplegit.rb b/lib/simplegit.rb
505
+ index 76f47bc..f9815f1 100644
506
+ --- a/lib/simplegit.rb
507
+ +++ b/lib/simplegit.rb
508
+ @@ -14,7 +14,7 @@ class SimpleGit
509
+ end
510
+
511
+ def log(treeish = 'master')
512
+ - command("git log #{treeish}")
513
+ + command("git log -n 20 #{treeish}")
514
+ end
515
+
516
+ def ls_tree(treeish = 'master')
517
+ --
518
+ 1.6.2.rc1.20.g8c5b.dirty
519
+
520
+ Tyto soubory záplaty můžete také upravit a přidat k nim další informace určené pro seznam příjemců e-mailu, u nichž nechcete, aby byly obsaženy ve zprávě k revizi. Přidáte-li text mezi řádek `---` a začátek záplaty (řádek `lib/simplegit.rb`), vývojářům se zobrazí, ale aplikace záplaty ho obsahovat nebude.
521
+
522
+ Chcete-li e-mail odeslat do poštovní konference, můžete soubor buď vložit do svého e-mailového programu, nebo ho odeslat pomocí příkazového řádku. Vložení textu může často způsobovat problémy s formátováním, zvlášť v případě některých „chytřejších“ klientů, kteří správně nezachovávají nové řádky a jiné prázdné znaky. Git naštěstí nabízí nástroj, který vám pomůže odeslat správně formátované patche pomocí protokolu IMAP. Já budu dokumentovat odeslání záplaty na příkladu Gmailu, který používám jako svého e-mailového agenta. Podrobné instrukce pro celou řadu poštovních programů najdete na konci již dříve zmíněného souboru `Documentation/SubmittingPatches` ve zdrojovém kódu systému Git.
523
+
524
+ Nejprve je třeba nastavit sekci „imap“ v souboru `~/.gitconfig`. Každou hodnotu můžete nastavit zvlášť pomocí série příkazů `git config` nebo můžete vložit hodnoty ručně. Na konci by ale měl váš soubor config vypadat přibližně takto:
525
+
526
+ [imap]
527
+ folder = "[Gmail]/Drafts"
528
+ host = imaps://imap.gmail.com
529
+ user = user@gmail.com
530
+ pass = p4ssw0rd
531
+ port = 993
532
+ sslverify = false
533
+
534
+ Pokud váš server IMAP nepoužívá SSL, dva poslední řádky zřejmě nebudou vůbec třeba a hodnota hostitele bude `imap://`, a nikoli `imaps://`.
535
+ Až toto nastavení dokončíte, můžete použít příkaz `git imap-send`, jímž umístíte sérii záplat (patch) do složky Koncepty (Drafts) zadaného serveru IMAP:
536
+
537
+ $ cat *.patch |git imap-send
538
+ Resolving imap.gmail.com... ok
539
+ Connecting to [74.125.142.109]:993... ok
540
+ Logging in...
541
+ sending 2 messages
542
+ 100% (2/2) done
543
+
544
+ V tomto okamžiku byste měli být schopni přejít do složky Drafts, změnit pole To na mailing list, do kterého záplatu posíláte, případně pole CC na správce nebo na osobu zodpovědnou za tuto část, a odeslat.
545
+
546
+ Záplaty můžete odesílat i přes SMTP server. Stejně jako v předchozím případu můžete nastavit sérií příkazů `git config` každou hodnotu zvlášť, nebo je můžete vložit ručně do sekce sendemail souboru `~/.gitconfig`:
547
+
548
+ [sendemail]
549
+ smtpencryption = tls
550
+ smtpserver = smtp.gmail.com
551
+ smtpuser = user@gmail.com
552
+ smtpserverport = 587
553
+
554
+ Jakmile je to hotové, můžete záplaty odeslat příkazem `git send-email`:
555
+
556
+ $ git send-email *.patch
557
+ 0001-added-limit-to-log-function.patch
558
+ 0002-changed-log-output-to-30-from-25.patch
559
+ Who should the emails appear to be from? [Jessica Smith <jessica@example.com>]
560
+ Emails will be sent from: Jessica Smith <jessica@example.com>
561
+ Who should the emails be sent to? jessica@example.com
562
+ Message-ID to be used as In-Reply-To for the first email? y
563
+
564
+ Git poté vytvoří log s určitými informacemi, který bude pro každou záplatu, kterou posíláte, vypadat asi takto:
565
+
566
+ (mbox) Adding cc: Jessica Smith <jessica@example.com> from
567
+ \line 'From: Jessica Smith <jessica@example.com>'
568
+ OK. Log says:
569
+ Sendmail: /usr/sbin/sendmail -i jessica@example.com
570
+ From: Jessica Smith <jessica@example.com>
571
+ To: jessica@example.com
572
+ Subject: [PATCH 1/2] added limit to log function
573
+ Date: Sat, 30 May 2009 13:29:15 -0700
574
+ Message-Id: <1243715356-61726-1-git-send-email-jessica@example.com>
575
+ X-Mailer: git-send-email 1.6.2.rc1.20.g8c5b.dirty
576
+ In-Reply-To: <y>
577
+ References: <y>
578
+
579
+ Result: OK
580
+
581
+ ### Shrnutí ###
582
+
583
+ V této části jsme popsali několik obvyklých pracovních postupů při přispívání do velmi odlišných typů projektů Git, s nimiž se můžete setkat. Představili jsme k nim také nové nástroje, které vám mohou v těchto procesech pomoci. V další části se na projekty podíváme z té druhé strany – ukážeme, jak může vypadat jejich správa. Dozvíte se, jak být benevolentním diktátorem nebo integračním manažerem.
584
+
585
+ ## Správa projektu ##
586
+
587
+ Při práci na projektech Git možná nevystačíte jen s vědomostmi, jak do projektu efektivně přispívat. Pravděpodobně budete jednou potřebovat vědět něco i o správě projektů. Do této oblasti spadá přijímání a aplikace záplat vygenerovaných příkazem `format-patch`, které vám vývojáři poslali, nebo třeba integrace změn ve vzdálených větvích pro repozitáře, které jste do svého projektu přidali jako vzdálené repozitáře. Ať spravujete standardní repozitář, nebo pomáháte při ověřování či schvalování záplat, budete muset vědět, jak přijímat práci ostatních přispěvatelů, a to způsobem, který je pro ostatní co nejčistší a pro vás dlouhodobě udržitelný.
588
+
589
+ ### Práce v tematických větvích ###
590
+
591
+ Pokud uvažujete o integraci nové práce do projektu, je většinou dobré zkusit si to v tematické větvi, tj. dočasné větvi, kterou vytvoříte konkrétně pro tento účel. Snadno tak můžete záplatu individuálně opravit, a pokud není funkční, opustit ji, dokud nebudete mít čas k její opravě. Pokud pro větev vytvoříte jednoduchý název spojený s tématem testované práce (např. `ruby_client` nebo něco obdobně popisného), snadno se na větev rozpomenete, jestliže se k ní musíte později vrátit. Správce projektů Git přiřazuje těmto větvím také jmenný prostor, např. `sc/ruby_client`, kde `sc` je zkratka pro osobu, která práci vytvořila.
592
+ Jak si vzpomínáte, můžete vytvořit větev založenou na své hlavní větvi:
593
+
594
+ $ git branch sc/ruby_client master
595
+
596
+ Nebo pokud na ni chcete rovnou přepnout, můžete použít parametr `checkout -b`:
597
+
598
+ $ git checkout -b sc/ruby_client master
599
+
600
+ Nyní tedy můžete vložit svůj příspěvek do této tematické větve a rozhodnout se, zda ho chcete začlenit do svých trvalejších větví.
601
+
602
+ ### Aplikace záplat z e-mailu ###
603
+
604
+ Jestliže obdržíte e-mailem záplatu, kterou potřebujete integrovat do svého projektu, aplikujete ho nejprve do tematické větve, v níž ho vyhodnotíte. Existují dva způsoby aplikace záplaty z e-mailu: příkazem `git apply` nebo příkazem `git am`.
605
+
606
+ #### Aplikace záplaty příkazem „apply“ ####
607
+
608
+ Pokud dostanete záplatu od někoho, kdo ji vygeneroval příkazem `git diff` nebo unixovým příkazem `diff`, můžete ho aplikovat příkazem `git apply`. Předpokládejme, že jste záplatu uložili jako `/tmp/patch-ruby-client.patch`. Aplikaci pak provedete takto:
609
+
610
+ $ git apply /tmp/patch-ruby-client.patch
611
+
612
+ Tím změníte soubory ve svém pracovním adresáři. Je to téměř stejné, jako byste k aplikaci záplaty použili příkaz `patch -p1`. Tento postup je však přísnější a nepřijímá tolik přibližných shod jako příkaz patch. Poradí si také s přidanými, odstraněnými a přejmenovanými soubory, jsou-li popsány ve formátu `git diff`, což příkaz `patch` nedělá. A konečně příkaz `git apply` pracuje na principu „aplikuj vše, nebo zruš vše“. Buď jsou tedy aplikovány všechny soubory, nebo žádný. Naproti tomu příkaz `patch` může aplikovat soubory záplaty jen částečně a zanechat váš pracovní adresář v neurčitém stavu. Příkaz `git apply` je tedy celkově víc paranoidní než příkaz `patch`. Tímto příkazem ostatně ani nezapíšete revizi, po jeho spuštění budete muset připravit a zapsat provedené změny ručně.
613
+
614
+ Příkaz `git apply` můžete použít také ke kontrole, zda bude záplata aplikována čistě. V takovém případě použijte na patch příkaz `git apply --check`:
615
+
616
+ $ git apply --check 0001-seeing-if-this-helps-the-gem.patch
617
+ error: patch failed: ticgit.gemspec:1
618
+ error: ticgit.gemspec: patch does not apply
619
+
620
+ Pokud se nezobrazí žádný výstup, záplata bude aplikována čistě. Jestliže kontrola selže, příkaz vrací nenulový návratový kód, a proto ho lze snadno používat ve skriptech.
621
+
622
+ #### Aplikace záplaty příkazem „am“ ####
623
+
624
+ Pokud je přispěvatel uživatelem systému Git a byl natolik dobrý, že k vygenerování záplaty použil příkaz `format-patch`, budete mít usnadněnou práci, protože záplata obsahuje informace o autorovi a zprávu k revizi. Můžete-li, doporučte svým přispěvatelům, aby místo příkazu `diff` používali příkaz `format-patch`. Příkaz `git apply` je dobré používat jen pro starší záplaty a podobně.
625
+
626
+ K aplikaci patche vygenerovaného příkazem `format-patch` použijte příkaz `git am`. Příkaz `git am` je technicky koncipován tak, aby přečetl soubor mbox, tj. formát prostého textu pro ukládání jedné či více e-mailových zpráv do jednoho textového souboru. Vypadá například takto:
627
+
628
+ From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001
629
+ From: Jessica Smith <jessica@example.com>
630
+ Date: Sun, 6 Apr 2008 10:17:23 -0700
631
+ Subject: [PATCH 1/2] add limit to log function
632
+
633
+ Limit log functionality to the first 20
634
+
635
+ Toto je začátek výstupu příkazu format-patch, s nímž jsme se setkali v předchozí části. Zároveň je to také platný e-mailový formát mbox. Jestliže vám přispěvatel řádně poslal záplatu e-mailem pomocí příkazu `git send-email` a vy záplatu stáhnete do formátu mbox, můžete na soubor mbox použít příkaz `git am`, který začne aplikovat všechny záplaty, které najde. Jestliže spustíte poštovního klienta, který dokáže uložit několik e-mailů ve formátu mbox, můžete do jednoho souboru uložit celou sérii záplat a příkazem `git am` je pak aplikovat všechny najednou.
636
+
637
+ Pokud však někdo nahrál soubor záplaty vygenerovaný příkazem `format-patch` do tiketového nebo podobného systému, můžete soubor uložit lokálně a poté na tento uložený soubor použít příkaz `git am`. Tímto způsobem záplatu aplikujete:
638
+
639
+ $ git am 0001-limit-log-function.patch
640
+ Applying: add limit to log function
641
+
642
+ Jak vidíte, záplata byla aplikována čistě a automaticky byla vytvořena nová revize. Informace o autorovi jsou převzaty z polí `From` a `Date` v e-mailu a zpráva k revizi je převzata z `Subject` a těla e-mailu (před samotnou záplatou). Pokud byl patch aplikován například ze souboru mbox v předchozím příkladu, vygenerovaná revize bude vypadat zhruba takto:
643
+
644
+ $ git log --pretty=fuller -1
645
+ commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0
646
+ Author: Jessica Smith <jessica@example.com>
647
+ AuthorDate: Sun Apr 6 10:17:23 2008 -0700
648
+ Commit: Scott Chacon <schacon@gmail.com>
649
+ CommitDate: Thu Apr 9 09:19:06 2009 -0700
650
+
651
+ add limit to log function
652
+
653
+ Limit log functionality to the first 20
654
+
655
+ Informace `Commit` uvádí osobu, která patch aplikovala, a čas, kdy se tak stalo. Informace `Author` naproti tomu označuje jedince, který patch původně vytvořil, a kdy tak učinil.
656
+
657
+ Může se ale stát, že záplata nebude aplikována čistě. Vaše hlavní větev se mohla příliš odchýlit od větve, z níž byla záplata vytvořena, nebo je záplata závislá na jiné záplatě, kterou jste ještě neaplikovali. V takovém případě proces `git am` neproběhne a Git se vás zeptá, co chcete udělat dál:
658
+
659
+ $ git am 0001-seeing-if-this-helps-the-gem.patch
660
+ Applying: seeing if this helps the gem
661
+ error: patch failed: ticgit.gemspec:1
662
+ error: ticgit.gemspec: patch does not apply
663
+ Patch failed at 0001.
664
+ When you have resolved this problem run "git am --resolved".
665
+ If you would prefer to skip this patch, instead run "git am --skip".
666
+ To restore the original branch and stop patching run "git am --abort".
667
+
668
+ Tento příkaz vloží poznámku o konfliktu (conflict marker) do všech souborů, u nichž došlo k problémům, stejně jako u operací sloučení nebo přeskládání, při nichž došlo ke konfliktu. Problém se také řeší stejným způsobem. Úpravou souboru odstraňte konflikt, připravte nový soubor k zapsání a spusťte příkaz `git am --resolved`, jímž se přesunete k následující záplatě:
669
+
670
+ $ (fix the file)
671
+ $ git add ticgit.gemspec
672
+ $ git am --resolved
673
+ Applying: seeing if this helps the gem
674
+
675
+ Pokud chcete, aby se Git pokusil vyřešit konflikt inteligentněji, můžete zadat parametr `-3`. Git se pokusí o třícestné sloučení. Tato možnost není nastavena jako výchozí, protože ji nelze použít v situaci, kdy revize, o níž záplata říká, že je na ní založen, není obsažena ve vašem repozitáři. Pokud tuto revizi vlastníte – byla-li záplata založena na veřejné revizi – počíná si parametr `-3` při aplikaci kolidující záplaty většinou mnohem inteligentněji.
676
+
677
+ $ git am -3 0001-seeing-if-this-helps-the-gem.patch
678
+ Applying: seeing if this helps the gem
679
+ error: patch failed: ticgit.gemspec:1
680
+ error: ticgit.gemspec: patch does not apply
681
+ Using index info to reconstruct a base tree...
682
+ Falling back to patching base and 3-way merge...
683
+ No changes -- Patch already applied.
684
+
685
+ V tomto případě jsem se pokoušel aplikovat záplatu, kterou už jsem jednou aplikoval. Bez parametru `-3` se celá situace tváří jako konflikt.
686
+
687
+ Pokud aplikujete několik záplat z jednoho souboru mbox, můžete příkaz `am` spustit také v interaktivním režimu, který zastaví před každou záplatou, kterou najde, a zeptá se vás, zda ji chcete aplikovat:
688
+
689
+ $ git am -3 -i mbox
690
+ Commit Body is:
691
+ --------------------------
692
+ seeing if this helps the gem
693
+ --------------------------
694
+ Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all
695
+
696
+ To oceníte v situaci, kdy máte uložených několik záplat. Pokud si nepamatujete, o co v dané záplatě šlo, můžete si ho před aplikací prohlédnout. Stejně tak vyloučíte záplaty, které jste už jednou aplikovali.
697
+
698
+ Až budete mít všechny záplaty aplikovány a zapsány do tematické větve, můžete se rozhodnout, zda a jak je chcete integrovat do některé z trvalejších větví.
699
+
700
+ ### Checkout vzdálených větví ###
701
+
702
+ Pokud váš příspěvek pochází od uživatele systému Git, který založil vlastní repozitář, odeslal do něj sérii změn a následně vám poslal adresu URL k repozitáři a název vzdálené větve, v níž změny najdete, můžete je přidat jako vzdálené a lokálně je začlenit.
703
+
704
+ Pokud vám tedy například Jessica pošle e-mail, že vytvořila skvělou novou funkci ve větvi `ruby-client` ve svém repozitáři, můžete funkci otestovat tak, že přidáte větev jako vzdálenou a provedete její lokální checkout:
705
+
706
+ $ git remote add jessica git://github.com/jessica/myproject.git
707
+ $ git fetch jessica
708
+ $ git checkout -b rubyclient jessica/ruby-client
709
+
710
+ Pokud vám později opět pošle e-mail, že jiná větev obsahuje další skvělou funkci, můžete tuto větev vyzvednout a provést její checkout, protože už máte nastaven tento repozitář jako vzdálený.
711
+
712
+ Tuto možnost využijete zejména tehdy, když s někým spolupracujete dlouhodobě. Má-li někdo jen jednu záplatu, jíž chce právě teď přispět, bude rychlejší, pokud vám záplatu doručí e-mailem, než abyste všechny vývojáře nutili provozovat kvůli pár záplatám vlastní servery a pravidelně přidávat a odstraňovat vzdálené repozitáře. Pravděpodobně také nebudete chtít mít nastaveny stovky vzdálených serverů, z nichž byste dostávali po jednom nebo dvou záplatách. Situaci vám mohou usnadnit skripty a hostované služby. Do velké míry tu záleží na tom, jak vy a vaši vývojáři k vývoji přistupujete.
713
+
714
+ Další výhodou tohoto postupu je, že získáte rovněž historii revizí. Přestože můžete mít oprávněné problémy se slučováním, víte, kde ve své historii můžete hledat příčiny. Řádné třícestné sloučení je vždy lepším řešením, než zadat parametr `-3` a doufat, že byl patch vygenerován z veřejné revize, k níž máte přístup.
715
+
716
+ Pokud s někým nespolupracujete dlouhodobě, ale přesto od něj chcete stáhnout data touto cestou, můžete zadat adresu URL vzdáleného repozitáře k příkazu `git pull`. Příkaz provede jednorázové stažení a nebude ukládat URL jako referenci na vzdálený repozitář:
717
+
718
+ $ git pull git://github.com/onetimeguy/project.git
719
+ From git://github.com/onetimeguy/project
720
+ * branch HEAD -> FETCH_HEAD
721
+ Merge made by recursive.
722
+
723
+ ### Jak zjistit provedené změny ###
724
+
725
+ Nyní máte tematickou větev s prací, kterou jste obdrželi od jiného vývojáře. V tomto okamžiku můžete určit, jak s ní chcete naložit. V této části zopakujeme některé příkazy a podíváme se, jak je můžete použít, chcete-li zjistit, co přesně se stane, pokud novou práci začleníte do své hlavní větve.
726
+
727
+ Často může být užitečné získat přehled o všech revizích, které jsou obsaženy v určité větvi, ale dosud nejsou ve vaší hlavní větvi. Revize v hlavní větvi lze vyloučit vložením parametru `--not` před název větve. Pokud vám například přispěvatel pošle dvě záplaty a vy vytvoříte větev s názvem `contrib`, do níž tyto záplaty aplikujete, můžete použít tento příkaz:
728
+
729
+ $ git log contrib --not master
730
+ commit 5b6235bd297351589efc4d73316f0a68d484f118
731
+ Author: Scott Chacon <schacon@gmail.com>
732
+ Date: Fri Oct 24 09:53:59 2008 -0700
733
+
734
+ seeing if this helps the gem
735
+
736
+ commit 7482e0d16d04bea79d0dba8988cc78df655f16a0
737
+ Author: Scott Chacon <schacon@gmail.com>
738
+ Date: Mon Oct 22 19:38:36 2008 -0700
739
+
740
+ updated the gemspec to hopefully work better
741
+
742
+ Chcete-li zjistit, jaké změny byly v jednotlivých revizích provedeny, můžete k příkazu `git log` přidat parametr `-p`, který ke každé revizi připojí rozdíly ve formátu diff.
743
+
744
+ Chcete-li vidět plný výpis diff, jak by vypadaly rozdíly, kdybyste tuto tematickou větev začlenili do jiné větve, můžete použít speciální trik, který vám zobrazí požadované informace. Můžete zadat následující příkaz:
745
+
746
+ $ git diff master
747
+
748
+ Výstupem tohoto příkazu bude výpis diff, který však může být lehce matoucí. Jestliže se vaše větev `master` posunula vpřed od chvíle, kdy jste z ní vytvořili tematickou větev, budou výstupem příkazu zdánlivě nesmyslné výsledky. Je to z toho důvodu, že Git přímo srovnává snímky poslední revize v tematické větvi, na níž se nacházíte, se snímky poslední revize ve větvi `master`. Pokud jste například do souboru ve větvi `master` přidali jeden řádek, přímé srovnání snímků bude vypadat, jako by měla tematická větev tento řádek odstranit.
749
+
750
+ Pokud je větev `master` přímým předkem vaší tematické větve, nebude s příkazem žádný problém. Pokud se však obě historie v nějakém bodě rozdělily, bude výpis diff vypadat, jako byste chtěli přidat všechna nová data v tematické větvi a odstranit vše, co je pouze ve větvi `master`.
751
+
752
+ To, co chcete vidět ve skutečnosti, jsou změny přidané do tematické větve, práci, kterou provedete začleněním této větve do větve hlavní. Tohoto srovnání dosáhnete tak, že necháte Git porovnat poslední revizi ve vaší tematické větvi s prvním předkem, kterého má společného s hlavní větví.
753
+
754
+ Můžete tedy explicitně najít společného předka obou větví a spustit na něm příkaz diff:
755
+
756
+ $ git merge-base contrib master
757
+ 36c7dba2c95e6bbb78dfa822519ecfec6e1ca649
758
+ $ git diff 36c7db
759
+
760
+ To však není příliš pohodlný způsob, a proto Git nabízí jinou možnost, jak lze provést stejnou věc: trojtečkovou syntaxi. V kontextu příkazu `diff` můžete vložit tři tečky za druhou větev – získáte výpis `diff` mezi poslední revizí větve, na níž se nacházíte, a společným předkem s druhou větví:
761
+
762
+ $ git diff master...contrib
763
+
764
+ Tento příkaz zobrazí pouze práci, která byla ve vaší aktuální tematické větvi provedena od chvíle, kdy se oddělila od hlavní větve. Určitě uděláte dobře, pokud si tuto syntaxi zapamatujete.
765
+
766
+ ### Integrace příspěvků ###
767
+
768
+ Když už je práce v tematické větvi připravena a může být integrována do některé z významnějších větví, vyvstává otázka, jak to provést. A vůbec, jaký celkový pracovní postup zvolíte ke správě projektu? Existuje hned několik možností. Na některé z nich se můžeme podívat.
769
+
770
+ #### Pracovní postupy založené na slučování ####
771
+
772
+ Jeden jednoduchý pracovní postup začlení vaší práci do větve `master`. V tomto scénáři obsahuje vaše větev `master` převážně jen stabilní kód. Máte-li v tematické větvi práci, kterou jste vytvořili nebo kterou vám někdo doručil a vy jste ji schválili, začleníte ji do své hlavní větve, smažete tematickou větev a proces může pokračovat. Máme-li repozitář s prací ve dvou větvích pojmenovaných `ruby_client` a `php_client`, který vypadá jako na obrázku 5-19, a začleníme nejprve větev `ruby_client` a poté `php_client`, bude naše historie vypadat jako na obrázku 5-20.
773
+
774
+ Insert 18333fig0519.png
775
+ Obrázek 5-19. Historie s několika tematickými větvemi
776
+
777
+ Insert 18333fig0520.png
778
+ Obrázek 5-20. Po začlenění tematické větve
779
+
780
+ Jedná se patrně o nejjednodušší pracovní postup. Je však problematický, pokud ho používáme u velkých repozitářů nebo projektů.
781
+
782
+ Máte-li více vývojářů nebo větší projekt, pravděpodobně budete chtít použít přinejmenším dvoufázový cyklus začlenění. V tomto scénáři máte dvě dlouhodobé větve, hlavní větev `master` a větev `develop`. Určíte, že větev `master` bude aktualizována, pouze když je k dispozici velmi stabilní verze a do větve `develop` je integrován veškerý nový kód. Obě tyto větve pravidelně odesíláte do veřejného repozitáře. Pokaždé, když máte novou tematickou větev k začlenění (obrázek 5-21), začleníte ji do větve `develop` (obrázek 5-22). Když poté označujete vydání, posunete větev `master` rychle vpřed do místa, kde je nyní větev `develop` stabilní (obrázek 5-23).
783
+
784
+ Insert 18333fig0521.png
785
+ Obrázek 5-21. Před začleněním tematické větve
786
+
787
+ Insert 18333fig0522.png
788
+ Obrázek 5-22. Po začlenění tematické větve
789
+
790
+ Insert 18333fig0523.png
791
+ Obrázek 5-23. Po vydání tematické větve
792
+
793
+ Pokud někdo při tomto postupu klonuje repozitář vašeho projektu, může provést buď checkout hlavní větve, aby získal nejnovější stabilní verzi a udržoval ji aktuální, nebo checkout větve develop, která může být ještě o něco napřed.
794
+ Tento koncept můžete dále rozšířit o integrační větev, v níž budete veškerou práci slučovat. Teprve pokud je kód v této větvi stabilní a projde testováním, začleníte ho do větve develop. A až se větev develop ukáže v některém okamžiku jako stabilní, posunete rychle vpřed i svou hlavní větev.
795
+
796
+ #### Pracovní postupy se začleňováním velkého objemu dat ####
797
+
798
+ Váš projekt Git má čtyři trvalé větve: `master`, `next` a `pu` (proposed updates, tj. návrh aktualizací) pro novou práci a `maint` pro backporty správy. Pokud přispěvatelé vytvoří novou práci, je shromažďována v tematických větvích v repozitáři správce podobným způsobem, jaký už jsem popisoval (viz obrázek 5-24). Nyní budou tematické větve vyhodnoceny, zda jsou bezpečné a mohou být aplikovány, nebo zda potřebují další úpravy. Jsou-li vyhodnoceny jako bezpečné, budou začleněny do větve `next` a ta bude následně odeslána do repozitáře, aby mohli všichni vyzkoušet, jak fungují tematické větve po sloučení.
799
+
800
+ Insert 18333fig0524.png
801
+ Obrázek 5-24. Správa komplexní série současně zpracovávaných příspěvků v tematických větvích
802
+
803
+ Pokud ale tematické větve vyžadují další úpravy, budou začleněny do větve `pu`. Pokud se ukáže, že jsou tyto tematické větve naprosto stabilní, budou začleněny do větve `master` a poté budou znovu sestaveny z tematických větví, které byly ve větvi `next`, ale ještě se nedostaly do větve `master`. To znamená, že se větev `master` téměř neustále posouvá vpřed, větev `next` je čas od času přeskládána a větev `pu` je přeskládávána ještě o něco častěji (viz obrázek 5-25).
804
+
805
+ Insert 18333fig0525.png
806
+ Obrázek 5-25. Začlenění tematických větví s příspěvky do dlouhodobých integračních větví
807
+
808
+ Byla-li tematická větev konečně začleněna do větve `master`, může být odstraněna z repozitáře. Projekt Git má kromě toho větev `maint`, která byla odštěpena z posledního vydání a představuje záplaty backportované pro případ, že by bylo třeba vydat opravnou verzi. Pokud tedy klonujete repozitář Git, můžete stáhnout až čtyři větve, a hodnotit tak projekt na čtyřech různých úrovních vývoje. Záleží na vás, do jaké hloubky chcete proniknout nebo jak chcete přispívat. A správce projektu má k dispozici strukturovaný pracovní postup k evaluaci nových příspěvků.
809
+
810
+ #### Pracovní postupy s přeskládáním a částečným převzetím ####
811
+
812
+ Jiní správci dávají před začleněním práce z příspěvků přednost jejímu přeskládání nebo částečnému převzetí na vrchol hlavní větve, čímž udržují historii co nejlineárnější. Máte-li určitou práci v tematické větvi a rozhodli jste se, že ji integrujete, přejdete na tuto větev a spustíte příkaz rebase, jímž znovu sestavíte příslušné změny na vrcholu svojí aktuální hlavní větve (příp. větve `develop` apod.). Pokud vše funguje, můžete větev `master` posunout rychle vpřed a výsledkem procesu bude lineární historie projektu.
813
+
814
+ Druhým způsobem, jak přesunout práci z jedné větve do druhé, je tzv. částečné převzetí (angl. cherry picking, tedy něco jako „vyzobání třešniček“). Částečné převzetí lze v systému Git přirovnat k přeskládání jedné revize. Při této operaci vezme systém záplatu, která byla provedena v dané revizi, a pokusí se ji znovu aplikovat na větev, na níž se právě nacházíte. To využijete například v situaci, kdy máte několik revizí v tematické větvi, ale chcete integrovat pouze jednu z nich. Částečné převzetí však můžete použít i místo přeskládání, pokud máte v tematické větvi pouze jednu revizi. Uvažujme tedy projekt, který vypadá jako na obrázku 5-26.
815
+
816
+ Insert 18333fig0526.png
817
+ Obrázek 5-26. Uvažovaná historie před částečným převzetím
818
+
819
+ Chcete-li do hlavní větve natáhnout revizi `e43a6`, můžete zadat následující příkaz:
820
+
821
+ $ git cherry-pick e43a6fd3e94888d76779ad79fb568ed180e5fcdf
822
+ Finished one cherry-pick.
823
+ [master]: created a0a41a9: "More friendly message when locking the index fails."
824
+ 3 files changed, 17 insertions(+), 3 deletions(-)
825
+
826
+ Tímto natáhnete stejnou změnu, která byla provedena revizí `e43a6`, avšak hodnota SHA-1 obou revizí se bude lišit, neboť bude rozdílné datum aplikace. Vaše historie revizí bude nyní vypadat jako na obrázku 5-27.
827
+
828
+ Insert 18333fig0527.png
829
+ Obrázek 5-27. Historie po částečném převzetí revize z tematické větve
830
+
831
+ Nyní můžete tematickou větev odstranit a zahodit revize, které nehodláte natáhnout do jiné větve.
832
+
833
+ ### Označení vydání značkou ###
834
+
835
+ Až se rozhodnete vydat určitou verzi, pravděpodobně ji budete chtít označit značkou, abyste mohli toto vydání v kterémkoli okamžiku v budoucnosti obnovit. Novou značku vytvoříte podle návodu v kapitole 2. Pokud se rozhodnete podepsat značku jako správce, bude označení probíhat takto:
836
+
837
+ $ git tag -s v1.5 -m 'my signed 1.5 tag'
838
+ You need a passphrase to unlock the secret key for
839
+ user: "Scott Chacon <schacon@gmail.com>"
840
+ 1024-bit DSA key, ID F721C45A, created 2009-02-09
841
+
842
+ Pokud své značky podepisujete, můžete mít problémy s distribucí veřejného klíče PGP použitého k podepsání značky. Správce projektu Git vyřešil tento problém tak, že přidal svůj veřejný klíč jako blob do repozitáře a poté vložil značku, která ukazuje přímo na tento obsah. Pomocí příkazu `gpg --list-keys` můžete určit, jaký klíč chcete:
843
+
844
+ $ gpg --list-keys
845
+ /Users/schacon/.gnupg/pubring.gpg
846
+ ---------------------------------
847
+ pub 1024D/F721C45A 2009-02-09 [expires: 2010-02-09]
848
+ uid Scott Chacon <schacon@gmail.com>
849
+ sub 2048g/45D02282 2009-02-09 [expires: 2010-02-09]
850
+
851
+ Poté můžete klíč přímo importovat do databáze Git: vyexportujte ho a použijte příkaz `git hash-object`, který zapíše nový blob s tímto obsahem do systému Git a vrátí vám otisk SHA-1 tohoto blobu:
852
+
853
+ $ gpg -a --export F721C45A | git hash-object -w --stdin
854
+ 659ef797d181633c87ec71ac3f9ba29fe5775b92
855
+
856
+ Nyní máte obsah svého klíče v systému Git a můžete vytvořit značku, která bude ukazovat přímo na něj. Zadejte proto novou hodnotu SHA-1, kterou jste získali příkazem `hash-object`:
857
+
858
+ $ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92
859
+
860
+ Zadáte-li příkaz `git push --tags`, začnete značku `maintainer-pgp-pub` sdílet s ostatními. Bude-li chtít značku kdokoli ověřit, může přímo importovat váš klíč PGP tak, že stáhne blob z databáze a naimportuje ho do programu GPG:
861
+
862
+ $ git show maintainer-pgp-pub | gpg --import
863
+
864
+ Klíč pak může použít k ověření všech vašich podepsaných značek. Pokud navíc zadáte do zprávy značky další instrukce k jejímu ověření, může si je koncový uživatel zobrazit příkazem `git show <tag>`.
865
+
866
+ ### Vygenerování čísla sestavení ###
867
+
868
+ Git nepoužívá pro jednotlivé revize monotónně rostoucí čísla („v123“ apod.), a proto možná rádi využijete příkaz `git describe`, jímž lze každé revizi přiřadit běžně zpracovatelný název. Git vám poskytne název nejbližší značky s počtem revizí na vrcholu této značky a část hodnoty SHA-1 revize, k níž se popis vztahuje:
869
+
870
+ $ git describe master
871
+ v1.6.2-rc1-20-g8c5b85c
872
+
873
+ Díky tomu lze snímek nebo sestavení (build) vyexportovat a přiřadit mu pro člověka srozumitelný název. Pokud sestavujete Git ze zdrojového kódu naklonovaného z repozitáře Git, získáte po spuštění příkazu `git --version` něco, co vypadá zhruba podobně. Zadáváte-li popis revize, kterou jste právě opatřili značkou, dostanete název této značky.
874
+
875
+ Příkaz `git describe` upřednostňuje anotované značky (značky vytvořené s příznakem `-a` nebo `-s`). Pokud tedy používáte příkaz `git describe`, abyste se při vytváření popisu ujistili, že je revize pojmenována správně, měli byste značky jednotlivých vydání vytvářet tímto způsobem. Tento řetězec můžete také použít jako cíl příkazu checkout nebo show, ačkoli ty pracují se zkrácenou hodnotou SHA-1, a tak nebudou platné navždy. Například jádro Linuxu nyní přešlo z 8 na 10 znaků, aby byla zajištěna jedinečnost objektů SHA-1. Starší výstupy příkazu `git describe` proto už nebudou platné.
876
+
877
+ ### Příprava vydání ###
878
+
879
+ Nyní budete chtít sestavení vydat. Jednou z věcí, kterou budete chtít udělat, je vytvoření archivu nejnovějšího snímku vašeho kódu pro všechny nebohé duše, které nepoužívají systém Git. Příkaz pro vytvoření archivu zní `git archive`:
880
+
881
+ $ git archive master --prefix='project/' | gzip > `git describe master`.tar.gz
882
+ $ ls *.tar.gz
883
+ v1.6.2-rc1-20-g8c5b85c.tar.gz
884
+
885
+ Až někdo tento tarball otevře, získá nejnovější snímek vašeho projektu v projektovém adresáři. Stejným způsobem můžete vytvořit také archiv zip. K příkazu `git archive` stačí přidat parametr `--format=zip`:
886
+
887
+ $ git archive master --prefix='project/' --format=zip > `git describe master`.zip
888
+
889
+ Nyní máte vytvořen tarball a archiv zip k vydání svého projektu, které můžete nahrát na svou webovou stránku nebo rozeslat e-mailem.
890
+
891
+ ### Příkaz „shortlog“ ###
892
+
893
+ Nyní je na čase obeslat e-mailem poštovní konferenci lidí, kteří chtějí vědět, co je ve vašem projektu nového. Elegantním způsobem, jak rychle získat určitý druh záznamu o změnách (changelog), které byly do projektu přidány od posledního vydání nebo e-mailu, je použít příkaz `git shortlog`. Příkaz shrne všechny revize v zadaném rozmezí. Například následující příkaz zobrazí shrnutí všech revizí od posledního vydání (pokud bylo vaše poslední vydání pojmenováno v1.0.1):
894
+
895
+ $ git shortlog --no-merges master --not v1.0.1
896
+ Chris Wanstrath (8):
897
+ Add support for annotated tags to Grit::Tag
898
+ Add packed-refs annotated tag support.
899
+ Add Grit::Commit#to_patch
900
+ Update version and History.txt
901
+ Remove stray `puts`
902
+ Make ls_tree ignore nils
903
+
904
+ Tom Preston-Werner (4):
905
+ fix dates in history
906
+ dynamic version method
907
+ Version bump to 1.0.2
908
+ Regenerated gemspec for version 1.0.2
909
+
910
+ Výstupem příkazu je čisté shrnutí všech revizí od v1.0.1, seskupené podle autora, kterého můžete přidat do e-mailu své konference.
911
+
912
+ ## Shrnutí ##
913
+
914
+ V tomto okamžiku byste tedy už měli hravě zvládat přispívání do projektů v systému Git, správu vlastního projektu i integraci příspěvků jiných uživatelů. Gratulujeme, nyní je z vás efektivní vývojář v systému Git! V další kapitole poznáte další výkonné nástroje a tipy k řešení složitých situací, které z vás udělají opravdového mistra mezi uživateli systému Git.