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,606 @@
1
+ # Personalizzare Git #
2
+
3
+ Finora abbiamo viso le basi di come Git e come usarlo, abbiamo introdotto alcuni strumenti forniti da Git per aiutarti a usarlo al meglio ed efficientemente. In questo capitolo vedremo alcune operazioni che possono essere utilizzate per personalizzare il comportamento di Git, introducendo molte impostazione e il sistema degli `hook`. Tramite questi strumenti sarà semplice fare in modo che Git lavori come tu, la tua azienda, o il tuo gruppo desideriate.
4
+
5
+ ## Configurazione di Git ##
6
+
7
+ Come abbiamo visto brevemente nel capitolo 1, è possibile configurare Git con il comando `git config`. Una delle prime cose che abbiamo fatto è stato definire il nostro nome e il nostro indirizzo e-mail:
8
+
9
+ $ git config --global user.name "John Doe"
10
+ $ git config --global user.email johndoe@example.com
11
+
12
+ Ora vedremo alcune delle opzioni più interessanti che puoi configurare allo stesso modo, per personalizzare il modo in cui usi Git.
13
+
14
+ Nel primo capitolo hai visto alcuni dettagli per delle configurazioni semplici, ora li rivedremo velocemente. Git usa più file di configurazione per decidere cosa fare in situazioni non standard. Il primo di questi, dove Git cercherà, è `/etc/gitconfig`, che contiene la configurazione per tutti gli utenti del sistema e dei loro repository. Git legge e scrive su questo file quando usi l'opzione `--system` con `git config`.
15
+
16
+ Il file successivo dove Git va a cercare è `~/.gitconfig`, che è specifico per ogni utente. Puoi fare in modo che Git legga e scriva su questo file con l'opzione `--global`.
17
+
18
+ Infine Git controlla le impostazioni nel file di configurazione presente nella directory Git (`.git/config`) di qualsiasi repository che tu stia utilizzando. Queste impostazioni sono specifiche di quel singolo repository. Ogni livello sovrascrive i valori del livello precedente, quindi i valori in `.git/config` battono quelli in `/etc/gitconfig`. Puoi configurare queste impostazioni anche editando manualmente il file, usando la sintassi corretta, ma solitamente è più semplice eseguire il comando `git config`.
19
+
20
+ ### Configurazione minima del client ###
21
+
22
+ Le opzioni di configurazione riconosciute da Git si suddividono in due categorie: `client-side` e `server-side`. La maggioranza delle opzioni sono client-side perché definiscono le tue preferenze personali. Sebbene siano disponibili moltissime opzioni, vedremo solo le poche che sono utilizzate spesso o che possono influenzare significativamente il tuo ambiente di lavoro. Molte opzioni sono utili solo in casi estremi che quindi non esamineremo in questa sede. Se vuoi vedere l'elenco di tutte le opzioni disponibili in Git, puoi eseguire il comando
23
+
24
+ $ git config --help
25
+
26
+ La pagina del manuale per `git config` elenca tutte le opzioni disponibili aggiungendo qualche dettaglio.
27
+
28
+ #### core.editor ####
29
+
30
+ Di default, Git utilizza qualsiasi programma tu abbia impostato come text editor o, in mancanza, sceglie l'editor Vi per creare e modificare i messaggi delle commit e dei tag. Per cambiare l'impostazione standard, puoi configurare il `core.editor`:
31
+
32
+ $ git config --global core.editor emacs
33
+
34
+ Facendo così non importa quale sia l'editor predefinito configurato per la tua shell, Git lancerà sempre Emacs per modificare i messaggi.
35
+
36
+ #### commit.template ####
37
+
38
+ Se come valore per questo parametro definisci il percorso di un file, Git utilizzerà quel file come modello per i tuoi messaggio quando committi. Supponiamo per esempio che tu abbia creato il seguente modello in `$HOME/.gitmessage.txt`:
39
+
40
+ oggetto
41
+
42
+ cos'è successo: giustifica la tua commit
43
+
44
+ [ticket: X]
45
+
46
+ Per comunicare a Git di usare sempre questo messaggio nel tuo editor quando esegui `git commit`, configura `commit.template` in questo modo:
47
+
48
+ $ git config --global commit.template $HOME/.gitmessage.txt
49
+ $ git commit
50
+
51
+ Quando committi, il tuo editor si aprirà con un contenuto simile al seguente, perché tu scriva il tuo messaggio:
52
+
53
+ oggetto
54
+
55
+ cos'è successo: giustifica la tua commit
56
+
57
+ [ticket: X]
58
+ # Please enter the commit message for your changes. Lines starting
59
+ # with '#' will be ignored, and an empty message aborts the commit.
60
+ # On branch master
61
+ # Changes to be committed:
62
+ # (use "git reset HEAD <file>..." to unstage)
63
+ #
64
+ # modified: lib/test.rb
65
+ #
66
+ ~
67
+ ~
68
+ ".git/COMMIT_EDITMSG" 14L, 297C
69
+
70
+ Nel caso tu abbia una sintassi standard da seguire per i messaggi di commit, configurare Git perché usi un modello può aumentare le possibilità che quello standard venga rispettato.
71
+
72
+ #### core.pager ####
73
+
74
+ L'impostazione core.pager determina quale applicazione debba essere usata da Git quando pagina output lunghi come `log` e `diff`. Puoi impostarlo a `more` o alla tua applicazione preferita (predefinito è `less`), o puoi anche disattivarlo impostandolo a una stringa vuota:
75
+
76
+ $ git config --global core.pager ''
77
+
78
+ Se eseguissi questo comando, Git paginerà l'intero output di qualsiasi comando, non importa quanto esso sia lungo.
79
+
80
+ #### user.signingkey ####
81
+
82
+ Nel caso utilizzi tag firmati (come descritto nel capitolo 2), definire la tua chiave GPG nelle impostazioni rende le cose più semplici. Imposta l'ID della tua chiave in questo modo:
83
+
84
+ $ git config --global user.signingkey <gpg-key-id>
85
+
86
+ Ora, puoi firmare i tags, senza dover specificare ogni volta la tua chiave, con il comando `git tag`:
87
+
88
+ $ git tag -s <tag-name>
89
+
90
+ #### core.excludesfile ####
91
+
92
+ Puoi inserire dei modelli nel file `.gitignore` del tuo progetto per fare in modo che Git non li veda come file non tracciati o provi a metterli nell'area di stage quando esegui `git add`, come visto nel capitolo 2. Se però vuoi che un altro file, all'esterno del tuo progetto, gestisca queste esclusioni o vuoi definire valori addizionali, puoi dire a Git dove si trovi quel file con `core.excludesfile`. Ti basta specificare il percorso del file che abbia un contenuto simile a quello che avrebbe il `.gitignore`.
93
+
94
+ #### help.autocorrect ####
95
+
96
+ Questa opzione è disponibile solo da Git 1.6.1 in poi. Se digiti male un comando in Git, otterrai qualcosa del genere:
97
+
98
+ $ git com
99
+ git: 'com' is not a git-command. See 'git --help'.
100
+
101
+ Did you mean this?
102
+ commit
103
+
104
+ Se imposti `help.autocorrect` a 1, Git eseguirà automaticamente il comando nel caso esista un'unica corrispondenza.
105
+
106
+ ### Colors in Git ###
107
+
108
+ Git può rendere i suoi messaggi colorati nel tuo terminale, in questo modo può aiutarti a capire velocemente e facilmente l'output. Un numero di opzioni può aiutarti ad impostare le preferenze nei colori.
109
+
110
+ #### color.ui ####
111
+
112
+ Git colora automaticamente la maggior parte dei suoi output se richiesto. Si possono fare richieste molto specifiche su cosa si vuole che sia colorato e come; per attivare tutti i colori di default nel terminale basta impostare `color.ui` a true:
113
+
114
+ $ git config --global color.ui true
115
+
116
+ Una volta impostato il valore, Git colorerà il suo output se esso è indirizzato ad un terminale. Altre possibili impostazioni sono false, che non permette mai di colorare l'output, ed always, che imposta i colori sempre, anche se l'output è reindirizzato ad un file o ad un altro comando tramite pipe. Questa impostazione è stata aggiunta a Git nella versione 1.5.5; se possiedi una versione più vecchia dovrai impostare tutti i settaggi per i colori individualmente.
117
+
118
+ Raramente è desiderabile impostare `color.ui = always`. Nella maggior parte dei casi, se vuoi codice colorato in un output reindirizzato puoi invocare il comando con il flag `--color` in modo da forzare l'uso del colore. L'opzione tipicamente usata è `color.ui = true`.
119
+
120
+ #### `color.*` ####
121
+
122
+ Nel caso in cui si desideri una configurazione più specifica su quali comandi sono colorati e come, o si abbia una versione meno recente, Git fornisce impostazioni di colorazione verb-specific. Ognuna di esse può essere impostata a `true`, `false` oppure `always`:
123
+
124
+ color.branch
125
+ color.diff
126
+ color.interactive
127
+ color.status
128
+
129
+ In aggiunta, ognuna di queste ha sottoimpostazioni che possono essere utilizzate per impostare colori specifici per le parti dell'output, nel caso si voglia sovrascrivere ogni colore. Per esempio, per impostare la meta informazione nell'output di diff che indichi di usare blu per il testo, nero per lo sfondo e testo in grassetto, puoi eseguire il comando:
130
+
131
+ $ git config --global color.diff.meta "blue black bold"
132
+
133
+ Il colore può essere impostato di ognuno dei seguenti valori: `normal` (normale), `black` (nero), `red` (rosso), `green` (verde), `yellow` (giallo), `blue` (blu), `magenta`, `cyan` (ciano), `white` (bianco) oppure, se il tuo terminale supporta più di sedici colori, un valore numerico per il colore che vada da 0 a 255 (in un terminale a 256 colori). Per quanto riguarda gli attributi, come `bold` nell'esempio precedente, puoi scegliere tra from `bold` (grassetto), `dim` (ridotto), `ul` (sottolineato), `blink` (lampeggiante), e `revers` (a colori invertiti).
134
+
135
+ Per queste sotto-configurazioni puoi guardare la pagina di manuale di `git config`.
136
+
137
+ ### Strumenti Esterni per Merge e Diff ###
138
+
139
+ Inoltre Git ha un'implementazione interna di diff, che è quella che stai utilizzando, puoi impostare, in alternativa, uno strumento esterno. Puoi anche impostare uno strumento per la risoluzione dei conflitti di merge invece di doverli risolvere a mano. Dimostrerò come impostare il Perforce Visual Merge Tool (P4Merge) per gestire i diff ed i merge, perché è uno strumento grafico carino e gratuito.
140
+
141
+ Se vuoi provarlo, P4Merge funziona su tutte le maggiori piattaforme, quindi dovresti riuscirci. Negli esempi utilizzerò nomi di percorso che funzionano su sistemi Mac e Linux; per quanto riguarda Windows, dovrai cambiare `/usr/local/bin` con il percorso dell'eseguibile nel tuo ambiente.
142
+
143
+ Puoi scarucare P4Merge qua:
144
+
145
+ http://www.perforce.com/product/components/perforce-visual-merge-and-diff-tools
146
+
147
+ Per iniziare dovrai impostare scripts esterni di wrapping per eseguire i tuoi comandi. Utilizzerò il percorso relativo a Mac per l'eseguibile; in altri sistemi, sarà dove è posizionato il binario `p4merge`. Imposta uno script per il wrapping del merge chiamato `extMerge` che chiami il binario con tutti gli argomenti necessari:
148
+
149
+ $ cat /usr/local/bin/extMerge
150
+ #!/bin/sh
151
+ /Applications/p4merge.app/Contents/MacOS/p4merge $*
152
+
153
+ Il wrapper per il diff controlla di assicurarsi che siano provveduti e passati sette argomenti: due per lo script di merge. Di default, Git passa i seguenti argomenti al programma di diff:
154
+
155
+ path old-file old-hex old-mode new-file new-hex new-mode
156
+
157
+ Visto che vuoi solamente gli argomenti `old-file` e `new-file`, puoi notare che lo script di wrapping passa quelli di cui hai bisogno.
158
+
159
+ $ cat /usr/local/bin/extDiff
160
+ #!/bin/sh
161
+ [ $# -eq 7 ] && /usr/local/bin/extMerge "$2" "$5"
162
+
163
+ Hai anche bisogno di assicurarti che questi strumenti siano eseguibili:
164
+
165
+ $ sudo chmod +x /usr/local/bin/extMerge
166
+ $ sudo chmod +x /usr/local/bin/extDiff
167
+
168
+ Ora puoi impostare il tuo file di configurazione per utilizzare gli strumenti personalizzati per diff e merge resolution. Questo richiede un certo numero di impostazioni personalizzate: `merge.tool` per comunicare a Git che strategia utilizzare, `mergetool.*.cmd` per specificare come eseguire i comandi, `mergetool.trustExitCode` per comunicare a Git se il codice di uscita del programma indichi o meno una risoluzione del merge andata a buon fine, e `diff.external` per comunicare a Git quale comando eseguire per i diffs. Quindi, puoi eseguire quattro comandi di configurazione:
169
+
170
+ $ git config --global merge.tool extMerge
171
+ $ git config --global mergetool.extMerge.cmd \
172
+ 'extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"'
173
+ $ git config --global mergetool.trustExitCode false
174
+ $ git config --global diff.external extDiff
175
+
176
+ in alternativa puoi modificate il file `~/.gitconfig` aggiungendo queste linee:
177
+
178
+ [merge]
179
+ tool = extMerge
180
+ [mergetool "extMerge"]
181
+ cmd = extMerge \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"
182
+ trustExitCode = false
183
+ [diff]
184
+ external = extDiff
185
+
186
+ Dopo aver impostato tutto ciò, se vengono eseguiti comandi diff come questo:
187
+
188
+ $ git diff 32d1776b1^ 32d1776b1
189
+
190
+ Invece di visualizzare l'output del diff sulla linea di comando, Git eseguirà P4Merge che assomiglia alla Figura 7-1.
191
+
192
+ Insert 18333fig0701.png
193
+ Figura 7-1. P4Merge.
194
+
195
+ Se provi ad unire due rami e ne derivano dei conflitti, puoi eseguire il comando `git mergetool`; esegue P4Merge permettendoti di risolvere i conflitti tramite uno strumento con interfaccia grafica.
196
+
197
+ Una cosa simpatica riguardo questa configurazione con wrapper è che puoi cambiare gli strumenti di diff e merge in modo semplice. Ad esempio, per cambiare `extDiff` e `extMerge` in modo che eseguano lo strumento KDiff3, tutto ciò che devi fare è modificare il file `extMerge`:
198
+
199
+ $ cat /usr/local/bin/extMerge
200
+ #!/bin/sh
201
+ /Applications/kdiff3.app/Contents/MacOS/kdiff3 $*
202
+
203
+ Ora, Git utilizzerà lo strumento KDiff3 per mostrare i diff e per la risoluzione di conflitti di merge.
204
+
205
+ Git è preconfigurato per utilizzare un numero di strumenti per la risoluzione di merge senza dover impostare una configurazione a linea di comando. Puoi impostare come mergetool: kdiff3, opendiff, tkdiff, meld, xxdiff, emerge, vimdiff, o gvimdiff. Nel caso tu non sia interessato ad utilizzare KDiff3 per i diff ma comunque tu voglia usarlo per la risoluzione del merge ed il comando kdiff3 è nel tuo path, puoi eseguire:
206
+
207
+ $ git config --global merge.tool kdiff3
208
+
209
+ Se esegui questo invece di impostare i files `extMerge` ed `extDiff`, Git utilizzerà KDiff3 per la risoluzione dei merge e lo strumento standard per i diffs.
210
+
211
+ ### Formattazione e Whitespace ###
212
+
213
+ I problemdi di formattazione e di whitespaces sono tra i più frustranti ed insidiosi che molti sviluppatori incontrano quando collaborano, specialmente in cross-platform. È molto semplice per patches o altri lavori in collaborazione inserire astrusi cambiamenti whitespace perché gli editor li introducono impercettibilmente o programmatori Windows aggiungono carriage-return al termine delle righe che modificano in progetti cross-platform. Git ha alcune opzioni di configurazione per aiutare con questi problemi.
214
+
215
+ #### core.autocrlf ####
216
+
217
+ Nel caso tu stia programmando su Windows o utilizzando un altro sistema ma comunque qualcuno nel tuo gruppo utilizza Windows, probabilmente avrai problemi di line-editing ad un certo punto. Questo è dovuto al fatto che Windows utilizza sia caratteri carriage-return che linefeed per andare a capo nei suoi files, mentre i sistemi Mac e Linux utilizzano solo caratteri linefeed. Questo è un insidioso ed incredibilmente fastidioso problema del lavoro cross-platform.
218
+
219
+ Git può gestire questo convertendo in modo automatico righe CRLF in LF al momento del commit, vice versa quando estrae codice nel filesystem. Puoi attivare questa funzionalità tramite l'opzione `core.autocrlf`. Nel caso tu sia su una macchina windows impostalo a `true` — questo converte le terminazioni LF in CRLF nel momento in cui il codice viene estratto:
220
+
221
+ $ git config --global core.autocrlf true
222
+
223
+ Nel caso tu sia su un sistema Linux o Mac che utilizza terminazioni LF, allora non vuoi che Git converta automaticamente all'estrazione dei files; comunque, se un file con terminazioni CRLF viene accidentalmente introdotto, allora potresti desiderare che Git lo ripari. Puoi comunicare a Git di convertire CRLF in LF nei commit ma un'altra via è impostare `core.autocrlf` in input:
224
+
225
+ $ git config --global core.autocrlf input
226
+
227
+ Questa configurazione dovrebbe lasciare le terminazioni CRLF nei checkouts Windows e terminazioni LF nei sistemi Mac e Linux e nei repository.
228
+
229
+ Nel caso tu sia un programmatore Windows che lavora solo con progetti Windows, allora puoi disattivare questa funzionalità, inviando carriage-returns sul repository impostando il valore di configurazione a `false`:
230
+
231
+ $ git config --global core.autocrlf false
232
+
233
+ #### core.whitespace ####
234
+
235
+ Git è preimpostato per trovare e riparare i problemi di whitespace. Può cercare i quattro principali problemi di whitespace — due sono abilitati di default e possono essere disattivati, altri due non sono abilitati di default e possono essere attivati.
236
+
237
+ I due che sono attivi di default sono `trailing-space`, che cerca spazi alla fine della riga, e `space-before-tab`, che cerca spazi prima di tablature all'inizio della riga.
238
+
239
+ I due che sono disattivi di default ma possono essere attivati sono `indent-with-non-tab`, che cerca righe che iniziano con otto o più spazi invece di tablature, e `cr-at-eol`, che comunica a Git che i carriage returns alla fine delle righe sono OK.
240
+
241
+ Puoi comunicare a Git quale di questi vuoi abilitare impostando `core.whitespaces` al valore desiderato o off, separati da virgole. Puoi disabilitare le impostazioni sia lasciando l'impostazione fuori, sia antecedento un `-` all'inizio del valore. Ad esempio, se vuoi tutto attivato a parte `cr-at-eol`, puoi eseguire questo comando:
242
+
243
+ $ git config --global core.whitespace \
244
+ trailing-space,space-before-tab,indent-with-non-tab
245
+
246
+ Git controllerà questi problemi quando viene eseguito un comando `git diff` e provi a colorarli in modo che si possa ripararli prima del commit. Utilizzerà anche questi valori per aiutarti quando applichi pathces tramite `git apply`. Quando stai applicando patches, puoi chiedere a Git di informarti se stai applicando patches con i problemi di whitespace specificati:
247
+
248
+ $ git apply --whitespace=warn <patch>
249
+
250
+ Oppure puoi fare in modo che Git provi automaticamente a riparare i problemi prima di applicare la patch:
251
+
252
+ $ git apply --whitespace=fix <patch>
253
+
254
+ Queste opzioni vengono applicate anche al comando `git rebase`. Se hai fatto commit con problemi di whitespace ma non ne hai fatto push in upstream, puoi eseguire un `rebase` con l'opzione `--whitespace=fix` per permettere a Git di riparare automaticamente i problemi di whitespace riscrivendo le patches.
255
+
256
+ ### Server Configuration ###
257
+
258
+ Non sono disponibili molte opzioni per quanto riguarda la parte server di Git, ma alcune sono interessanti se vuoi prenderne nota.
259
+
260
+ #### receive.fsckObjects ####
261
+
262
+ Di default, Git non fa check di consistenza per tutti gli oggetti che riceve durante un push. Tuttavia Git può fare il check per assicurarsi che ogni oggetto corrisponda al suo checksum SHA-1 e punti ad un oggetto valido, non viene fatto di default ad ogni push. È un'operazione relativamente costosa e può aggiungere molto tempo ad ogni push, in dipendenza della dimensione del repository o del push. Se vuoi che Git esegua il check per la consistenza degli oggetti ad ogni push, puoi forzarlo impostando:
263
+
264
+ $ git config --system receive.fsckObjects true
265
+
266
+ Ora, Git eseguirà un check di integrità del tuo repository prima che ogni push venga accettato, per assicurarsi che client difettosi non introducano dati corrotti.
267
+
268
+ #### receive.denyNonFastForwards ####
269
+
270
+ Se esegui rebase commits di cui hai già fatto push e poi provi nuovamente a farne un push, o altrimenti provi a fare push di un commit ad un ramo remoto che non contiene il commit a cui il ramo remoto punta, ti verrà proibito. Questa è una norma generalmente buona; tuttavia nel caso del rebase, potrebbe succedere che sai quello che stai facendo e puoi eseguire un force-update al branch remoto con un flag `-f` al comando push.
271
+
272
+ Per disabilitare la possibilità di eseguire force-update su rami remoti a riferimenti non-fast-forward, imposta `receive.denyNonFastForwards`:
273
+
274
+ $ git config --system receive.denyNonFastForwards true
275
+
276
+ Un altro modo in cui puoi fare la stessa cosa è ricevere hooks via server-side, che copriremo tra poco. Questo approccio ti permette di eseguire azioni più complesse come impedire non-fast-forwards ad un certo sottoinsieme di utenti.
277
+
278
+ #### receive.denyDeletes ####
279
+
280
+ Uno dei workarounds che si possono fare alla norma `denyNonFastForwards` è che l'utente di cancelli il ramo e lo reinserisca con un nuovo riferimento. Nella nuova versione di Git (a partire dalla versione 1.6.1), puoi impostare `receive.denyDeletes` a true:
281
+
282
+ $ git config --system receive.denyDeletes true
283
+
284
+ Questo nega branch e rimozione di tag su un push su tutta la linea — nessun utente può farlo. Per rimuovere rami remoti, devi rimuovere i files di riferimento dal server manualmente. Ci sono anche altri modi interessanti per farlo su una base per-user utilizzando le ACLs, come imparerai alla fine di questo capitolo.
285
+
286
+ ## Attributi di Git ##
287
+
288
+ Alcune di queste impostazioni possono anche essere specificate per un percorso, per fare in modo che Git applichi queste impostazioni solo per una sottodirectory o un sottoinsieme di files. Queste opzioni path-specific sono chiamate attributi di Git e sono impostati nel file `.gitattributes` in una delle tue directories (normalmente nella radice del progetto) oppure nel file `.git/info/attributes` se non vuoi che venga fatto il commit del file degli attributi del tuo progetto.
289
+
290
+ Usando gli attributi, puoi fare cose come specificare strategie di merge separate per files individuali o directories nel tuo progetto, comunicare a Git come fare diff per files non di testo, oppure fare in modo che Git filtri il contenuto prima del check all'interno o all'esterno di Git. In questa sezione imparerai come impostare alcuni degli attributi sui tuoi percorsi, nel tuo progetto Git, e vedere alcuni esempi di come usare questa caratteristica nella pratica.
291
+
292
+ ### Files Binari ###
293
+
294
+ Un trucco figo per il quale si possono usare gli attributi Git è comunicare a Git quali files siano binari (nel caso non sia capace di capirlo) e dargli istruzioni speciali riguardo a come gestire tali files. Per esempio, alcuni files di testo possono essere generati dalla macchina e non sottomissibili a diff, mentre altri files binari possono essere sottoposti a diff — vedremo come dire a Git cosa è cosa.
295
+
296
+ #### Identificare Files Binari ####
297
+
298
+ Alcuni files assomigliano a files di testo ma per il loro scopo vengono trattati come dati. Per esempio, i progetti Xcode di un Mac contengono un file che termina con `.pbxproj`, che è praticamente un dataset JSON (testo in chiaro nel formato javascript) scritto sul disco dall'IDE che registra i parametri di build e così via. Comunque tecnicamente è un file di testo, essendo tutto codice ASCII, non si vuole però trattarlo come tale perché è in realtà un leggero database — non è possibile eseguire un merge dei contenuti se due persone l'hanno modificato ed i diffs solitamente non sono d'aiuto. Il file è stato creato con lo scopo di essere usato dalla macchina. Infine lo si vuole trattare come un file binario.
299
+
300
+ Per comunicare a Git di trattare tutti i files `pbxproj` come files binari, bisogna aggiungere la riga seguente al file `.gitattributes`:
301
+
302
+ *.pbxproj -crlf -diff
303
+
304
+ Ora Git non proverà più a convertire o sistemare i problemi CRLF; non proverà nemmeno a calcolare o stampare diff per i cambiamenti in questo file quando esegui git show o git diff sul progetto. Nella serie 1.6 di Git è fornita una macro che equivale ad utilizzare `-crlf -diff`:
305
+
306
+ *.pbxproj binary
307
+
308
+ #### Diff di Files Binari ####
309
+
310
+ Nella serie 1.6 di Git, è possibile utilizzare funzionalità degli attributi Git per eseguire effettivamente diff di files binari. Questo può essere fatto comunicando a Git come convertire il file binario in formato testuale che possa essere comparato con un normale diff.
311
+
312
+ ##### Files MS Word #####
313
+
314
+ Visto che questo è un metodo abbastanza figo e non molto conosciuto, lo analizzeremo con qualche esempio. Prima di tutto useremo questa tecnica per risolvere uno dei più fastidiosi problemi conosciuti dall'umanità: version-control per documenti Word. Ognuno sa che Word è il peggiore editor esistente; tuttavia, purtroppo, lo usano tutti. Se vogliamo eseguire il version-control per documenti Word, possiamo inserirli in un repository Git ed eseguire un commit ogni tanto; ma è un metodo così buono? Se eseguiamo `git diff` normalmente, vedremo solamente qualcosa del genere:
315
+
316
+ $ git diff
317
+ diff --git a/chapter1.doc b/chapter1.doc
318
+ index 88839c4..4afcb7c 100644
319
+ Binary files a/chapter1.doc and b/chapter1.doc differ
320
+
321
+ Non possiamo confrontare direttamente due versioni a meno che non si estraggano e le si controlli a mano, giusto? Ne deriva che possiamo farlo meglio utilizzando gli attributi Git. Inseriamo la linea seguente nel file `.gitattributes`:
322
+
323
+ *.doc diff=word
324
+
325
+ Questo comunica a Git che ogni file che corrisponde a questo pattern (.doc) deve utilizzare il filtro "word" nel caso si cerchi di visualizzarne un diff contenente modifiche. Cos'è il filtro "word"? Bisogna impostarlo. Ora configureremo Git per utilizzare il programma `strings` per convertire documenti Word in file di testo leggibili di cui possa fare un diff appropriato:
326
+
327
+ $ git config diff.word.textconv strings
328
+
329
+ Questo comando aggiunge una sezione al file `.git/config` che assomiglia a questa:
330
+
331
+ [diff "word"]
332
+ textconv = strings
333
+
334
+ Nota bene: esistono diversi tipi di files `.doc`. Alcuni utilizzano codifica UTF-16 o altre "codepages" e `strings` non sarà in grado di trovare nulla di utile.
335
+
336
+ Ora Git è al corrente che se prova ad eseguire diff tra i due snapshot, e qualunque dei files termina in `.doc`, deve eseguire questi files tramite il filtro "word", che è definito come il programma `strings`. Questo li rende effettivamente delle simpatiche versioni di testo dei files Word prima di tentare di eseguire il diff.
337
+
338
+ Vediamo ora un esempio. Ho inserito il Capitolo 1 di questo libro all'interno di Git, aggiunto un po' di testo nel paragrafo, e salvato il documento. In seguito ho eseguito `git diff` per vederne i cambiamenti:
339
+
340
+ $ git diff
341
+ diff --git a/chapter1.doc b/chapter1.doc
342
+ index c1c8a0a..b93c9e4 100644
343
+ --- a/chapter1.doc
344
+ +++ b/chapter1.doc
345
+ @@ -8,7 +8,8 @@ re going to cover Version Control Systems (VCS) and Git basics
346
+ re going to cover how to get it and set it up for the first time if you don
347
+ t already have it on your system.
348
+ In Chapter Two we will go over basic Git usage - how to use Git for the 80%
349
+ -s going on, modify stuff and contribute changes. If the book spontaneously
350
+ +s going on, modify stuff and contribute changes. If the book spontaneously
351
+ +Let's see if this works.
352
+
353
+ Git comunica in modo corretto e succinto che è stata aggiunta la stringa "Let’s see if this works", che è corretto. Non è perfetto — aggiunge un mucchio di altre cose alla fine — tuttavia certamente funziona. Se si vuole trovare o scrivere un convertitore Word-to-plain-text che lavori sufficientemente bene, la soluzione sarà incredibilmente efficace. Comunque, `strings` è disponibile per la maggior parte di sistemi Mac e Linux, quindi eseguirlo potrebbe essere una prima prova per molti files binari.
354
+
355
+ ##### OpenDocument Text files #####
356
+
357
+ Lo stesso approccio usato per i file MS Word (`*.doc`) può essere utilizzato per i files di testo Opendocument (`*.odt`) creati da OpenOffice.org.
358
+
359
+ Agiungiamo la seguente riga al file `.gitattributes`:
360
+
361
+ *.odt diff=odt
362
+
363
+ Ora impostiamo il filtro diff `odt` in `.git/config`:
364
+
365
+ [diff "odt"]
366
+ binary = true
367
+ textconv = /usr/local/bin/odt-to-txt
368
+
369
+ I files di tipo OpenDocument sono in effetti cartelle compresse contenenti files (contenuto in formato XML, fogli di stile, immagini...). Bisogna quindi scrivere uno script che estragga il contenuto e lo restituisca come semplice testo. Creiamo un file `/usr/local/bin/odt-to-txt` (o anche in una directory differente) con il seguente contenuto:
370
+
371
+ #! /usr/bin/env perl
372
+ # Simplistic OpenDocument Text (.odt) to plain text converter.
373
+ # Author: Philipp Kempgen
374
+
375
+ if (! defined($ARGV[0])) {
376
+ print STDERR "No filename given!\n";
377
+ print STDERR "Usage: $0 filename\n";
378
+ exit 1;
379
+ }
380
+
381
+ my $content = '';
382
+ open my $fh, '-|', 'unzip', '-qq', '-p', $ARGV[0], 'content.xml' or die $!;
383
+ {
384
+ local $/ = undef; # slurp mode
385
+ $content = <$fh>;
386
+ }
387
+ close $fh;
388
+ $_ = $content;
389
+ s/<text:span\b[^>]*>//g; # remove spans
390
+ s/<text:h\b[^>]*>/\n\n***** /g; # headers
391
+ s/<text:list-item\b[^>]*>\s*<text:p\b[^>]*>/\n -- /g; # list items
392
+ s/<text:list\b[^>]*>/\n\n/g; # lists
393
+ s/<text:p\b[^>]*>/\n /g; # paragraphs
394
+ s/<[^>]+>//g; # remove all XML tags
395
+ s/\n{2,}/\n\n/g; # remove multiple blank lines
396
+ s/\A\n+//; # remove leading blank lines
397
+ print "\n", $_, "\n\n";
398
+
399
+ Rendiamolo eseguibile:
400
+
401
+ chmod +x /usr/local/bin/odt-to-txt
402
+
403
+ Ora `git diff` sarà in grado di comunicare cosa è cambiato nei files `.odt`.
404
+
405
+
406
+ ##### Immagini #####
407
+
408
+ Un altro problema interessante che puoi risolvere in questo modo è eseguire diff di immagini. Un modo per farlo è di elaborare i files PNG tramite un filtro che ne estragga le informazioni EXIF — metadati codificati nella maggior parte dei formati delle immagini. Se scarichiamo ed installiamo il programma `exiftool`, possiamo utilizzarlo per convertire le immagini in testo riguardante i metadati, quindi il diff mostrerà almeno una rappresentazione testuale di cosa è successo:
409
+
410
+ $ echo '*.png diff=exif' >> .gitattributes
411
+ $ git config diff.exif.textconv exiftool
412
+
413
+ Se si rimpiazza un'immagine nel progetto e si esegue `git diff`, si ottiene qualcosa del genere:
414
+
415
+ diff --git a/image.png b/image.png
416
+ index 88839c4..4afcb7c 100644
417
+ --- a/image.png
418
+ +++ b/image.png
419
+ @@ -1,12 +1,12 @@
420
+ ExifTool Version Number : 7.74
421
+ -File Size : 70 kB
422
+ -File Modification Date/Time : 2009:04:17 10:12:35-07:00
423
+ +File Size : 94 kB
424
+ +File Modification Date/Time : 2009:04:21 07:02:43-07:00
425
+ File Type : PNG
426
+ MIME Type : image/png
427
+ -Image Width : 1058
428
+ -Image Height : 889
429
+ +Image Width : 1056
430
+ +Image Height : 827
431
+ Bit Depth : 8
432
+ Color Type : RGB with Alpha
433
+
434
+ Si può semplicemente vedere che la dimensione ed il peso dell'immagine sono entrambe cambiati.
435
+
436
+ ### Keyword Expansion ###
437
+
438
+ Gli sviluppatori abituati a sistemi come CVS o SVN richiedono spesso una keyword expansion tipica di quei sistemi. Il problema maggiore con questo su Git è che non è possibile modificare un file con informazioni per il commit dopo aver eseguito il commit, perché Git esegue prima un check del file. Comunque, è possibile inserire testo all'interno del file quando viene estratto e rimuoverlo prima che venga aggiunto al commit. Gli attributi Git forniscono due modi per farlo.
439
+
440
+ Innanzitutto, è possibile inserire il checksum SHA-1 di una bolla in un campo `$Id$` del file in modo automatico. Se si imposta questo attributo in un file o insieme di files, allora la prossima volta verrà eseguito un check out di quel ramo, Git rimpiazzerà quel campo con lo SHA-1 della bolla. È importante notare che non è lo SHA del commit, ma della bolla stessa:
441
+
442
+ $ echo '*.txt ident' >> .gitattributes
443
+ $ echo '$Id$' > test.txt
444
+
445
+ La prossima volta che eseguiremo un check out di questo file, Git inserirà lo SHA della bolla:
446
+
447
+ $ rm test.txt
448
+ $ git checkout -- test.txt
449
+ $ cat test.txt
450
+ $Id: 42812b7653c7b88933f8a9d6cad0ca16714b9bb3 $
451
+
452
+ Comunque, questo risultato è di utilizzo limitato. Se hai usato la keyword substitution di CVS o Subversion, puoi includere un datastamp — lo SHA non è così utile, perché è un numero praticamente casuale e non puoi sapere se uno SHA sia o meno precedente di un altro.
453
+
454
+ Ne consegue che puoi scrivere i tuoi filtri per eseguire sostituzioni nei commit/checkout dei files. Questi sono i filtri "clean" e "smudge". Nel file `.gitattributes`, puoi impostare un filtro per un percorso particolare e quindi impostare gli scripts che processano files appena prima che ne venga eseguito un checkout ("smudge", vedi Figura 7-2) ed appena prima che ne venga eseguito un commit ("clean", vedi figura 7-3). Questi filtri possono essere impostati per fare tutte queste cose divertenti.
455
+
456
+ Insert 18333fig0702.png
457
+ Figura 7-2. Filtro “smudge” eseguito al checkout.
458
+
459
+ Insert 18333fig0703.png
460
+ Figura 7-3. Filtro “clean” eseguito quando viene fatto lo stage dei files.
461
+
462
+ Il messaggio originale di commit per questa funzionalità fornisce un semplice esempio dell'eseguire tutto il nostro codice C durante il programma `indent` prima del commit. Puoi impostarlo assegnando all'attributo filter in `.gitattributes` il compito di filtrare files `*.c` con il filtro "indent":
463
+
464
+ *.c filter=indent
465
+
466
+ Diciamo poi a Git cosa farà il filtro "indent" in smudge e clean:
467
+
468
+ $ git config --global filter.indent.clean indent
469
+ $ git config --global filter.indent.smudge cat
470
+
471
+ In questo caso, quando verranno fatti commit di files che corrispondono a `*.c`, Git li eseguirà attraverso il programma indent prima di farne commits e quindi passarli al programma `cat` prima di rifarne un check nel disco. Il programma `cat` è praticamente una non-operazione: restituisce gli stessi dati che riceve in ingresso. Questa combinazione effettivamente filtra tutto il codice C tramite `indent` prima del commit.
472
+
473
+ Un altro esempio interessante è la keyword expansion `$Date$`, in stile RCS. Per farlo in modo appropriato, bisogna avere un piccolo script che dato in ingresso il nome di un file ne capisca la data dell'ultimo commit, ed inserisca la data nel file. Ad esempio questo è un piccolo script Ruby che esegue il compito:
474
+
475
+ #! /usr/bin/env ruby
476
+ data = STDIN.read
477
+ last_date = `git log --pretty=format:"%ad" -1`
478
+ puts data.gsub('$Date$', '$Date: ' + last_date.to_s + '$')
479
+
480
+ Lo script preleva la data dell'ultimo commit tramite il comando `git log`, lo allega ad ogni stringa `$Date$` che trova in stdin, stampa il risultato — dovrebbe essere semplice da fare in ogni linguaggio con cui siete pratici. Questo file può essere chiamato `expand_date` ed essere posizionato nel path. Ora bisogna impostare un filtro in Git (chiamato `dater`) e comunicare di utilizzare il filtro `expand_date` per eseguire uno smudge dei files in checkout. Utilizzeremo un'espressione Perl per pulirlo al commit:
481
+
482
+ $ git config filter.dater.smudge expand_date
483
+ $ git config filter.dater.clean 'perl -pe "s/\\\$Date[^\\\$]*\\\$/\\\$Date\\\$/"'
484
+
485
+ Questo frammento di Perl toglie qualsiasi cosa veda nella stringa `$Date$`, per tornare al punto di partenza. Ora che il filtro è pronto, è possibile provarlo costruendo un file con la keyword `$Date$` e quindi impostare un attributo Git per il file che richiami il nuovo filtro:
486
+
487
+ $ echo '# $Date$' > date_test.txt
488
+ $ echo 'date*.txt filter=dater' >> .gitattributes
489
+
490
+ Se esegui un commit per questi cambiamenti e quindi fai un checkout del file, noterai che la keyword è stata sostituita:
491
+
492
+ $ git add date_test.txt .gitattributes
493
+ $ git commit -m "Testing date expansion in Git"
494
+ $ rm date_test.txt
495
+ $ git checkout date_test.txt
496
+ $ cat date_test.txt
497
+ # $Date: Tue Apr 21 07:26:52 2009 -0700$
498
+
499
+ Si può vedere quanto sia potente questa tecnica per applicazioni personalizzate. Bisogna però prestare attenzione, infatti del file `.gitattributes` viene eseguito un commit e viene distribuito insieme al progetto, tuttavia non si può dire la stessa cosa per quanto riguarda il driver (in questo caso, `dater`); quindi non funzionerà ovunque. Quando costruisci questi filtri, dovrebbero essere in grado di non fallire in modo drastico e permettere al progetto di continuare a funzionare in modo appropriato.
500
+
501
+ ### Esportare il Repository ###
502
+
503
+ Gli attributi Git permettono inoltre di attuare operazioni interessanti quando si esporta un archivio del proprio progetto.
504
+
505
+ #### export-ignore ####
506
+
507
+ È possibile comunicare a Git di non esportare alcuni files o directories quando si genera un archivio. Nel caso ci sia una sottodirectory o file che non si vuole includere nell'archivio ma che si vuole comunque tenere nel progetto, è possibile determinare questi files tramite l'attributo `export-ignore`.
508
+
509
+ Per esempio, diciamo di avere dei files per i test in una sottodirectory `test/`, non avrebbe senso includerla in un tarball del progetto. È possibile aggiungere la seguente riga al file Git attributes:
510
+
511
+ test/ export-ignore
512
+
513
+ Ora, quando verrà eseguito git archive per creare la tarball del progetto, la directory non sarà inclusa nell'archivio.
514
+
515
+ #### export-subst ####
516
+
517
+ Un'altra cosa che è possibile fare per gli archivi è qualche semplice keyword substitution. Git permette di inserire la stringa `$Format:$` in ogni file con uno qualsiasi degli shortcodes di formattazione `--pretty=format`, dei quali ne abbiamo visti alcuni nel Capitolo 2. Per esempio, nel caso si voglia includere un file chiamato `LAST_COMMIT` nel progetto, e l'ultima data di commit è stata inserita automaticamente al suo interno all'esecuzione di `git archive`, è possibile impostare il file in questo modo:
518
+
519
+ $ echo 'Last commit date: $Format:%cd$' > LAST_COMMIT
520
+ $ echo "LAST_COMMIT export-subst" >> .gitattributes
521
+ $ git add LAST_COMMIT .gitattributes
522
+ $ git commit -am 'adding LAST_COMMIT file for archives'
523
+
524
+ All'esecuzione di `git archive`, il contenuto del file quando qualcuno aprirà l'archivio sarà di questo tipo:
525
+
526
+ $ cat LAST_COMMIT
527
+ Last commit date: $Format:Tue Apr 21 08:38:48 2009 -0700$
528
+
529
+ ### Strategie di merge ###
530
+
531
+ È possibile inoltre utilizzare attributi Git per comunicare a Git di utilizzare differenti strategie di merge per files specifici nel progetto. Un opzione molto utile è comunicare a Git di non provare ad eseguire merge di files specifici quando sussistono conflitti, ma, invece, di la propria parte di merge sopra quella di qualcun altro.
532
+
533
+ Questo è utile se un ramo nel progetto presenta divergenze o è specializzato, ma si vuole essere in grado di fare merge dei cambiamenti su di esso, e si vogliono ignorare alcuni files. Diciamo di avere un database di opzioni chiamato database.xml che è differente in due rami, e si vuole eseguire un marge nell'altro ramo senza fare confusione all'interno del database. È possibile impostare un attributo in questo modo:
534
+
535
+ database.xml merge=ours
536
+
537
+ Definisci quindi una strategia di merge fittizia chiamata `ours`:
538
+
539
+ git config --global merge.ours.driver true
540
+
541
+ Nel caso si voglia fare un merge nell'altro ramo, invece di avere conflitti di merge con il file database.xml, si noterà qualcosa di simile a:
542
+
543
+ $ git merge topic
544
+ Auto-merging database.xml
545
+ Merge made by recursive.
546
+
547
+ In questo caso, database.xml rimarrà a qualsiasi versione si aveva in origine.
548
+
549
+ ## Git Hooks ##
550
+
551
+ Come in molti altri Version Control Systems, in Git esiste un modo per eseguire alcuni script personalizzati quando si verificano determinate azioni. Questi hooks sono di due tipi: lato client e lato server. Gli hooks lato client sono per operazioni client come commit e merge. Per quanto riguarda gli hooks lato server, sono per operazioni lato server, come ricevere i commits di cui è stato eseguito il push. È possibile utilizzare questi hooks per molte ragioni, ora ne vedremo alcune.
552
+
553
+ ### Configurare un Hook ###
554
+
555
+ Gli hooks sono salvati nella sottodirectory `hooks` all'interno della directory Git. In molti progetti è `.git/hooks`. Di default, Git inserisce in questa directory un mucchio di scripts di esempio, molti di essi sono utili; viene anche documentato l'input per ciascuno script. Tutti gli esempi sono scritti come shell scripts, con un po' di Perl, tuttavia ogni script eseguibile chiamato in modo appropriato andrà bene — è possibile scriverli in Ruby, Python... Per le versioni di Git successive alla 1.6, questi hook di esempio finiscono con .sample; è necessario rinominarli. Per le versioni precedenti alla 1.6 i files hanno nome corretto ma non sono eseguibili.
556
+
557
+ Per abilitare uno script hook, bisogna inserire il file nella sottodirectory `hooks` della directory Git, il file dovrà essere nominato in modo appropriato ed eseguibile. Da questo punto in poi dovrebbe essere chiamato. Vedremo ora i principali nomi di hook.
558
+
559
+ ### Hook sul client ###
560
+
561
+ Esistono molti hooks lato client. In questa sezione li divideremo in committing-workflow hooks, e-mail-workflow scripts, ed i restanti client-side scripts.
562
+
563
+ #### Hook per le commit ####
564
+
565
+ I primi quattro hooks sono correlati con il processo di commit. L'hook `pre-commit` è eseguito per primo, prima che venga richiesto l'inserimento del messaggio di commit. È usato per controllare lo snapshot di cui si vuole eseguire il commit, per vedere se ci si è dimenticati di qualcosa, per assicurarsi che i test funzionino, o per esaminare qualsiasi cosa si voglia nel codice. Se il valore di uscita di questo hook è un non-zero il commit viene annullato, in alternativa può essere bypassato tramite il comando `git commit --no-veriy`. È possibile eseguire operazioni come controllare lo stile del codice (eseguendo lint o qualcosa di simile), cercare whitespace alla fine (l'hook di default fa esattamente questo), cercare documentazione appropriata su nuovi metodi.
566
+
567
+ L'hook `prepare-commit-msg` è eseguito prima che venga invocato il message editor del commit, ma dopo che il messaggio di default sia stato creato. Permette di modificare il messaggio di default prima che l'autore del commit lo veda. Questo hook riceve qualche parametro: il path del file che contiene il messaggio del commit, il tipo di commit, lo SHA-1 del commit nel caso sia un amend commit. Questo hook solitamente non è utile per i commit normali; tuttavia va bene per commit dove il messaggio di default è generato in maniera automatica, come templated commit messages, merge commits, squashed commits ed amend commits. È utilizzabile insieme ad un commit template per inserire informazioni in modo programmato.
568
+
569
+ L'hook `commit-msg` riceve un parametro: il path del file temporaneo contenete il messaggio commit. Se lo script termina con non-zero, Git annulla il procedimento, quindi è possibile utilizzarlo per validare lo stato del progetto o un messaggio del commit prima di consentire al commit di proseguire. Nell'ultima sezione di questo capitolo, Vedremo come verificare che un messaggio del commit sia conforme ad un certo pattern utilizzando un hook.
570
+
571
+ Al termine dell'intero processo di commit, viene eseguito l'hook `post-commit`. Non riceve alcun parametro, tuttavia è possibile recuperare l'ultimo commit semplicemente tramite il comando `git log -1 HEAD`. Solitamente, questo script è utilizzato per notificazioni o simili.
572
+
573
+ Gli script client-side per il committing-workflow possono essere utilizzati in ogni flusso di lavoro. Sono spesso utilizzati per rafforzare alcune norme, è comunque importante notare che questi scripts non sono trasferiti durante un clone. È possibile rafforzare le norme lato server per rifiutare push di commits che non siano conformi a qualche norma, ma è responsabilità dello sviluppatore utilizzare questi script lato client. Quindi, questi sono scripts che aiutano gli sviluppatori, devono essere impostati e mantenuti da loro, possono essere modificati o sovrascritti da loro in ogni momento.
574
+
575
+ #### Hook per le e-mail ####
576
+
577
+ È possibile impostare tre hooks lato client per un flusso di lavoro basato sulle e-mail. Sono tutti invocati dal comando `git am`, quindi se non si utilizza il detto comando, questa sezione può essere tranquillamente saltata. Se si prendono patches via e-mail preparate tramite `git format-patch`, allora alcuni di questi hooks potrebbero risultare utili.
578
+
579
+ Il primo hook che viene eseguito è `applypatch-msg`. Riceve un unico argomento: il nome del file temporaneo che contiene il messaggio di commit proposto. Git annulla la patch nel caso lo script termini con valore d'uscita non-zero. È possibile utilizzare questo hook per assicurarsi che il messaggio di un commit sia formattato in modo appropriato o per normalizzare il messaggio facendolo editare allo script.
580
+
581
+ Il prossimo hook che viene eseguito è `pre-applypatch`. Non riceve argomenti e viene eseguito dopo che la patch viene applicata, quindi è possibile utilizzarlo per esaminare lo snapshot prima di eseguire il commit. È possibile eseguire tests o, in alternativa, esaminare l'albero di lavoro con questo script. Se manca qualcosa o non passano i tests, ritornando non-zero viene annullato `git am` senza che venga eseguito il commit della patch.
582
+
583
+ L'ultimo hook che viene eseguito è `post-applypatch`. È possibile utilizzarlo per notificare ad un gruppo o all'autore della patch che è stato eseguito il pull nel quale si è lavorato. È possibile fermare il patching tramite questo script.
584
+
585
+ #### Altri hook sul client ####
586
+
587
+ L'hook `pre-rebase` viene eseguito prima di un rebase e può fermare il processo ritornando un non-zero. È possibile utilizzare questo hook per negare il rebasing di qualsiasi commit di cui sia stato già effettuato un push. Lo script `pre-rebase` di esempio esegue quanto detto, in alternativa assume che next sia il nome del branch che si vuole pubblicare. Dovresti cambiarlo nel branch stabile.
588
+
589
+ Dopo aver eseguito con successp `git checkout`, viene eseguito l'hook `post-checkout`; è possibile utilizzarlo per configurare in modo appropriato la directory di lavoro per il progetto. Questo potrebbe significare spostare all'interno grossi file binari di cui non si vuole conrollare il codice, generare in modo automatico la documentazione...
590
+
591
+
592
+ Infine, l'hook `post-merge` viene eseguito dopo un comando `merge` terminato con successo. È possibile utilizzarlo per ripristinare informazioni dell'albero che Git non riesce a tracciare (come informazioni di permessi). Questo hook può allo stesso modo validare la presenza di files esterni al controllo di Git che potresti voler copiare all'interno quando l'albero di lavoro cambia.
593
+
594
+ ### Hook sul server ###
595
+
596
+ In aggiunta agli hooks lato client, è possibile utilizzare un paio di hooks lato server come amministrazione di sistema per rafforzare praticamente ogni tipo di norma per il progetto. Questi scripts vengono eseguiti prima e dopo i push verso il server. I pre hooks possono ritornare non-zero in ogni momento per rifiutare il push inviando un messaggio di errore al client; è possibile configurare una politica di push che sia complessa quanto si desidera.
597
+
598
+ #### pre-receive e post-receive ####
599
+
600
+ Il primo script da eseguire nella gestione di un push da client è `pre-receive`. Riceve in ingresso una lista di riferimenti di cui si esegue il push da stdin; se ritorna non-zero, nessuno di essi sarà accettato. È possibile utilizzare questo hook per eseguire azioni come assicurarsi che nessuno dei riferimenti aggiornati sia non-fast-forwards; o di controllare che l'utente esegua il push che ha creato, cancellato,
601
+ The first script to run when handling a push from a client is `pre-receive`. It takes a list of references that are being pushed from stdin; if it exits non-zero, none of them are accepted. You can use this hook to do things like make sure none of the updated references are non-fast-forwards; or to check that the user doing the pushing has create, delete, or push access or access to push updates to all the files they’re modifying with the push.
602
+
603
+ L'hook `post-receive` viene eseguito al termine dell'intero processo, può essere usato per aggiornare altri servizi o notificare agli utenti. Riceve in ingresso gli stessi dati stdin del `pre-receive` hook. Gli esempi includono inviare via mail un elenco, notificare una continua integrazione con il server, aggiornare un sistema ticket-tracking — è possibile anche eseguire un parse dei messaggi commit per vedere se deve essere aperto, chiuso o modificato, qualche ticket. Questo script non può interrompere il processo di push, tuttavia il client non si disconnette fino a che non è completato; quindi, è necessario fare attenzione ogni volta che si cerca di fare qualcosa che potrebbe richiedere lunghi tempi.
604
+ #### update ####
605
+
606
+ Lo script update è molto simile allo script `pre-receive`, a parte per il fatto che è eseguito una volta per ogni branch che chi esegue push stia cercando di aggiornare. Se si vogliono aggiornare molti rami, `pre-receive` viene eseguiro una volta, mentre update viene eseguito una volta per ogni ramo. Invece di leggere informazioni da stdin, questo script contiene tre argomenti: il nome del riferimento (ramo), lo SHA-1 a cui si riferisce all'elemento puntato prima del push, lo SHA-1 di cui l'utente sta cercando di eseguire un push. Nel caso lo script di update ritorni non-zero, solo il riferimento in questione verrà rifiutato; gli altri riferimenti possono comunque essere caricati.