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,854 @@
1
+ # Git на сервере #
2
+
3
+ К этому моменту вы уже должны уметь решать большинство повседневных задач, для которых будете использовать Git. Однако, для совместной работы в Git'е, вам необходим удалённый репозиторий. Несмотря на то, что технически вы можете отправлять и забирать изменения непосредственно из личных репозиториев, делать это не рекомендуется. Вы легко можете испортить то, над чем работают другие, если не будете аккуратны. К тому же, вам бы наверняка хотелось, чтобы остальные имели доступ к репозиторию даже если ваш компьютер выключен, поэтому наличие более надежного репозитория обычно весьма полезно. Поэтому предпочтительный метод взаимодействия с кем-либо — это создание промежуточного репозитория, к которому вы оба будете иметь доступ, и отправка и получение изменений через него. Мы будем называть этот репозиторий "Git-сервер", но обычно размещение Git-репозитория требует очень небольшого количества ресурсов, поэтому вряд ли вам для этого будет нужен весь сервер.
4
+
5
+ Запустить Git-сервер просто. Для начала вам следует выбрать протокол, который вы будете использовать для связи с сервером. Первая часть этой главы описывает доступные протоколы и их достоинства и недостатки. Следующие части освещают базовые конфигурации с использованием этих протоколов, а также настройку вашего сервера для работы с ними. Наконец, мы рассмотрим несколько вариантов готового хостинга, если вы не против разместить ваш код на чьём-то сервере и вы не хотите мучиться с настройками и поддержкой вашего собственного сервера.
6
+
7
+ Если вас не интересует настройка собственного сервера, вы можете перейти сразу к последней части этой главы для настройки аккаунта на Git-хостинге, и затем перейти к следующей главе, где мы обсудим различные аспекты работы с распределённой системой контроля версий.
8
+
9
+ Удалённый репозиторий — это обычно _голый (чистый, bare) репозиторий_ — Git-репозиторий, не имеющий рабочего каталога. Поскольку этот репозиторий используется только для обмена, нет причин создавать рабочую копию на диске, и он содержит только данные Git'а. Проще говоря, голый репозиторий содержит только каталог `.git` вашего проекта и ничего больше.
10
+
11
+ ## Протоколы ##
12
+
13
+ Git умеет работать с четырьмя сетевыми протоколами для передачи данных: локальный, Secure Shell (SSH), Git и HTTP. В этой части мы обсудим каждый из них и в каких случаях стоит (или не стоит) их использовать.
14
+
15
+ Важно понимать, что за исключением протокола HTTP, все эти протоколы требуют, чтобы Git был установлен и работал на сервере.
16
+
17
+ ### Локальный протокол ###
18
+
19
+ Базовым протоколом является _Локальный протокол_, при использовании которого удалённый репозиторий — другой каталог на диске. Наиболее часто он используется, если все члены команды имеют доступ к общей файловой системе, например к NFS, или, что менее вероятно, когда все работают на одном компьютере. Последний вариант не столь хорош, поскольку все копии вашего репозитория находятся на одном компьютере, делая возможность потерять всё более вероятной.
20
+
21
+ Если у вас смонтирована общая файловая система, вы можете клонировать, отправлять и получать изменения из локального репозитория. Чтобы склонировать такой репозиторий или добавить его в качестве удалённого в существующий проект, используйте путь к репозиторию в качестве URL. Например, для клонирования локального репозитория вы можете выполнить что-то вроде этого:
22
+
23
+ $ git clone /opt/git/project.git
24
+
25
+ Или этого:
26
+
27
+ $ git clone file:///opt/git/project.git
28
+
29
+ Git работает немного по-другому если вы укажете префикс `file://` для вашего URL. Когда вы просто указываете путь, Git пытается использовать жёсткие ссылки и копировать файлы, когда это нужно. Если вы указываете `file://`, Git работает с данными так же как при использовании сетевых протоколов, что в целом менее эффективный способ передачи данных. Причиной для использования `file://` может быть необходимость создания чистой копии репозитория без лишних внешних ссылок и объектов, обычно после импорта из другой СКВ или чего-то похожего (см. главу 9 о задачах поддержки). Мы будем использовать обычные пути, поскольку это практически всегда быстрее.
30
+
31
+ Чтобы добавить локальный репозиторий в существующий проект, вы можете воспользоваться командой:
32
+
33
+ $ git remote add local_proj /opt/git/project.git
34
+
35
+ Теперь вы можете отправлять и получать изменения из этого репозитория так, как вы это делали по сети.
36
+
37
+ #### Преимущества ####
38
+
39
+ Преимущества основанных на файлах хранилищ в том, что они просты и используют существующие разграничения прав на файлы и сетевой доступ. Если у вас уже есть общая файловая система, доступ к которой имеет вся команда, настройка репозитория очень проста. Вы помещаете голый репозиторий туда, куда все имеют доступ, и выставляете права на чтение и запись так же, как вы это делали бы для любого другого общего каталога. Мы обсудим, как экспортировать голую копию репозитория для этой цели в следующем разделе, "Настройка Git на сервере".
40
+
41
+ Также это хорошая возможность быстро получить наработки из чьего-то рабочего репозитория. Если вы и ваш коллега работаете над одним и тем же проектом и он хочет, чтобы вы проверили что-то, то запуск команды вроде `git pull /home/john/project` зачастую проще, чем если бы он отправил на удалённый сервер, а вы забрали бы оттуда.
42
+
43
+ #### Недостатки ####
44
+
45
+ Недостаток этого метода в том, что общий доступ обычно сложнее настроить и получить из разных мест, чем простой сетевой доступ. Если вы хотите отправлять со своего ноутбука, когда вы дома, вы должны смонтировать удалённый диск, что может быть сложно и медленно по сравнению с сетевым доступом.
46
+
47
+ Также важно упомянуть, что не всегда использование общей точки монтирования является быстрейшим вариантом. Локальный репозиторий быстрый, только если вы имеете быстрый доступ к данным. Репозиторий на NFS часто медленнее, чем репозиторий через SSH на том же сервере, позволяющий Git'у использовать на полную локальные диски на каждой системе.
48
+
49
+ ### Протокол SSH ###
50
+
51
+ Наверное, наиболее часто используемый транспортный протокол — это SSH. Причина этого в том, что доступ по SSH уже есть на многих серверах, а если его нет, то его очень легко настроить. Кроме того, SSH — единственный из сетевых протоколов, предоставляющий доступ и на чтение, и на запись. Два других сетевых протокола (HTTP и Git) в большинстве случаев дают доступ только на чтение, поэтому даже если они вам доступны, вам всё равно понадобится SSH для записи. К тому же SSH протокол с аутентификацией, и благодаря его распространённости обычно его легко настроить и использовать.
52
+
53
+ Чтобы склонировать Git-репозиторий по SSH, вы можете указать префикс ssh:// в URL, например:
54
+
55
+ $ git clone ssh://user@server/project.git
56
+
57
+ Альтернативно для протокола SSH можно использовать более короткую запись в scp-стиле:
58
+
59
+ $ git clone user@server:project.git
60
+
61
+ Также вы можете не указывать имя пользователя, Git будет использовать то, под которым вы вошли в систему.
62
+
63
+ #### Достоинства ####
64
+
65
+ SSH имеет множество достоинств. Во-первых, вы, по сути, вынуждены его использовать, когда нужен авторизованный доступ на запись к репозиторию через сеть. Во-вторых, SSH достаточно легко настроить — SSH-демоны распространены, многие системные администраторы имеют опыт работы с ними, и во многих дистрибутивах они уже настроены или есть утилиты для управления ими. Также доступ по SSH безопасен — данные передаются зашифрованными по авторизованным каналам. Наконец, так же как и Git-протокол и локальный протокол, SSH эффективен, делая данные перед передачей максимально компактными.
66
+
67
+ #### Недостатки ####
68
+
69
+ Недостаток SSH в том, что, используя его, вы не можете обеспечить анонимный доступ к репозиторию. Клиенты должны иметь доступ к машине по SSH, даже для работы в режиме только на чтение, что делает SSH неподходящим для проектов с открытым исходным кодом. Если вы используете Git только внутри корпоративной сети, то возможно SSH единственный протокол, с которым вам придётся иметь дело. Если же вам нужен анонимный доступ на чтение для ваших проектов, вам придётся настроить SSH для себя, чтобы выкладывать изменения, и что-нибудь другое для других, для скачивания.
70
+
71
+ ### Git-протокол ###
72
+
73
+ Следующий протокол — Git-протокол. Вместе с Git'ом поставляется специальный демон, который слушает порт 9418 и предоставляет сервис, схожий с протоколом ssh, но абсолютно без аутентификации. Чтобы использовать Git-протокол для репозитория, вы должны создать файл `git-daemon-export-ok`, иначе демон не будет работать с этим репозиторием, но следует помнить, что в протоколе отсутствуют средства безопасности. Соответственно, любой репозиторий в Git'е может быть либо доступен для клонирования всем, либо не доступен никому. Как следствие, обычно вы не можете отправлять изменения по этому протоколу. Вы можете открыть доступ на запись, но из-за отсутствия авторизации в этом случае кто угодно, зная URL вашего проекта, сможет его изменить. В общем, это редко используемая возможность.
74
+
75
+ #### Достоинства ####
76
+
77
+ Git-протокол — самый быстрый из доступных протоколов. Если у вас проект с публичным доступом и большой трафик или у вас очень большой проект, для которого не требуется авторизация пользователей для чтения, вам стоит настроить Git-демон для вашего проекта. Он использует тот же механизм передачи данных, что и протокол SSH, но без дополнительных затрат на кодирование и аутентификацию.
78
+
79
+ #### Недостатки ####
80
+
81
+ Недостатком Git-протокола является отсутствие аутентификации. Поэтому обычно не следует использовать этот протокол как единственный способ доступа к вашему проекту. Обычно он используется в паре с SSH для разработчиков, имеющих доступ на запись, тогда как все остальные используют `git://` с доступом только на чтение.
82
+ Кроме того, это, вероятно, самый сложный для настройки протокол. Вы должны запустить собственно демон, не являющийся стандартным. Мы рассмотрим его настройку в разделе "Gitosis" этой главы. К тому же, ему необходим сервис `xinetd` или ему подобный, что не всегда легко сделать. Также необходимо, чтобы сетевой экран позволял доступ на порт 9418, который не является стандартным портом, всегда разрешённым в корпоративных брандмауэрах. За сетевыми экранами крупных корпораций этот неизвестный порт обычно заблокирован.
83
+
84
+ ### Протокол HTTP/S ###
85
+
86
+ Последний доступный протокол — HTTP. Прелесть протоколов HTTP и HTTPS в простоте их настройки. По сути, всё, что необходимо сделать — поместить голый репозиторий внутрь каталога с HTTP документами, установить перехватчик `post-update` и всё (подробнее о перехватчиках будет рассказано в главе 7). Теперь каждый, имеющий доступ к веб-серверу, на котором был размещён репозиторий, может его склонировать. Таким образом, чтобы открыть доступ к своему репозиторию на чтение через HTTP, нужно сделать что-то наподобие этого:
87
+
88
+ $ cd /var/www/htdocs/
89
+ $ git clone --bare /path/to/git_project gitproject.git
90
+ $ cd gitproject.git
91
+ $ mv hooks/post-update.sample hooks/post-update
92
+ $ chmod a+x hooks/post-update
93
+
94
+ Вот и всё. Перехватчик `post-update`, входящий в состав Git'а по умолчанию, выполняет необходимую команду (`git update-server-info`), чтобы извлечение (fetch) и клонирование (clone) по HTTP работали правильно. Эта команда выполняется, когда вы отправляете изменения в репозиторий по SSH. Затем остальные могут склонировать его командой:
95
+
96
+ $ git clone http://example.com/gitproject.git
97
+
98
+ В рассмотренном примере мы использовали каталог `/var/www/htdocs`, обычно используемый сервером Apache, но вы можете использовать любой веб-сервер, отдающий статические данные, расположив голый репозиторий в нужном каталоге. Данные Git'а представляют собой обычные файлы (в главе 9 предоставление данных рассматривается более подробно).
99
+
100
+ Также возможна настройка Git'а для доступа на запись через HTTP, однако этот способ мало распространён и требует от вас настройки WebDAV. Поскольку этот способ редко используется, мы не будем рассматривать его в рамках этой книги. Если вас интересует использование протокола HTTP с возможностью записи, вы можете почитать о подготовке репозитория в этой статье: `http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt`. Положительным моментом настройки Git'а для записи через HTTP является то, что вы можете использовать любой WebDAV-сервер, без поддержки каких-либо специфичных для Git'а возможностей. Таким образом если ваш хостинг предоставляет WebDAV, вы можете обеспечить запись обновлений репозитория на ваш веб-сайт.
101
+
102
+ #### Достоинства ####
103
+
104
+ Положительным аспектом использования протокола HTTP является простота настройки. Запуск всего нескольких команд даёт вам возможность предоставить миру доступ к вашему Git-репозиторию. Вам понадобится всего несколько минут, чтобы сделать это. Кроме того, использование протокола HTTP не потребует много ресурсов вашего сервера. Поскольку в основном используется статический HTTP-сервер, обычный сервер Apache может обрабатывать в среднем тысячи файлов в секунду — трудно перегрузить даже небольшой сервер.
105
+
106
+ Также вы можете выставлять ваши репозитории в режиме только для чтения через HTTPS, т.е. вы можете шифровать трафик, или вы даже можете авторизовывать клиентов по SSL-сертификату. Обычно для этих целей легче использовать открытые SSH-ключи, но в некоторых конкретных случаях лучшим решением может оказаться использование подписанных SSL-сертификатов или других методов аутентификации, основанных на HTTP, для доступа на чтение через HTTPS.
107
+
108
+ Другим плюсом является то, что HTTP — настолько широко используемый протокол, что корпоративные сетевые экраны часто настроены на пропускание трафика, проходящего через этот порт.
109
+
110
+ #### Недостатки ####
111
+
112
+ Обратной стороной использования протокола HTTP является его относительно низкая эффективность для клиента. Обычно клонирование или извлечение изменений из репозитория при использовании HTTP гораздо продолжительнее, а объем данных и нагрузка на сеть намного больше, чем у любого другого имеющегося сетевого протокола. Поскольку он не заботится о том, чтобы передавались только необходимые вам данные — никакой динамической обработки на стороне сервера в этом случае не происходит — протокол HTTP часто называют _тупым_ (dumb) протоколом. Более подробно о разнице в эффективности протокола HTTP и других протоколов рассказывается в главе 9.
113
+
114
+ ## Настройка Git на сервере ##
115
+
116
+ Для того чтобы осуществить первоначальную настройку любого Git-сервера, необходимо экспортировать существующий репозиторий в новый "голый" репозиторий, т.е. репозиторий без рабочего каталога. Обычно это несложно сделать.
117
+ Чтобы склонировать ваш репозиторий и создать новый "голый" репозиторий, выполните команду clone с параметром `--bare`. По существующему соглашению, каталоги с голыми репозиториями заканчиваются на `.git`, например:
118
+
119
+ $ git clone --bare my_project my_project.git
120
+ Initialized empty Git repository in /opt/projects/my_project.git/
121
+
122
+ Вывод этой команды слегка обескураживает. Поскольку `clone` это по сути `git init`, а затем `git fetch`, мы видим вывод от `git init`, который создаёт пустой каталог. Реальное перемещение объектов не даёт вывода, однако оно действительно происходит. Теперь у вас должна появиться копия данных из каталога Git'а в каталоге `my_project.git`.
123
+
124
+ Это примерно то же самое, что и это:
125
+
126
+ $ cp -Rf my_project/.git my_project.git
127
+
128
+ Тут есть пара небольших различий в файле конфигурации, но в вашем случае эту разницу можно считать несущественной. Можно считать, что в этом случае берётся собственно Git-репозиторий без рабочего каталога и создаётся каталог только для него.
129
+
130
+ ### Размещение "голого" репозитория на сервере ###
131
+
132
+ Теперь, когда у вас есть голая копия репозитория, всё, что вам нужно сделать, это поместить её на сервер и настроить протоколы. Условимся, что вы уже настроили сервер `git.example.com`, имеете к нему доступ по SSH и хотите размещать все свои Git-репозитории в каталоге `/opt/git`. Вы можете сделать новый репозиторий простым копированием голого репозитория:
133
+
134
+ $ scp -r my_project.git user@git.example.com:/opt/git
135
+
136
+ Теперь другие пользователи, имеющие доступ к серверу по SSH и право на чтение к каталогу `/opt/git`, могут склонировать ваш репозиторий, выполнив:
137
+
138
+ $ git clone user@git.example.com:/opt/git/my_project.git
139
+
140
+ Если у пользователя сервера есть право на запись в каталог `/opt/git/my_project.git`, он автоматически получает возможность отправки изменений в репозиторий. Git автоматически добавит право на запись в репозиторий для группы, если вы запустите команду `git init` с параметром `--shared`.
141
+
142
+ $ ssh user@git.example.com
143
+ $ cd /opt/git/my_project.git
144
+ $ git init --bare --shared
145
+
146
+ Видите, это просто — взять Git-репозиторий, создать его "голую" версию и поместить её на сервер, к которому у вас и ваших коллег есть доступ по SSH. Теперь вы готовы работать вместе над одним проектом.
147
+
148
+ Важно отметить, что это практически всё, что вам нужно сделать, чтобы получить рабочий Git-сервер, к которому несколько человек имеют доступ — просто добавьте учётные записи SSH на сервер, и положите голый репозиторий в место, к которому эти пользователи имеют доступ на чтение и запись. И всё.
149
+
150
+ Из нескольких последующих разделов вы узнаете, как получить более сложные конфигурации. В том числе как не создавать учётные записи для каждого пользователя, как сделать публичный доступ на чтение репозитория, как установить веб-интерфейс, как использовать Gitosis, и др. Однако, помните, что для совместной работы пары человек на закрытом проекте, всё, что вам _нужно_ — это SSH-сервер и "голый" репозиторий.
151
+
152
+ ### Малые установки ###
153
+
154
+ Если вы небольшая фирма или вы только пробуете Git в вашей организации и у вас мало разработчиков, то всё достаточно просто. Один из наиболее сложных аспектов настройки Git-сервера — управление пользователями. Если вы хотите, чтобы некоторые репозитории были доступны некоторым пользователям только на чтение, а другие и на чтение, и на запись, вам может быть не очень просто привести права доступа в порядок.
155
+
156
+ #### Доступ по SSH ####
157
+
158
+ Если у вас уже есть сервер, к которому все ваши разработчики имеют доступ по SSH, проще всего разместить ваш первый репозиторий там, поскольку вам не нужно практически ничего делать (как мы уже обсудили в предыдущем разделе). Если вы хотите более сложного управления правами доступа к вашим репозиториям, вы можете сделать это обычными правами файловой системы, предоставляемыми операционной системой вашего сервера.
159
+
160
+ Если вы хотите разместить ваши репозитории на сервер, на котором нет учётных записей для каждого в вашей команде, кому нужен доступ на запись, вы должны настроить доступ по SSH для них. Будем считать, что если у вас есть сервер, на котором вы хотите это сделать, то SSH-сервер на нём уже установлен, и через него вы имеете доступ к серверу.
161
+
162
+ Есть несколько способов дать доступ каждому в вашей команде. Первый — настроить учётные записи для каждого. Это просто, но может быть весьма обременительно. Вероятно, вы не захотите для каждого пользователя выполнять `adduser` и задавать временные пароли.
163
+
164
+ Второй способ — создать на машине одного пользователя 'git', попросить каждого пользователя, кому нужен доступ на запись, прислать вам открытый SSH-ключ, и добавить эти ключи в файл `~/.ssh/authorized_keys` вашего нового пользователя 'git'. Теперь все будут иметь доступ к этой машине через пользователя 'git'. Это никак не повлияет на данные коммита — пользователь, под которым вы соединяетесь с сервером по SSH, не затрагивает сделанные вами коммиты.
165
+
166
+ Другой способ сделать это — использовать SSH-сервер, аутентифицирующий по LDAP-серверу или любому другому централизованному источнику, который у вас может быть уже настроен. Любой способ аутентификации по SSH, какой вы только сможете придумать, должен работать, если пользователь может получить доступ к консоли.
167
+
168
+ ## Создание открытого SSH-ключа ##
169
+
170
+ Как было уже сказано, многие Git-серверы используют аутентификацию по открытым SSH-ключам. Для того чтобы предоставить открытый ключ, пользователь должен его сгенерировать, если только это не было сделано ранее. Этот процесс похож во всех операционных системах.
171
+ Сначала вам стоит убедиться, что у вас ещё нет ключа. По умолчанию пользовательские SSH-ключи хранятся в каталоге `~/.ssh` этого пользователя. Вы можете легко проверить, есть ли у вас ключ, зайдя в этот каталог и посмотрев его содержимое:
172
+
173
+ $ cd ~/.ssh
174
+ $ ls
175
+ authorized_keys2 id_dsa known_hosts
176
+ config id_dsa.pub
177
+
178
+ Ищите пару файлов с именами "что-нибудь" и "что-нибудь.pub", где "что-нибудь" — обычно `id_dsa` или `id_rsa`. Файл с расширением `.pub` — это ваш открытый ключ, а второй файл — ваш секретный ключ. Если у вас нет этих файлов (или даже нет каталога `.ssh`), вы можете создать их, запустив программу `ssh-keygen`, которая входит в состав пакета SSH в системах Linux/Mac, а также поставляется в составе MSysGit для Windows:
179
+
180
+ $ ssh-keygen
181
+ Generating public/private rsa key pair.
182
+ Enter file in which to save the key (/Users/schacon/.ssh/id_rsa):
183
+ Enter passphrase (empty for no passphrase):
184
+ Enter same passphrase again:
185
+ Your identification has been saved in /Users/schacon/.ssh/id_rsa.
186
+ Your public key has been saved in /Users/schacon/.ssh/id_rsa.pub.
187
+ The key fingerprint is:
188
+ 43:c5:5b:5f:b1:f1:50:43:ad:20:a6:92:6a:1f:9a:3a schacon@agadorlaptop.local
189
+
190
+ Сначала необходимо указать расположение файла для сохранения ключа (`.ssh/id_rsa`), затем дважды ввести пароль, который вы можете оставить пустым, если не хотите его вводить каждый раз, когда используете ключ.
191
+
192
+ Теперь каждый пользователь должен послать свой открытый ключ вам или тому, кто администрирует Git-сервер (предположим, что ваш SSH-сервер уже настроен на работу с открытыми ключами). Для этого им нужно скопировать всё содержимое файла с расширением `.pub` и отправить его по электронной почте. Открытый ключ выглядит следующим образом:
193
+
194
+ $ cat ~/.ssh/id_rsa.pub
195
+ ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU
196
+ GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3
197
+ Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA
198
+ t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En
199
+ mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx
200
+ NrRFi9wrf+M7Q== schacon@agadorlaptop.local
201
+
202
+ Более подробное руководство по созданию SSH-ключей на различных системах вы можете найти в руководстве GitHub по SSH-ключам на `http://github.com/guides/providing-your-ssh-key`.
203
+
204
+ ## Настраиваем сервер ##
205
+
206
+ Давайте рассмотрим настройку доступа по SSH на стороне сервера. В этом примере мы будем использовать метод `authorized_keys` для аутентификации пользователей. Мы подразумеваем, что вы используете стандартный дистрибутив Linux типа Ubuntu. Для начала создадим пользователя 'git' и каталог `.ssh` для этого пользователя:
207
+
208
+ $ sudo adduser git
209
+ $ su git
210
+ $ cd
211
+ $ mkdir .ssh
212
+
213
+ Затем нужно добавить открытый SSH-ключ какого-нибудь разработчика в файл `authorized_keys` этого пользователя. Предположим, вы уже получили несколько ключей по электронной почте и сохранили их во временные файлы. Напомню, открытые ключи выглядят вот так:
214
+
215
+ $ cat /tmp/id_rsa.john.pub
216
+ ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCB007n/ww+ouN4gSLKssMxXnBOvf9LGt4L
217
+ ojG6rs6hPB09j9R/T17/x4lhJA0F3FR1rP6kYBRsWj2aThGw6HXLm9/5zytK6Ztg3RPKK+4k
218
+ Yjh6541NYsnEAZuXz0jTTyAUfrtU3Z5E003C4oxOj6H0rfIF1kKI9MAQLMdpGW1GYEIgS9Ez
219
+ Sdfd8AcCIicTDWbqLAcU4UpkaX8KyGlLwsNuuGztobF8m72ALC/nLF6JLtPofwFBlgc+myiv
220
+ O7TCUSBdLQlgMVOFq1I2uPWQOkOWQAHukEOmfjy2jctxSDBQ220ymjaNsHT4kgtZg2AYYgPq
221
+ dAv8JggJICUvax2T9va5 gsg-keypair
222
+
223
+ Вы просто добавляете их в свой файл `authorized_keys`:
224
+
225
+ $ cat /tmp/id_rsa.john.pub >> ~/.ssh/authorized_keys
226
+ $ cat /tmp/id_rsa.josie.pub >> ~/.ssh/authorized_keys
227
+ $ cat /tmp/id_rsa.jessica.pub >> ~/.ssh/authorized_keys
228
+
229
+ Теперь вы можете создать пустой репозиторий для них, запустив `git init` с параметром `--bare`, что инициализирует репозиторий без рабочего каталога:
230
+
231
+ $ cd /opt/git
232
+ $ mkdir project.git
233
+ $ cd project.git
234
+ $ git --bare init
235
+
236
+ Затем Джон, Джози или Джессика могут отправить первую версию своего проекта в этот репозиторий, добавив его как удалённый и отправив ветку. Заметьте, что кто-то должен заходить на сервер и создавать голый репозиторий каждый раз, когда вы хотите добавить проект. Пусть `gitserver` — имя хоста сервера, на котором вы создали пользователя 'git' и репозиторий. Если он находится в вашей внутренней сети, вы можете настроить DNS-запись для `gitserver`, ссылающуюся на этот сервер, и использовать эти команды:
237
+
238
+ # на компьютере Джона
239
+ $ cd myproject
240
+ $ git init
241
+ $ git add .
242
+ $ git commit -m 'initial commit'
243
+ $ git remote add origin git@gitserver:/opt/git/project.git
244
+ $ git push origin master
245
+
246
+ Теперь остальные могут склонировать его и отправлять (push) туда изменения так же легко:
247
+
248
+ $ git clone git@gitserver:/opt/git/project.git
249
+ $ cd project
250
+ $ vim README
251
+ $ git commit -am 'fix for the README file'
252
+ $ git push origin master
253
+
254
+ Этим способом вы можете быстро получить Git-сервер с доступом на чтение/запись для небольшой группы разработчиков.
255
+
256
+ В качестве дополнительной меры предосторожности вы можете ограничить возможности пользователя 'git' только действиями, связанными с Git'ом, с помощью ограниченной оболочки `git-shell`, поставляемой вместе с Git'ом. Если вы выставите её в качестве командного интерпретатора пользователя 'git', то этот пользователь не сможет получить доступ к обычной командной оболочке на вашем сервере. Чтобы её использовать, укажите `git-shell` вместо bash или csh в качестве командной оболочки пользователя. Для этого вы должны отредактировать файл `/etc/passwd`:
257
+
258
+ $ sudo vim /etc/passwd
259
+
260
+ В конце вы должны найти строку, похожую на эту:
261
+
262
+ git:x:1000:1000::/home/git:/bin/sh
263
+
264
+ Замените `/bin/sh` на `/usr/bin/git-shell` (или запустите `which git-shell`, чтобы проверить, куда он установлен). Отредактированная строка должна выглядеть следующим образом:
265
+
266
+ git:x:1000:1000::/home/git:/usr/bin/git-shell
267
+
268
+ Теперь пользователь 'git' может использовать SSH-соединение только для работы с Git-репозиториями и не может зайти на машину. Вы можете попробовать и увидите, что вход в систему отклонён:
269
+
270
+ $ ssh git@gitserver
271
+ fatal: What do you think I am? A shell?
272
+ Connection to gitserver closed.
273
+
274
+ ## Открытый доступ ##
275
+
276
+ Что, если вы хотите иметь анонимный доступ к вашему проекту на чтение? Возможно, вместо размещения внутреннего закрытого проекта, вы хотите разместить проект с открытым исходным кодом. Или, может быть, у вас есть автоматизированные серверы сборки или серверы непрерывной интеграции, которые часто изменяются, и вы не хотите постоянно перегенерировать SSH-ключи, а вы просто хотите добавить анонимный доступ на чтение.
277
+
278
+ Вероятно, наиболее простой способ для небольших конфигураций — запустить статический веб-сервер, указав в качестве корневого каталога для документов каталог, в котором расположены ваши Git-репозитории, и задействовав перехватчик `post-update`, как было показано в первой части этой главы. Давайте продолжим работу с предыдущего примера. Допустим, ваши репозитории расположены в каталоге `/opt/git`, и сервер Apache запущен на вашей машине. Повторюсь, вы можете использовать любой веб-сервер, но в качестве примера мы покажем несколько основных конфигураций Apache, которые покажут основную идею.
279
+
280
+ Для начала вам следует включить перехватчик:
281
+
282
+ $ cd project.git
283
+ $ mv hooks/post-update.sample hooks/post-update
284
+ $ chmod a+x hooks/post-update
285
+
286
+ Что делает перехватчик `post-update`? Обычно он выглядит так:
287
+
288
+ $ cat .git/hooks/post-update
289
+ #!/bin/sh
290
+ exec git-update-server-info
291
+
292
+ Это означает, что когда вы отправляете что-то с помощью `git push` на сервер по SSH, Git будет запускать эту команду, чтобы обновить файлы необходимые для скачивания по HTTP.
293
+
294
+ Затем вы должны добавить запись VirtualHost в конфигурацию вашего Apache с корневым каталогом документов в каталоге с вашими Git-проектами. Здесь мы подразумеваем, что ваш DNS-сервер настроен на отсылку `*.gitserver` на ту машину, на которой всё это запущено:
295
+
296
+ <VirtualHost *:80>
297
+ ServerName git.gitserver
298
+ DocumentRoot /opt/git
299
+ <Directory /opt/git/>
300
+ Order allow, deny
301
+ allow from all
302
+ </Directory>
303
+ </VirtualHost>
304
+
305
+ Вам также понадобится установить Unix-группу для каталога `/opt/git` в `www-data`, чтобы ваш веб-сервер получил доступ на чтение этих каталогов, поскольку (по умолчанию) Apache запускает CGI-сценарии от имени такого пользователя:
306
+
307
+ $ chgrp -R www-data /opt/git
308
+
309
+ После перезапуска Apache вы должны получить возможность склонировать ваши репозитории из этого каталога указывая их в URL:
310
+
311
+ $ git clone http://git.gitserver/project.git
312
+
313
+ Таким образом, вы можете настроить доступ на чтение по HTTP к любому из ваших проектов для значительного количества пользователей за несколько минут. Другой простой способ дать открытый неаутентифицируемый доступ — использовать Git-демон, однако это требует запуска процесса демона. Мы рассмотрим этот вариант в следующем разделе, если вы предпочитаете этот вариант.
314
+
315
+ ## GitWeb ##
316
+
317
+ Теперь, когда у вас есть основной доступ на чтение и запись и доступ только на чтение к вашему проекту, вероятно, вы захотите настроить простой веб-визуализатор. Git поставляется в комплекте с CGI-сценарием, называющимся GitWeb, который обычно используется для этого. Вы можете увидеть GitWeb в действии на таких сайтах как `http://git.kernel.org` (рис. 4-1).
318
+
319
+ Insert 18333fig0401.png
320
+ Рисунок 4-1. Веб-интерфейс GitWeb.
321
+
322
+ Если вы хотите проверить, как GitWeb будет выглядеть для вашего проекта, Git поставляется с командой для быстрой установки временного экземпляра, если в вашей системе есть легковесный веб-сервер, такой как `lighttpd` или `webrick`. На машинах с Linux'ом `lighttpd` часто установлен, поэтому возможно вы сможете его запустить, выполнив `git instaweb` в каталоге с вашим проектом. Если вы используете Mac, Leopard поставляется с предустановленным Ruby, поэтому `webrick` может быть лучшим выбором. Чтобы запустить `instaweb` не с `lighttpd`, вы можете запустить команду с параметром `--httpd`.
323
+
324
+ $ git instaweb --httpd=webrick
325
+ [2009-02-21 10:02:21] INFO WEBrick 1.3.1
326
+ [2009-02-21 10:02:21] INFO ruby 1.8.6 (2008-03-03) [universal-darwin9.0]
327
+
328
+ Это запустит сервер HTTPD на порте 1234 и затем запустит веб-браузер, открытый на этой странице. Это очень просто. Когда вы закончили и хотите остановить сервер, вы можете запустить ту же команду с параметром `--stop`:
329
+
330
+ $ git instaweb --httpd=webrick --stop
331
+
332
+ Если вы хотите иметь постоянно работающий веб-интерфейс на сервере для своей команды или для своего проекта с открытым кодом, вам необходимо установить CGI-сценарий на своём веб-сервере. В некоторых дистрибутивах Linux есть пакет `gitweb`, который можно установить, используя `apt` или `yum`, так что вы можете попробовать сначала этот способ. Мы рассмотрим установку GitWeb вручную очень быстро. Для начала вам нужно получить исходный код Git'а, с которым поставляется GitWeb, и сгенерировать CGI-сценарий под свою систему:
333
+
334
+ $ git clone git://git.kernel.org/pub/scm/git/git.git
335
+ $ cd git/
336
+ $ make GITWEB_PROJECTROOT="/opt/git" \
337
+ prefix=/usr gitweb
338
+ $ sudo cp -Rf gitweb /var/www/
339
+
340
+ Помните, что вы должны указать команде, где расположены ваши Git-репозитории с помощью переменной `GITWEB_PROJECTROOT`. Теперь нужно настроить Apache на использование этого сценария, для чего вы можете добавить виртуальный хост:
341
+
342
+ <VirtualHost *:80>
343
+ ServerName gitserver
344
+ DocumentRoot /var/www/gitweb
345
+ <Directory /var/www/gitweb>
346
+ Options ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch
347
+ AllowOverride All
348
+ order allow,deny
349
+ Allow from all
350
+ AddHandler cgi-script cgi
351
+ DirectoryIndex gitweb.cgi
352
+ </Directory>
353
+ </VirtualHost>
354
+
355
+ Повторюсь, GitWeb может быть установлен на любой веб-сервер, совместимый с CGI. Если вы предпочитаете использовать что-то другое, настройка не должна стать для вас проблемой. К этому моменту вы должны иметь возможность зайти на `http://gitserver/` для просмотра ваших репозиториев онлайн, а также использовать `http://git.gitserver` для клонирования и извлечения данных для ваших репозиториев по HTTP.
356
+
357
+ ## Gitosis ##
358
+
359
+ Хранение открытых ключей всех пользователей в `authorized_keys` для предоставления доступа работает хорошо лишь на время. Когда у вас сотни пользователей, это скорее похоже на пытку. Вы должны заходить на сервер каждый раз, и нет никакого разграничения доступа — все перечисленные в файле имеют доступ на чтение и на запись к каждому проекту.
360
+
361
+ На этой стадии вы можете захотеть обратиться к широко используемому ПО под названием Gitosis. Gitosis — это просто набор сценариев (scripts), который поможет вам управляться с файлом `authorized_keys` и реализовать простой контроль доступа. Действительно интересно, что добавление людей и настройка доступа для них осуществляется не через веб-интерфейс, а с помощью специального git-репозитория. Вы настраиваете информацию в этом проекте и, когда вы отправляете её в репозиторий, Gitosis, исходя из неё, перенастраивает сервер, что круто.
362
+
363
+ Установка Gitosis'а — не самая простая задача, хотя и не слишком сложная. Проще всего использовать под него Linux-сервер — в наших примерах используется сервер Ubuntu 8.10 в начальной конфигурации.
364
+
365
+ Gitosis'у нужны некоторые инструменты для Python'а, так что первым делом вы должны установить для Python'а пакет setuptools, который в Ubuntu называется python-setuptools:
366
+
367
+ $ apt-get install python-setuptools
368
+
369
+ Затем вы клонируете и устанавливаете Gitosis с главного сайта проекта:
370
+
371
+ $ git clone https://github.com/tv42/gitosis.git
372
+ $ cd gitosis
373
+ $ sudo python setup.py install
374
+
375
+ Это установит несколько исполняемых файлов, которые Gitosis будет использовать. Затем Gitosis хочет расположить свои репозитории в каталоге `/home/git`, что неплохо. Но вы уже установили репозитории в `/opt/git`, так что вместо перенастройки всего на свете вы сделаете символическую ссылку:
376
+
377
+ $ ln -s /opt/git /home/git/repositories
378
+
379
+ Gitosis будет управлять ключами за вас, так что вы должны удалить текущий файл, добавить ключи снова позже и предоставить Gitosis'у управлять файлом `authorized_keys` автоматически. Сейчас просто уберите этот файл с дороги:
380
+
381
+ $ mv /home/git/.ssh/authorized_keys /home/git/.ssh/ak.bak
382
+
383
+ Затем вы должны вернуть пользователю git его командную оболочку, если вы меняли её на команду `git-shell`. Люди всё так же не смогут выполнить вход, но для вас это будет контролировать Gitosis. Итак, давайте поменяем эту строку в файле '/etc/passwd'
384
+
385
+ git:x:1000:1000::/home/git:/usr/bin/git-shell
386
+
387
+ обратно на эту:
388
+
389
+ git:x:1000:1000::/home/git:/bin/sh
390
+
391
+ Теперь самое время инициализировать Gitosis. Сделаете это, выполнив команду `gitosis-init` со своим персональным открытым ключом. Если вашего открытого ключа ещё нет на сервере, вам нужно будет скопировать его туда:
392
+
393
+ $ sudo -H -u git gitosis-init < /tmp/id_dsa.pub
394
+ Initialized empty Git repository in /opt/git/gitosis-admin.git/
395
+ Reinitialized existing Git repository in /opt/git/gitosis-admin.git/
396
+
397
+ Это позволит пользователю с таким ключом изменять главный Git-репозиторий, который управляет настройками Gitosis'а. Затем вы должны вручную установить бит исполнения на сценарий `post-update` в новом управляющем репозитории.
398
+
399
+ $ sudo chmod 755 /opt/git/gitosis-admin.git/hooks/post-update
400
+
401
+ Всё готово. Если вы всё настроили правильно, вы можете попытаться соединиться по SSH с вашим сервером под тем пользователем, для которого вы добавили открытый ключ, чтобы инициализировать Gitosis. Вы должны увидеть что-то вроде этого:
402
+
403
+ $ ssh git@gitserver
404
+ PTY allocation request failed on channel 0
405
+ fatal: unrecognized command 'gitosis-serve schacon@quaternion'
406
+ Connection to gitserver closed.
407
+
408
+ Это означает, что Gitosis узнал вас, но не пустил, потому что вы не пытались выполнить ни одну из команд Git'а. Ну так давайте выполним настоящую команду Git'а — вы склонируете управляющий репозиторий Gitosis:
409
+
410
+ # на вашем локальном компьютере
411
+ $ git clone git@gitserver:gitosis-admin.git
412
+
413
+ Теперь у вас есть каталог с именем `gitosis-admin`, в котором есть две главные части:
414
+
415
+ $ cd gitosis-admin
416
+ $ find .
417
+ ./gitosis.conf
418
+ ./keydir
419
+ ./keydir/scott.pub
420
+
421
+ Файл `gitosis.conf` — файл настройки, который используется, чтобы указать пользователей, репозитории и права доступа. В каталоге `keydir` должны храниться открытые ключи всех пользователей, у которых есть какой-либо доступ к вашим репозиториям — по файлу на пользователя. Имя файла в `keydir` (в предыдущем примере `scott.pub`) у вас будет отличаться — Gitosis берёт это имя из описания в конце открытого ключа, который был импортирован сценарием `gitosis-init`.
422
+
423
+ Если вы посмотрите в файл `gitosis.conf`, там должна быть указана только информация о проекте `gitosis-admin`, который вы только что склонировали:
424
+
425
+ $ cat gitosis.conf
426
+ [gitosis]
427
+
428
+ [group gitosis-admin]
429
+ writable = gitosis-admin
430
+ members = scott
431
+
432
+ Это показывает, что пользователь 'scott' — пользователь, чьим открытым ключом вы инициализировали Gitosis — единственный, кто имеет доступ к проекту `gitosis-admin`.
433
+
434
+ А теперь давайте добавим новый проект. Добавьте новую секцию с названием `mobile` и перечислите в ней всех разработчиков из команды, занимающейся мобильными устройствами, а также проекты, к которым этим разработчикам нужно иметь доступ. Поскольку `scott` — пока что единственный пользователь в системе, добавьте его как единственного члена и создайте новый проект под названием `iphone_project`, чтобы ему было с чем начать работать:
435
+
436
+ [group mobile]
437
+ writable = iphone_project
438
+ members = scott
439
+
440
+ Когда вы вносите изменения в проект `gitosis-admin`, вы должны зафиксировать изменения и отправить их на сервер, чтобы они возымели эффект:
441
+
442
+ $ git commit -am 'add iphone_project and mobile group'
443
+ [master]: created 8962da8: "changed name"
444
+ 1 files changed, 4 insertions(+), 0 deletions(-)
445
+ $ git push
446
+ Counting objects: 5, done.
447
+ Compressing objects: 100% (2/2), done.
448
+ Writing objects: 100% (3/3), 272 bytes, done.
449
+ Total 3 (delta 1), reused 0 (delta 0)
450
+ To git@gitserver:/opt/git/gitosis-admin.git
451
+ fb27aec..8962da8 master -> master
452
+
453
+ Вы можете сделать свой первый push в новый проект `iphone_project`, добавив свой сервер в качестве удалённого (remote) в локальную версию проекта и выполнив `git push`. Вам больше не нужно вручную создавать голые репозитории на сервере для новых проектов — Gitosis создаёт их сам автоматически, когда видит первый push:
454
+
455
+ $ git remote add origin git@gitserver:iphone_project.git
456
+ $ git push origin master
457
+ Initialized empty Git repository in /opt/git/iphone_project.git/
458
+ Counting objects: 3, done.
459
+ Writing objects: 100% (3/3), 230 bytes, done.
460
+ Total 3 (delta 0), reused 0 (delta 0)
461
+ To git@gitserver:iphone_project.git
462
+ * [new branch] master -> master
463
+
464
+ Заметьте, что вам не нужно указывать путь (фактически, если вы это сделаете, то оно не сработает), только двоеточие и имя проекта — Gitosis найдёт его за вас.
465
+
466
+ Вы хотите работать над проектом с вашими друзьями, так что вам нужно снова добавить их открытые ключи. Но вместо того, чтобы вручную добавлять их к файлу `~/.ssh/authorized_keys` на вашем сервере, добавьте их, один файл на ключ, в каталог `keydir`. То, как вы назовёте ключи, определит, как вы будете ссылаться на пользователей в `gitosis.conf`. Давайте по-новому добавим открытые ключи для Джона, Джози и Джессики:
467
+
468
+ $ cp /tmp/id_rsa.john.pub keydir/john.pub
469
+ $ cp /tmp/id_rsa.josie.pub keydir/josie.pub
470
+ $ cp /tmp/id_rsa.jessica.pub keydir/jessica.pub
471
+
472
+ Теперь вы можете добавить их всех в вашу 'мобильную' команду, чтобы они имели доступ на чтение и запись в `iphone_project`:
473
+
474
+ [group mobile]
475
+ writable = iphone_project
476
+ members = scott john josie jessica
477
+
478
+ После того, как вы зафиксируете и отправите изменения, все четыре пользователя будут иметь возможность читать и писать в проект.
479
+
480
+ В Gitosis'е также есть простой контроль доступа. Если вы хотите, чтобы Джон имел только доступ на чтение к этому проекту, вы можете вместо этого сделать:
481
+
482
+ [group mobile]
483
+ writable = iphone_project
484
+ members = scott josie jessica
485
+
486
+ [group mobile_ro]
487
+ readonly = iphone_project
488
+ members = john
489
+
490
+ Теперь Джон может клонировать проект и получать обновления, но Gitosis не позволит ему отправлять изменения обратно в проект. Вы можете создать таких групп сколько хотите, каждую содержащую разные проекты и пользователей. Вы также можете указать другую группу в качестве одного из пользователей (используя `@` как префикс), чтобы автоматически добавить всех её членов:
491
+
492
+ [group mobile_committers]
493
+ members = scott josie jessica
494
+
495
+ [group mobile]
496
+ writable = iphone_project
497
+ members = @mobile_committers
498
+
499
+ [group mobile_2]
500
+ writable = another_iphone_project
501
+ members = @mobile_committers john
502
+
503
+ Если у вас возникли какие-то проблемы, полезным может быть добавить `loglevel=DEBUG` в секции `[gitosis]`. Если вы потеряли доступ к отправке, отправив неверную конфигурацию, вы можете вручную поправить файл `/home/git/.gitosis.conf` на сервере — файл, из которого Gitosis читает свою информацию. Отправка в проект берёт файл `gitosis.conf`, который вы только что отправили, и помещает его туда. Если вы отредактируете этот файл вручную, он останется таким до следующей успешной отправки в проект `gitosis-admin`.
504
+
505
+ ## Gitolite ##
506
+
507
+ В этом разделе мы вкратце рассмотрим Gitolite, научимся его устанавливать и настраивать. Gitolite представляет собой дополнительную прослойку поверх Git'а, обеспечивающую широкие возможности по управлению правами доступа. Gitolite для авторизации использует `sshd` или `httpd`.
508
+
509
+ Gitolite даёт возможность назначать права доступа не только для всего репозитория, но и для отдельных веток или имён меток внутри любого репозитория. То есть вы можете указать, что определённые люди (или группы людей) могут отправлять (push) определённые "ссылки" (ветки или метки), а остальные нет.
510
+
511
+ ### Установка ###
512
+
513
+ Установить Gitolite очень просто, даже не читая идущую с ним обширную документацию. Вам понадобится аккаунт на сервере с каким-нибудь Unix'ом. Вам не нужен root-доступ, если Git, Perl и OpenSSH-совместимый SSH-сервер уже установлены. Далее в примерах мы будем использовать аккаунт `git` на хосте с именем `gitserver`.
514
+
515
+ Gitolite несколько необычен, по крайней мере, в сравнении с другим "серверным" ПО — доступ осуществляется по SSH, и, следовательно, каждый пользователь на сервере является потенциальным "gitolite-хостом". В этом разделе мы рассмотрим самый простой метод установки; про остальные методы можно прочитать в документации.
516
+
517
+ Для начала, создайте пользователя с именем `git` на своём сервере и войдите в систему под этим пользователем. Скопируйте свой открытый ключ (это файл `~/.ssh/id_rsa.pub`, если вы сгенерировали его с помощью просто `ssh-keygen` без изменения параметров) со своего рабочего компьютера и переименуйте его в `<вашеимя>.pub` (в нашем примере это будет файл `scott.pub`). Затем выполните следующие команды:
518
+
519
+ $ git clone git://github.com/sitaramc/gitolite
520
+ $ gitolite/install -ln
521
+ # предполагает, что $HOME/bin существует и находится в $PATH
522
+ $ gitolite setup -pk $HOME/scott.pub
523
+
524
+ Последняя из команд создаст на сервере новый Git-репозиторий с именем `gitolite-admin`.
525
+
526
+ В завершение, вернитесь на свой рабочий компьютер и выполните там `git clone git@gitserver:gitolite-admin`. И всё! Gitolite теперь установлен на сервере, а на вашей рабочей станции теперь есть новый репозиторий, который называется `gitolite-admin`. Администрировать свой установленный Gitolite нужно, внося изменения в этот репозиторий и отправляя их на сервер.
527
+
528
+ ### Изменение параметров установки ###
529
+
530
+ Хотя быстрая установка с параметрами по умолчанию подходит для большинства людей, есть несколько способов изменения параметров установки, если вам это нужно. Если опустить опцию `-q`, вы получите "подробную" установку с детальной информацией о том, что происходит на каждом шаге. Подробный режим также позволяет изменить некоторые параметры на стороне сервера такие, как расположение репозиториев, с помощью редактирования "rc" файла, используемого сервером. Этот "rc" файл содержит развёрнутые комментарии так, чтобы вы легко смогли сделать любые изменения, сохранить их и продолжить. Этот файл также содержит различные настройки, которые вы можете изменить, чтобы активировать или выключить некоторые "продвинутые" функции Gitolite'а.
531
+
532
+ ### Конфигурационный файл и правила контроля доступа ###
533
+
534
+ Теперь, когда установка завершена, перейдите в клон репозитория `gitolite-admin` на вашем рабочем компьютере и осмотритесь, чтобы выяснить, что же вы получили:
535
+
536
+ $ cd ~/gitolite-admin/
537
+ $ ls
538
+ conf/ keydir/
539
+ $ find conf keydir -type f
540
+ conf/gitolite.conf
541
+ keydir/scott.pub
542
+ $ cat conf/gitolite.conf
543
+
544
+ repo gitolite-admin
545
+ RW+ = scott
546
+
547
+ repo testing
548
+ RW+ = @all
549
+
550
+ Заметьте, что "scott" (имя файла открытого ключа, использовавшееся ранее при запуске команды `gitolite setup`) имеет права на чтение и запись в репозиторий `gitolite-admin`, а также файл с открытым ключом с таким же именем.
551
+
552
+ Добавить нового пользователя просто. Чтобы добавить пользователя "alice", возьмите её ключ, переименуйте его в `alice.pub` и положите в каталог `keydir` клона репозитория `gitolite-admin` на вашем компьютере. Выполните `add`, `commit`, отправьте изменения, и пользователь добавлен.
553
+
554
+ Синтаксис конфигурационного файла для Gitolite'а подробно продокументирован, так что мы рассмотрим здесь только основные моменты.
555
+
556
+ Вы можете сгруппировать пользователей или репозитории для удобства. Имена групп совсем как макросы; когда вы их определяете, даже неважно, определяют ли они проекты или пользователей; это различие делается, только когда вы *используете* "макрос".
557
+
558
+ @oss_repos = linux perl rakudo git gitolite
559
+ @secret_repos = fenestra pear
560
+
561
+ @admins = scott
562
+ @interns = ashok
563
+ @engineers = sitaram dilbert wally alice
564
+ @staff = @admins @engineers @interns
565
+
566
+ Вы можете контролировать права доступа на уровне "ссылок" (то, что находится в .git/refs/). В следующем примере стажёры (группа @interns) могут отправлять (push) только ветку "int". Инженеры (группа @engineers) могут отправлять любую ветку, чьё имя начинается с "eng-", а также метки, начинающиеся с "rc" и затем содержащие цифры. Администраторы (группа @admins) могут делать всё с любыми ссылками (в том числе откатывать назад).
567
+
568
+ repo @oss_repos
569
+ RW int$ = @interns
570
+ RW eng- = @engineers
571
+ RW refs/tags/rc[0-9] = @engineers
572
+ RW+ = @admins
573
+
574
+ Выражение после `RW` или `RW+` — это регулярное выражение (regex), с которым сопоставляется имя отправляемой ссылки (ref). Поэтому мы называем его "refex"! Конечно, "refex" может быть гораздо более сложным, чем показано здесь, так что не переусердствуйте с ними, если вы не очень хорошо знакомы с регулярными выражениями Perl.
575
+
576
+ К тому же, как вы уже, наверное, догадались, Gitolite для удобства дописывает в начале регулярного выражения `refs/heads/`, если оно не начинается с `refs/`.
577
+
578
+ Важной особенностью синтаксиса конфигурационного файла является то, что все правила для репозитория не обязательно должны находиться в одном месте. Вы можете держать все общие вещи вместе, как, например, правила для всех `oss_repos` выше, а потом добавить уточняющие правила для отдельных случаев следующим образом:
579
+
580
+ repo gitolite
581
+ RW+ = sitaram
582
+
583
+ Это правило будет добавлено к набору правил для репозитория `gitolite`.
584
+
585
+ В данный момент вы, возможно, задаётесь вопросом: "Каким образом правила контроля доступа применяются на самом деле?" — так что давайте вкратце рассмотрим это.
586
+
587
+ В Gitolite'е есть два уровня контроля доступа. Первый — на уровне репозитория; если у вас есть доступ на чтение (или запись) к *любой* ссылке в репозитории, то у вас есть доступ на чтение (или запись) к этому репозиторию.
588
+
589
+ Второй уровень применим только к доступу на запись и осуществляется по веткам или меткам внутри репозитория. Имя пользователя, запрашиваемый уровень доступа (`W` или `+`) и имя ссылки, которая будет обновлена, известны. Правила доступа проверяются в порядке их появления в конфигурационном файле, в поисках совпадений для этой комбинации (но помните, что имя ссылки сопоставляется с регулярным выражением, а не просто строкой). Если совпадение найдено, отправка (push) проходит успешно. При неудачном исходе доступ запрещается.
590
+
591
+ ### Продвинутый контроль доступа с запрещающими правилами ###
592
+
593
+ До сих пор у нас были только права вида `R`, `RW` или `RW+`. Однако в Gitolite'е есть другие права доступа: `-` означающий "запретить". Это даёт гораздо больше возможностей в обмен на большую сложность, так как теперь отсутствие разрешающего правила — не *единственный* вариант, при котором пользователю может быть отказано в доступе, так что *порядок правил теперь имеет значение*!
594
+
595
+ Предположим, в описанной выше ситуации мы хотим, чтобы инженеры могли откатить назад любую ветку, *кроме* `master` и `integ`. Вот как это сделать:
596
+
597
+ RW master integ = @engineers
598
+ - master integ = @engineers
599
+ RW+ = @engineers
600
+
601
+ Снова, вы просто идёте по правилам сверху вниз, пока не наткнётесь на соответствующее вашему режиму доступа или на запрет. Неоткатывающий push в `master` или `integ` разрешается первым правилом. Откатывающий push для этих ссылок не соответствует первому правилу, переходит ко второму и поэтому запрещается. Любой push (откатывающий или неоткатывающий) по ссылкам, отличным от `master` и `integ`, не совпадёт с первыми двумя правилами, а третье правило его разрешает.
602
+
603
+ ### Ограничение push'ей на основе изменённых файлов ###
604
+
605
+ Вдобавок к ограничению веток, в которые пользователю можно отправлять изменения, вы можете также ограничить файлы, которые он может трогать. Например, возможно, Makefile (или какая-то другая программа) не предназначен для изменения кем угодно, так как многие вещи зависят от него или сломаются, если изменения не будут сделаны *правильно*. Вы можете сказать Gitolite'у:
606
+
607
+ repo foo
608
+ RW = @junior_devs @senior_devs
609
+
610
+ - VREF/NAME/Makefile = @junior_devs
611
+
612
+ Стоит предостеречь тех, кто пользовался старыми версиями Gitolite'а, о том, что в новых версиях поведение этой функции было сильно изменено. Подробнее об этих изменениях можно узнать в руководстве по миграции.
613
+
614
+ ### Персональные ветки ###
615
+
616
+ Gitolite также имеет средство, которое называется "персональные ветки" (или даже "персональное пространство имён веток"), которое может быть весьма полезным в корпоративных средах.
617
+
618
+ Очень часто обмен кодом в мире Git'а происходит через запросы "пожалуйста, заберите (pull)". В корпоративных средах, однако, неаутентифицированный доступ под строгим запретом, и рабочая станция разработчика не может выполнить аутентификацию. Так что вы вынуждены отправить (push) работу на центральный сервер и попросить кого-нибудь забрать (pull) её оттуда.
619
+
620
+ Это обычно вызывает такой же беспорядок с именами веток, что и в централизованных СКВ, плюс настройка прав доступа для этого становится ежедневной обязанностью админа.
621
+
622
+ Gitolite позволяет определить "персональный" или "рабочий" префикс пространства имён для каждого разработчика (например, `refs/personal/<devname>/*`); подробное описание этой функциональности есть в документации.
623
+
624
+ ### "Шаблонные" репозитории ###
625
+
626
+ Gitolite позволяет указывать репозитории с помощью шаблонов (на самом деле регулярных выражений Perl'а), таких как, например, `assignments/s[0-9][0-9]/a[0-9][0-9]`. Это позволяет назначать новый режим доступа (`C`), который позволяет пользователям создавать репозитории на основе подобных шаблонов, автоматически назначает владельцем пользователя, который создал репозиторий, позволяет ему раздавать `R` и `RW` права другим пользователям и т.п.
627
+
628
+ ### Другие функции ###
629
+
630
+ Мы закончим это обсуждение рассмотрением подборки других функций, все они и многие другие описаны в мельчайших подробностях в документации.
631
+
632
+ **Логирование**: Gitolite регистрирует все успешные действия. Если вы несколько легкомысленно раздали людям права на откатывание изменений (`RW+`) и кто-то снёс `master`, лог-файл спасёт вам жизнь, и вы легко и быстро найдёте потерянный SHA.
633
+
634
+ **Уведомление о правах доступа**: Другая удобная функция проявляется в момент, когда вы просто проверяете и заходите по ssh на сервер. Gitolite показывает, к каким репозиториям у вас есть доступ и какого типа доступ может быть получен. Вот пример:
635
+
636
+ hello scott, this is git@git running gitolite3 v3.01-18-g9609868 on git 1.7.4.4
637
+
638
+ R anu-wsd
639
+ R entrans
640
+ R W git-notes
641
+ R W gitolite
642
+ R W gitolite-admin
643
+ R indic_web_input
644
+ R shreelipi_converter
645
+
646
+ **Делегирование**: При действительно больших установках вы можете делегировать ответственность за группы репозиториев различным людям, которые будут независимо управлять этими частями. Это уменьшает нагрузку на главного админа и делает его не таким критичным элементом.
647
+
648
+ **Зеркалирование**: Gitolite может помочь вам поддерживать несколько зеркал, и легко переключаться между ними, если основной сервер упадёт.
649
+
650
+ ## Git-демон ##
651
+
652
+ Для предоставления публичного неаутентифицируемого доступа на чтение к своим проектам стоит продвинуться дальше, чем протокол HTTP, и начать использовать Git-протокол. Основное его преимущество — скорость. Git-протокол гораздо эффективнее и следовательно быстрее чем HTTP, поэтому, используя его, вы можете сэкономить своим пользователям время.
653
+
654
+ Напомним, что он годится только для доступа на чтение без аутентификации. Если вы запустили его на сервере не загороженном сетевым экраном, то он должен использоваться только для проектов, которые публично видны внешнему миру. Если сервер, на котором вы его запускаете, находится за сетевым экраном, тогда его вполне можно использовать для проектов, к которым нужно иметь доступ только на чтение для большого числа людей или компьютеров (серверов непрерывной интеграции или сборки), если вы не хотите для каждого из них заводить свой SSH-ключ.
655
+
656
+ В любом случае, Git-протокол относительно просто настроить. По сути, вам нужно запустить следующую команду в демонизированной форме:
657
+
658
+ git daemon --reuseaddr --base-path=/opt/git/ /opt/git/
659
+
660
+ Опция `--reuseaddr` позволит серверу перезапускаться без ожидания окончания старых соединений, `--base-path` позволит людям не указывать полный путь при клонировании проекта, а путь в конце говорит Git-демону, где искать экспортируемые репозитории. Если у вас запущен сетевой экран, то ещё необходимо проделать в нём дырочку, открыв порт 9418 на машине, на которой это всё запущено.
661
+
662
+ Вы можете демонизировать этот процесс несколькими путями, в зависимости от операционной системы. На машине с Ubuntu используйте Upstart-сценарий. Итак, в этот файл
663
+
664
+ /etc/event.d/local-git-daemon
665
+
666
+ поместите такой сценарий:
667
+
668
+ start on startup
669
+ stop on shutdown
670
+ exec /usr/bin/git daemon \
671
+ --user=git --group=git \
672
+ --reuseaddr \
673
+ --base-path=/opt/git/ \
674
+ /opt/git/
675
+ respawn
676
+
677
+ По соображениям безопасности крайне желательно, чтобы вы запускали этот демон от пользователя с правами только на чтение на репозитории — вы легко можете сделать это, создав пользователя 'git-ro' и запустив этот демон из-под него. Для простоты мы запустим его от того же пользователя 'git', от которого запущен Gitosis.
678
+
679
+ Когда вы перезапустите машину, Git-демон запустится автоматически, и возродится, если вдруг завершится. Чтобы запустить его без перезагрузки машины, выполните следующее:
680
+
681
+ initctl start local-git-daemon
682
+
683
+ На других системах вы можете использовать `xinetd`, сценарий для системы `sysvinit`, или что-то другое — главное, чтобы вы могли эту команду как-либо демонизировать и перезапускать в случае завершения.
684
+
685
+ Затем, вы должны указать Gitosis-серверу, к каким репозиториям предоставить неаутентифицируемый доступ через Git-сервер. Если вы добавили по секции для каждого репозитория, вы можете указать, из каких из них Git-демону позволено читать. Если вы хотите предоставить доступ по Git-протоколу к `iphone_project`, добавьте следующее в конец своего файла `gitosis.conf`:
686
+
687
+ [repo iphone_project]
688
+ daemon = yes
689
+
690
+ Когда это зафиксировано и отправлено, ваш запущенный демон должен начать обслуживать запросы к проекту от всех, у кого есть доступ к порту 9418 на вашем сервере.
691
+
692
+ Если вы решили не использовать Gitosis, но хотите установить Git-демон, вам необходимо выполнить следующее в каждом проекте, который должен обслуживаться Git-демоном:
693
+
694
+ $ cd /path/to/project.git
695
+ $ touch git-daemon-export-ok
696
+
697
+ Наличие этого файла скажет Git'у, что этот проект можно обслуживать без аутентификации.
698
+
699
+ Gitosis также может контролировать, какие проекты будет показывать GitWeb. Вам нужно добавить что-то вроде этого в файл `/etc/gitweb.conf`:
700
+
701
+ $projects_list = "/home/git/gitosis/projects.list";
702
+ $projectroot = "/home/git/repositories";
703
+ $export_ok = "git-daemon-export-ok";
704
+ @git_base_url_list = ('git://gitserver');
705
+
706
+ Вы можете контролировать, какие проекты GitWeb будет позволять просматривать пользователям, добавляя или удаляя пункт настройки `gitweb` в конфигурационном файле Gitosis'а. Например, если вы хотите, чтобы `iphone_project` просматривался в GitWeb, сделайте так, чтобы секция настроек `repo` выглядела следующим образом:
707
+
708
+ [repo iphone_project]
709
+ daemon = yes
710
+ gitweb = yes
711
+
712
+ Теперь, если вы зафиксируете и отправите изменения, GitWeb автоматически начнёт показывать ваш проект для iphone.
713
+
714
+ ## Git-хостинг ##
715
+
716
+ Если вы не хотите связываться со всей работой по установке собственного Git-сервера, у вас есть несколько вариантов размещения ваших Git-проектов на внешних специальных хостинг сайтах. Это предоставляет множество преимуществ: на хостинг сайте обычно быстро настроить и запустить проект и нет никакого мониторинга или поддержки сервера. Даже если вы установили и запустили свой собственный внутренний сервер, вы можете захотеть использовать публичный хостинг сайт для вашего открытого кода — обычно сообществу открытого кода так будет проще вас найти и помочь.
717
+
718
+ В наши дни у вас есть огромное количество вариантов хостинга на выбор, все со своими преимуществами и недостатками. Актуальный список можно найти на следующей странице:
719
+
720
+ https://git.wiki.kernel.org/index.php/GitHosting
721
+
722
+ Поскольку мы не можем рассмотреть их все, и поскольку я работаю на один из них, мы в этом разделе рассмотрим процесс создания учётной записи и нового проекта на GitHub'е. Это даст вам представление о вовлечённых в него вещах.
723
+
724
+ GitHub — крупнейший на сегодняшний день сайт, предоставляющий Git-хостинг для проектов с открытым исходным кодом, а также один из немногих, предоставляющих одновременно и публичный, и приватный хостинг, так что вы можете хранить ваш открытый и коммерческий код в одном месте. На самом деле, мы использовали GitHub, чтобы закрыто совместно писать эту книгу (прим. переводчика: и открыто переводить после её издания).
725
+
726
+ ### GitHub ###
727
+
728
+ GitHub немного отличается от других хостингов кода способом группировки проектов. Вместо того, чтобы брать за основу проекты, GitHub ориентируется на пользователей. Это значит, что если я размещаю свой проект `grit` на GitHub'е, вы не найдёте его в `github.com/grit`, он будет в `github.com/schacon/grit`. Здесь нет никакой канонической версии проекта, что позволяет проектам беспрепятственно переходить от одного пользователя к другому, если начальный автор забросил проект.
729
+
730
+ GitHub — это коммерческая компания, которая взимает плату с учётных записей, использующих приватные репозитории, но любой может хоть сейчас получить бесплатную учётную запись и разместить сколько ему угодно открытых проектов. Мы быстро рассмотрим, как это делается.
731
+
732
+ ### Настройка учётной записи ###
733
+
734
+ Первое, что вам нужно сделать, это настроить учётную запись. Если вы посетите страницу "Plans and pricing" по адресу `https://github.com/pricing` и нажмёте на кнопку "Create a free account" (см. рисунок 4-2), вы попадёте на страницу регистрации.
735
+
736
+ Insert 18333fig0402.png
737
+ Рисунок 4-2. Страница тарифных планов на GitHub'е.
738
+
739
+ Здесь вы должны выбрать имя пользователя, которое ещё не занято в системе, ввести адрес электронной почты, который будет сопоставлен аккаунту, и пароль (см. рис. 4-3).
740
+
741
+ Insert 18333fig0403.png
742
+ Рисунок 4-3. Страница регистрации пользователя на GitHub'е.
743
+
744
+ Если есть возможность, сейчас также самое время добавить свой открытый SSH-ключ. Мы рассмотрели, как создать ключ, ранее, в разделе "Создание открытого SSH-ключа". Возьмите содержимое открытого ключа из своей пары и вставьте в поле для ввода открытого SSH-ключа. Ссылка "explain ssh keys" направит вас к подробным инструкциям о том, как это сделать на всех основных операционных системах.
745
+ Нажатие на кнопку "I agree, sign me up" откроет инструментальную панель вашего нового пользователя (см. рис. 4-4).
746
+
747
+ Insert 18333fig0404.png
748
+ Рисунок 4-4. Инструментальная панель на GitHub'е.
749
+
750
+ После этого вы можете создать новый репозиторий.
751
+
752
+ ### Создание нового репозитория ###
753
+
754
+ Начните с нажатия на "New repository" рядом с разделом "Your Repositories" на странице инструментальной панели. Вы попадёте к форме для создания нового репозитория (см. рис. 4-5).
755
+
756
+ Insert 18333fig0405.png
757
+ Рисунок 4-5. Создание нового репозитория на GitHub'е.
758
+
759
+ Единственное, что вам обязательно нужно сделать, это указать имя проекта, но вы также можете добавить и описание. Когда сделаете это, нажмите на кнопку "Create Repository". Теперь у вас есть новый репозиторий на GitHub'е (см. рис. 4-6).
760
+
761
+ Insert 18333fig0406.png
762
+ Рисунок 4-6. Заглавная информация проекта GitHub.
763
+
764
+ Поскольку у вас ещё нет кода, GitHub покажет вам инструкцию, как создать совершенно новый проект, отправить существующий или импортировать проект из публичного репозитория Subversion (см. рис. 4-7).
765
+
766
+ Insert 18333fig0407.png
767
+ Рисунок 4-7. Инструкции для нового репозитория.
768
+
769
+ Эти инструкции похожи на то, что мы проходили раньше. Чтобы инициализировать проект, если это ещё не Git-проект, используйте:
770
+
771
+ $ git init
772
+ $ git add .
773
+ $ git commit -m 'initial commit'
774
+
775
+ Если у вас есть локальный Git-репозиторий, добавьте GitHub как удалённый сервер и отправьте туда свою ветку master:
776
+
777
+ $ git remote add origin git@github.com:testinguser/iphone_project.git
778
+ $ git push origin master
779
+
780
+ Теперь ваш проект размещён на GitHub'е, и вы можете дать ссылку на него любому, с кем вы захотите разделить проект. В этом случае, это `http://github.com/testinguser/iphone_project`. Вы также можете видеть в заголовке каждой страницы проекта, что у вас две Git-ссылки (см. рис. 4-8).
781
+
782
+ Insert 18333fig0408.png
783
+ Рисунок 4-8. Заголовок проекта с публичной и приватной ссылками.
784
+
785
+ Ссылка "Public Clone URL" — это публичная ссылка только для чтения, через которую кто угодно может склонировать проект. Можете опубликовать эту ссылку или разместить её на своём сайте — где угодно.
786
+
787
+ "Your Clone URL" — это SSH-ссылка на чтение и запись, через которую вы можете читать и писать только в том случае, если вы подключаетесь с использованием секретного ключа из пары открытого SSH-ключа, загруженного в вашу учётную запись. Если другие пользователи посетят страницу этого проекта, они не увидят этой ссылки — только публичную.
788
+
789
+ ### Импорт из Subversion ###
790
+
791
+ Если у вас есть существующий публичный Subversion-проект, который вы хотите импортировать в Git, GitHub часто может сделать это за вас. Внизу страницы инструкций есть ссылка на импорт из Subversion. Если вы кликнете по ней, вы увидите форму с информацией о процессе импорта и текстовое поле, где вы можете вставить ссылку на ваш публичный Subversion-проект (см. рис. 4-9).
792
+
793
+ Insert 18333fig0409.png
794
+ Рисунок 4-9. Интерфейс импорта из Subversion.
795
+
796
+ Если ваш проект очень большой, нестандартный или приватный, этот процесс, возможно, не сработает для вас. В главе 7 вы узнаете, как делать более сложные импорты вручную.
797
+
798
+ ### Добавление участников ###
799
+
800
+ Давайте добавим остальную команду. Если Джон, Джози и Джессика зарегистрированы на GitHub'е, и вы хотите дать им доступ на отправку изменений в свой репозиторий, вы можете добавить их в свой проект как участников. Это позволит им отправлять изменения, используя свои открытые ключи.
801
+
802
+ Нажмите на кнопку "edit" в заголовке проекта или вкладку "Admin" вверху, чтобы попасть на страницу администратора вашего проекта на GitHub'е (см. рис. 4-10).
803
+
804
+ Insert 18333fig0410.png
805
+ Рисунок 4-10. Страница администратора на GitHub'е.
806
+
807
+ Чтобы дать другому пользователю доступ на запись в проект, кликните по ссылке “Add another collaborator”. Появится новое текстовое поле, в котором вы можете набрать имя пользователя. По мере набора всплывёт подсказка, показывающая возможные совпадения имён. Когда найдёте нужного пользователя, нажмите на кнопку Add, чтобы добавить пользователя как участника вашего проекта (см. рис. 4-11).
808
+
809
+ Insert 18333fig0411.png
810
+ Рисунок 4-11. Добавление участника в проект.
811
+
812
+ Когда закончите добавлять участников, вы должны увидеть их список в разделе Repository Collaborators (см. рис. 4-12).
813
+
814
+ Insert 18333fig0412.png
815
+ Рисунок 4-12. Список участников вашего проекта.
816
+
817
+ Если вам нужно отозвать чей-то доступ, можете кликнуть по ссылке "revoke", и его доступ на отправку будет удалён. Для будущих проектов вы также можете скопировать группы участников, скопировав права доступа из существующего проекта.
818
+
819
+ ### Ваш проект ###
820
+
821
+ После того как вы отправили ваш проект или импортировали его из Subversion, у вас есть главная страница проекта, которая выглядит как на рис. 4-13.
822
+
823
+ Insert 18333fig0413.png
824
+ Рисунок 4-13. Главная страница проекта на GitHub'е.
825
+
826
+ Когда люди посещают ваш проект, они видят эту страницу. Она содержит вкладки, касающиеся различных аспектов вашего проекта. Вкладка Commits показывает список коммитов в обратном хронологическом порядке наподобие вывода команды `git log`. Вкладка Network показывает всех людей, отделивших ваш проект и вернувших свои наработки. Вкладка Downloads позволяет выложить бинарные файлы проекта и ссылки на архивы каких-нибудь отмеченных точек проекта. Вкладка Wiki предоставляет вики, где вы можете написать документацию или другую информацию о своём проекте. Вкладка Graphs показывает некоторую информацию о вкладе участников и статистику проекта. Главная вкладка Source показывает листинг корневого каталога проекта и автоматически выводит под ним содержимое файла README, если он у вас есть. Эта вкладка также показывает информацию о последнем коммите.
827
+
828
+ ### Ответвления проектов ###
829
+
830
+ Если вы хотите внести вклад в существующий проект, на отправку изменений в который у вас нет прав, GitHub приветствует ответвления. Когда вы смотрите на страницу заинтересовавшего вас проекта и хотите немного поработать над ним, вы можете нажать на кнопку "Fork" в заголовке проекта, чтобы GitHub скопировал проект вашему пользователю, и вы смогли отправлять туда свои изменения.
831
+
832
+ Таким образом, проектам не нужно беспокоиться о добавлении пользователей в качестве участников для предоставления им доступа на отправку изменений. Люди могут ответвить проект и отправлять изменения в свою копию. А мейнтейнер главного проекта может вернуть эти изменения, добавляя форки как удалённые серверы и сливая из них наработки.
833
+
834
+ Чтобы ответвить проект, посетите страницу проекта (в нашем случае mojombo/chronic) и нажмите на кнопку "Fork" в его заголовке (см. рис. 4-14).
835
+
836
+ Insert 18333fig0414.png
837
+ Рисунок 4-14. Получение доступной для записи копии любого репозитория.
838
+
839
+ Через несколько секунд вы будете направлены на страницу своего нового проекта, на которой указано, что данный проект является ответвлением другого проекта (см. рис. 4-15).
840
+
841
+ Insert 18333fig0415.png
842
+ Рисунок 4-15. Вы ответвили проект.
843
+
844
+ ### Заключение о GitHub ###
845
+
846
+ Это всё, что мы хотели бы рассказать про GitHub, но важно отметить, как быстро вы можете всё сделать. Вы можете создать аккаунт, добавить новый проект и отправить изменения в него за минуты. Если ваш проект с открытым исходным кодом, вы также получите огромное сообщество разработчиков, которые смогут увидеть ваш проект, ответвить его и внести в него свой вклад. Во всяком случае, это хороший способ получить готовую к работе с Git'ом среду, чтобы быстренько испытать его в деле.
847
+
848
+ ## Итоги ##
849
+
850
+ У вас есть несколько вариантов получения удалённого Git-репозитория так, чтобы вы могли принимать участие в проекте вместе с другими или поделиться работой.
851
+
852
+ Запуск своего сервера даёт полный контроль и позволяет запускать сервер за вашим сетевым экраном, но такой сервер обычно требует значительной части вашего времени на настройку и поддержку. Если вы разместите ваши данные на хостинге, его просто настроить и поддерживать; однако вам необходимо иметь возможность хранить код на чужом сервере, а некоторые организации этого не позволяют.
853
+
854
+ Выбор решения или комбинации решений, которые подойдут вам и вашей организации, не должен вызвать затруднений.