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,1144 @@
1
+ # Strumenti di Git #
2
+
3
+ Finora hai imparato la maggior parte dei comandi d’uso quotidiani e i flussi di lavoro che devi conoscere per gestire o mantenere un repository Git per i tuoi sorgenti. Hai eseguito le attività di base per tracciare e committare i file, hai sfruttato il potere dell' *area di assemblamento* e le diramazioni (*branch*) e le unioni (*merge*) leggere.
4
+
5
+ Ora vedremo una serie di cose molto potenti di Git che potresti non usare quotidianamente, ma di cui a un certo punto potresti averne bisogno.
6
+
7
+ ## Selezione della revisione ##
8
+
9
+ Git ti permette di specificare una o più *commit* in diversi modi. Non sono sempre ovvi, ma è utile conoscerli.
10
+
11
+ ### Singole versioni ###
12
+
13
+ Puoi fare riferimento a una singola commit usando l’hash SHA-1 attribuito, ma ci sono altri metodi più amichevoli per fare riferimento a una *commit*. Questa sezione delinea i modi con cui ci si può riferire a una singolo commit.
14
+
15
+ ### SHA breve ###
16
+
17
+ Git è abbastanza intelligente da capire a quale *commit* ti riferisci se scrivi i primi caratteri purché il codice SHA-1 sia di almeno quattro caratteri e sia univoco: ovvero che uno solo degli oggetti nel *repository* inizi con quel SHA-1.
18
+
19
+ Per vedere per esempio una specifica *commit*, immagina di eseguire 'git log' e trovi la *commit* dove sono state aggiunte determinate funzionalità:
20
+
21
+ $ git log
22
+ commit 734713bc047d87bf7eac9674765ae793478c50d3
23
+ Author: Scott Chacon <schacon@gmail.com>
24
+ Date: Fri Jan 2 18:32:33 2009 -0800
25
+
26
+ fixed refs handling, added gc auto, updated tests
27
+
28
+ commit d921970aadf03b3cf0e71becdaab3147ba71cdef
29
+ Merge: 1c002dd... 35cfb2b...
30
+ Author: Scott Chacon <schacon@gmail.com>
31
+ Date: Thu Dec 11 15:08:43 2008 -0800
32
+
33
+ Merge commit 'phedders/rdocs'
34
+
35
+ commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b
36
+ Author: Scott Chacon <schacon@gmail.com>
37
+ Date: Thu Dec 11 14:58:32 2008 -0800
38
+
39
+ added some blame and merge stuff
40
+
41
+ In questo caso scegli '1c002dd....'. Se vuoi eseguire 'git show' su quella *commit*, i seguenti comandi sono equivalenti (assumendo che le versioni più brevi siano univoche):
42
+
43
+ $ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b
44
+ $ git show 1c002dd4b536e7479f
45
+ $ git show 1c002d
46
+
47
+ Git riesce a capire un valore SHA-1 intero da uno corto, abbreviato. Se usi l’opzione '--abbrev-commit' col comando 'git-log', l'*output* userà valori più corti ma garantirà che siano unici: di default usa sette caratteri ma ne userà di più se sarà necessario per mantenere l’univocità del valore SHA-1:
48
+
49
+ $ git log --abbrev-commit --pretty=oneline
50
+ ca82a6d changed the version number
51
+ 085bb3b removed unnecessary test code
52
+ a11bef0 first commit
53
+
54
+ Da otto a dieci caratteri sono, generalmente, più che sufficienti per essere univoci all'interno di un progetto. Uno dei progetti Git più grandi, il kernel di Linux, inizia a necessitare 12 caratteri, dei 40 possibili, per essere univoco.
55
+
56
+ ### Una breve nota su SHA-1 ###
57
+
58
+ Molte persone si preoccupa che a un certo punto, in modo del tutto casuale, ci possano essere due oggetti nel tuo *repository* che abbiano lo stesso SHA-1. Cosa succederebbe?
59
+
60
+ Se dovessi committare un oggetto che abbia lo stesso hash SHA-1 di un altro oggetto che sia già nel tuo repository, Git troverà l'altro oggetto già nel database di Git e lo considererà già scritto. Se in seguito vorrai scaricare quest'ultimo ogetto, otterrai sempre le informazioni del più vecchio.
61
+
62
+ Dovresti comunque essere consapevole che questo sia uno scenario molto improbabile. Il codice SHA-1 è di 20 bytes o 160 bits. Il numero di oggetti casuali necessari perché ci sia la probabilità del 50% di una singola collisione è di circa 2^80 (la formula per determinare la probabilità di collisione è `p = (n(n-1)/2) * (1/2^160)`). 2^80 è 1.2 x 10^24 ovvero 1 milione di miliardi di miliardi. È 1.200 volte il numero di granelli di sabbia sulla terra.
63
+
64
+ Ecco un esempio per dare un'idea di cosa ci vorrebbe per ottenere una collisione SHA-1. Se tutti i 6.5 miliardi di esseri umani sulla Terra programmassero e, ogni secondo, ognuno scrivesse codice che sia equivalente all'intera cronologia del kernel Linux (1 milione di oggetti Git) e ne facesse la push su un enorme *repository* Git, ci vorrebbero 5 anni per contenere abbastanza oggetti in quel *repository* per avere il 50% di possibilità di una singola collisione di oggetti SHA-1. Esiste una probabilità più alta che ogni membro del tuo gruppo di sviluppo, in incidenti non correlati venga attaccato e ucciso da dei lupi nella stessa notte.
65
+
66
+ ### Riferimenti alle diramazioni ###
67
+
68
+ Il modo più diretto per specificare una *commit* è avere una diramazione (*branch* in inglese) che vi faccia riferimento, che ti permetterebbe di usare il nome della diramazione in qualsiasi comando Git che richieda un oggetto *commit* o un valore SHA-1. Se per esempio vuoi vedere l'ultima *commit* di una diramazione, i comandi seguenti sono equivalenti (supponendo che la diramazione 'topic1' punti a 'ca82a6d'):
69
+
70
+ $ git show ca82a6dff817ec66f44342007202690a93763949
71
+ $ git show topic1
72
+
73
+ Se vuoi vedere a quale SHA specifico punti una diramazione, o se vuoi vedere a quali SHA puntino questi esempi, puoi usare il comando 'rev-parse' di Git, che fa parte dei comandi sottotraccia (*plumbing* in inglese) . Nel Capitolo 9 trovi maggiori informazioni sui comandi sottotraccia ma, brevemente, 'rev-parse' esiste per operazioni di basso livello e non è concepito per essere usato nelle operazioni quotidiane. Può comunque essere d'aiuto quando hai bisogno di vedere cosa sta succedendo davvero. Qui puoi quindi eseguire 'rev-parse' sulla tua diramazione.
74
+
75
+ $ git rev-parse topic1
76
+ ca82a6dff817ec66f44342007202690a93763949
77
+
78
+ ### Nomi brevi dei riferimenti ###
79
+
80
+ Una delle cose che Git fa dietro le quinte è aggiornare il registro dei riferimenti (*reflog* in inglese), che registra la posizione dei tuoi riferimenti HEAD e delle diramazione su cui hai lavorato negli ulti mesi.
81
+
82
+ Puoi consultare il registro con il comando 'git reflog':
83
+
84
+ $ git reflog
85
+ 734713b HEAD@{0}: commit: fixed refs handling, added gc auto, updated
86
+ d921970 HEAD@{1}: merge phedders/rdocs: Merge made by recursive.
87
+ 1c002dd HEAD@{2}: commit: added some blame and merge stuff
88
+ 1c36188 HEAD@{3}: rebase -i (squash): updating HEAD
89
+ 95df984 HEAD@{4}: commit: # This is a combination of two commits.
90
+ 1c36188 HEAD@{5}: rebase -i (squash): updating HEAD
91
+ 7e05da5 HEAD@{6}: rebase -i (pick): updating HEAD
92
+
93
+ Ogni volta che una diramazione viene aggiornata per qualsiasi ragione, Git memorizza questa informazione in questa cronologia temporanea. E puoi anche specificare *commit* più vecchie. Se vuoi vedere la cronologia a partire dalla quintultima commit a partire dalla *HEAD* del tuo *repository*, puoi usare il riferimento '@{n}' che vedi nel *output* del registro:
94
+
95
+ $ git show HEAD@{5}
96
+
97
+ Puoi anche usare questa sintassi per vedere dov'era una diramazione a una certa data. Se vuoi vedere, per esempio, dov'era ieri la diramazione 'master' puoi scrivere:
98
+
99
+ $ git show master@{yesterday}
100
+
101
+ Che mostra dov'era ieri la diramazione. Questa tecnica funziona solo per i dati che sono ancora nel registri e non puoi quindi usarla per vedere *commit* più vecchie di qualche mese.
102
+
103
+ Per vedere le informazioni del registro formattate come l’output di `git log`, puoi eseguire il comando `git log -g`:
104
+
105
+ $ git log -g master
106
+ commit 734713bc047d87bf7eac9674765ae793478c50d3
107
+ Reflog: master@{0} (Scott Chacon <schacon@gmail.com>)
108
+ Reflog message: commit: fixed refs handling, added gc auto, updated
109
+ Author: Scott Chacon <schacon@gmail.com>
110
+ Date: Fri Jan 2 18:32:33 2009 -0800
111
+
112
+ fixed refs handling, added gc auto, updated tests
113
+
114
+ commit d921970aadf03b3cf0e71becdaab3147ba71cdef
115
+ Reflog: master@{1} (Scott Chacon <schacon@gmail.com>)
116
+ Reflog message: merge phedders/rdocs: Merge made by recursive.
117
+ Author: Scott Chacon <schacon@gmail.com>
118
+ Date: Thu Dec 11 15:08:43 2008 -0800
119
+
120
+ Merge commit 'phedders/rdocs'
121
+
122
+ E' importante notare che l'informazione del registro è solamente locale: è un registro di ciò che hai fatto nel tuo *repository*. I riferimenti non saranno uguali sui cloni degli altri. Appena dopo aver clonato un *repository* il tuo registro sarà vuoto perché non è successo ancora nulla nel tuo *repository*. Potrai eseguire 'git show HEAD@{2.months.ago}' solo se hai clonato il progetto almeno due mesi fa: se è stato clonato cinque minuti fa non otterrai nessun risultato.
123
+
124
+ ### Riferimenti ancestrali ###
125
+
126
+ L'altro modo principale per specificare una *commit* è attraverso i suoi ascendenti. Se metti un `^` alla fine di un riferimento, Git lo risolve interpretandolo come il padre padre di quella determinata *commit*.
127
+ Immagina di vedere la cronologia del tuo progetto:
128
+
129
+ $ git log --pretty=format:'%h %s' --graph
130
+ * 734713b fixed refs handling, added gc auto, updated tests
131
+ * d921970 Merge commit 'phedders/rdocs'
132
+ |\
133
+ | * 35cfb2b Some rdoc changes
134
+ * | 1c002dd added some blame and merge stuff
135
+ |/
136
+ * 1c36188 ignore *.gem
137
+ * 9b29157 add open3_detach to gemspec file list
138
+
139
+ Puoi quindi vedere la *commit* precedente specificando `HEAD^`, che significa "l'ascendente di HEAD":
140
+
141
+ $ git show HEAD^
142
+ commit d921970aadf03b3cf0e71becdaab3147ba71cdef
143
+ Merge: 1c002dd... 35cfb2b...
144
+ Author: Scott Chacon <schacon@gmail.com>
145
+ Date: Thu Dec 11 15:08:43 2008 -0800
146
+
147
+ Merge commit 'phedders/rdocs'
148
+
149
+ Puoi specificare anche un numero dopo la `^`: per esempio `d921970^2` significa "il secondo ascendente di d921870." Questa sintassi è utile solo per incorporare delle *commit* che hanno più di un ascendente. Il primo ascendente è la diramazione dove ti trovi al momento dell'incorporamento, e il secondo è la *commit* sulla diramazione da cui hai fatto l'incorporamento:
150
+
151
+ $ git show d921970^
152
+ commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b
153
+ Author: Scott Chacon <schacon@gmail.com>
154
+ Date: Thu Dec 11 14:58:32 2008 -0800
155
+
156
+ added some blame and merge stuff
157
+
158
+ $ git show d921970^2
159
+ commit 35cfb2b795a55793d7cc56a6cc2060b4bb732548
160
+ Author: Paul Hedderly <paul+git@mjr.org>
161
+ Date: Wed Dec 10 22:22:03 2008 +0000
162
+
163
+ Some rdoc changes
164
+
165
+ Un altro modo di specificare un riferimento ancestrale è la `~`. Questo si riferisce anche al primo ascendente, quindi `HEAD~` e `HEAD^` sono equivalenti. La differenza diventa evidente quando specifichi un numero. `HEAD~2` significa "il primo ascendente del primo ascendente", o "il nonno”: attraversa i primi ascendenti il numero di volte specificato. Per esempio, nella cronologia precedente, `HEAD~3` sarebbe
166
+
167
+ $ git show HEAD~3
168
+ commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d
169
+ Author: Tom Preston-Werner <tom@mojombo.com>
170
+ Date: Fri Nov 7 13:47:59 2008 -0500
171
+
172
+ ignore *.gem
173
+
174
+ Che può essere scritto anche come `HEAD^^^` che, di nuovo, è sempre il primo genitore del primo genitore del primo genitore:
175
+
176
+ $ git show HEAD^^^
177
+ commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d
178
+ Author: Tom Preston-Werner <tom@mojombo.com>
179
+ Date: Fri Nov 7 13:47:59 2008 -0500
180
+
181
+ ignore *.gem
182
+
183
+ È anche possibile combinare queste sintassi: puoi prendere il secondo genitore del riferimento precedente (assumendo che si tratti di una commit d'incorporamento) usando `HEAD~3^2`, e così via.
184
+
185
+ ### Intervalli di commit ###
186
+
187
+ Ora che sai come specificare singole commit, vediamo come specificare intervalli di commit. Ciò è particolarmente utile per gestire le tue diramazioni: se ne hai molte puoi usare gli intervalli per rispondere a domande come “cosa c’è in questa diramazione che non ho ancora incorporato?”
188
+
189
+ #### Due punti ####
190
+
191
+ Il modo più comune per specificare un intervallo è con i due punti che, praticamente, chiede a Git di risolvere l’intervallo tra commit che sia raggiungibile da una commit, ma non dall’altra. Immaginiamo di avere la cronologia dell’immagine 6-1
192
+
193
+ Insert 18333fig0601.png
194
+ Figure 6-1. Esempio di cronologia per la selezione di intervalli.
195
+
196
+ Vuoi vedere cosa sia nella tua diramazione sperimentale che non sia ancora stato incorporato nella master: puoi chiedere a Git di mostrarti solo il registro delle commit con `master..experiment`: questo significa “tutte le commit raggiungibili da experiment che non lo siano da master”. Affinché questi esempi siano sintetici ma chiari, invece del registro effettivo di Git, userò le lettere degli oggetti commit del diagramma:
197
+
198
+ $ git log master..experiment
199
+ D
200
+ C
201
+
202
+ Se volessi invece vedere il contrario, ovvero tutte le commit in `master` che non siano in `experiment`, puoi invertire i nomi dei branch: `experiment..master` ti mostra tutto ciò che è in `master` e che non sia raggiungibile da `experiment`:
203
+
204
+ $ git log experiment..master
205
+ F
206
+ E
207
+
208
+ Questo è utile se vuoi mantenere aggiornata la diramazione `experiment` e sapere cosa stai per incorporare. Un’altro caso in cui si usa spesso questa sintassi è quando stai per condividere delle commit verso un repository remoto:
209
+
210
+ $ git log origin/master..HEAD
211
+
212
+ Questo comando mostra tutte le commit della tua diramazione che non sono in quella `master` del tuo repository remoto `origin`. Se esegui `git push` quando la tua diramazione attuale è associata a `origin/master`, le commit elencate da `git log origin/master..HEAD` saranno quelle che saranno inviate al server.
213
+ Puoi anche omettere una delle parti della sintassi, e Git assumerà che sia HEAD. Per esempio puoi ottenere lo stesso risultato dell’esempio precedente scrivendo `git log origin/master..`: Git sostituisce la parte mancante con HEAD.
214
+
215
+ #### Punti multipli ####
216
+
217
+ La sintassi dei due punti è utile come la stenografia, ma potresti voler specificare più di due branch per indicare la tua revisione, per vedere le commit che sono nelle varie diramazioni che non siano in quella attuale. Git ti permette di farlo sia con `^` che con l’opzione `--not` prima di ciascun riferimento del quale vuoi vedere le commit raggiungibili. Quindi questi tre comandi sono equivalenti:
218
+
219
+ $ git log refA..refB
220
+ $ git log ^refA refB
221
+ $ git log refB --not refA
222
+
223
+ Questo è interessante, perché con questa sintassi puoi specificare più di due riferimenti nella tua richiesta, cosa che non puoi fare con i due punti. Se per esempio vuoi vedere tutte le commit che siano raggiungibili da `refA` o da `refB` ma non da `refC` puoi usare una delle seguenti alternative:
224
+
225
+ $ git log refA refB ^refC
226
+ $ git log refA refB --not refC
227
+
228
+ Questo produce un sistema di revisione molto potente che dovrebbe aiutarti a capire cosa c’è nelle tue diramazioni.
229
+
230
+ #### Tre punti ####
231
+
232
+ L’ultima sintassi per la selezione di intervalli è quella dei tre punti, che indica tutte le commit raggiungibili da uno qualsiasi dei riferimenti ma non da entrambi. Rivedi la cronologia delle commit nella Figura 6-1.
233
+ Se vuoi vedere cosa ci sia nel `master` o in `experiment` ma non i riferimenti comuni, puoi eseguire
234
+
235
+ $ git log master...experiment
236
+ F
237
+ E
238
+ D
239
+ C
240
+
241
+ Che ti mostra l’output normale del `log` mostrando solo le informazioni di quelle quattro commit nell'ordinamento cronologico normale.
242
+
243
+ Un'opzione comunemente usata in questi casi con il comando `log` è il parametro `--left-right`, che mostra da che lato dell'intervallo si trovi ciascuna commit dell’intervallo selezionato, che rende le informazioni molto più utili:
244
+
245
+ $ git log --left-right master...experiment
246
+ < F
247
+ < E
248
+ > D
249
+ > C
250
+
251
+ Con questi strumenti puoi dire facilmente a Git quale o quali commit vuoi ispezionare.
252
+
253
+ ## Assemblaggio interattivo ##
254
+
255
+ Git viene distribuito con un paio di script che rendono più semplice l'uso della riga di comando. In questo capitolo vedremo alcuni comandi interattivi che possono aiutarti a modellare le tue commit perché includano solo determinate combinazioni di parti dei file. Questi strumenti sono molto utili se modifichi molti file tutti assieme e poi decidi che vuoi distribuire le modifiche in più commit puntuali, piuttosto che un'unica grossa commit confusa. In questo modo puoi fare che le tue commit separino logicamente le tue modifiche e possano essere facilmente revisionate dagli altri sviluppatori con cui lavori.
256
+ Se esegui `git add` con le opzioni `-i` o `--interactive`, Git entrerà nella modalità interattiva, mostrandoti qualcosa del genere:
257
+
258
+ $ git add -i
259
+ staged unstaged path
260
+ 1: unchanged +0/-1 TODO
261
+ 2: unchanged +1/-1 index.html
262
+ 3: unchanged +5/-1 lib/simplegit.rb
263
+
264
+ *** Commands ***
265
+ 1: status 2: update 3: revert 4: add untracked
266
+ 5: patch 6: diff 7: quit 8: help
267
+ What now>
268
+
269
+ Come vedi, questo comando mostra una vista della tua area di assemblaggio molto diversa: sono le stesse informazioni che otterà con il comando `git status`, ma in maniera più succinta e con più informazioni. Sulla sinistra mostra le modifiche che stai assemblando e quelle non ancora assemblate sulla destra.
270
+
271
+ Dopo questa sezione c'è quella dei Comandi. Qui puoi fare una serie di cose, incluso assemblare file, disassemblarli, assemblare alcune parti dei file, aggiungere file non ancora tracciati e vedere le differenze con ciò che è già stato assemblato.
272
+
273
+ ### Assemblare e disassemblare file ###
274
+
275
+ Se digiti `2` o `u` alla richiesta `What now>`, lo script ti chiederà quale file vuoi assemblare:
276
+
277
+ What now> 2
278
+ staged unstaged path
279
+ 1: unchanged +0/-1 TODO
280
+ 2: unchanged +1/-1 index.html
281
+ 3: unchanged +5/-1 lib/simplegit.rb
282
+ Update>>
283
+
284
+ Per assemblare i file TODO e index.html, puoi digitare i numeri:
285
+
286
+ Update>> 1,2
287
+ staged unstaged path
288
+ * 1: unchanged +0/-1 TODO
289
+ * 2: unchanged +1/-1 index.html
290
+ 3: unchanged +5/-1 lib/simplegit.rb
291
+ Update>>
292
+
293
+ L'asterisco (`*`) vicino a ogni file, significa che è stato selezionato per essere assemblato. Se premi INVIO alla richiesta `Update>>`, Git assembla tutto ciò che è stato selezionato:
294
+
295
+ Update>>
296
+ updated 2 paths
297
+
298
+ *** Commands ***
299
+ 1: status 2: update 3: revert 4: add untracked
300
+ 5: patch 6: diff 7: quit 8: help
301
+ What now> 1
302
+ staged unstaged path
303
+ 1: +0/-1 nothing TODO
304
+ 2: +1/-1 nothing index.html
305
+ 3: unchanged +5/-1 lib/simplegit.rb
306
+
307
+ Ora puoi vedere che i file TODO e index.html sono assemblati e simplegit.rb non lo è ancora. Se ora vuoi disassemblare il file TODO, devi digitare `3` o `r` (come `revert` - annullare):
308
+
309
+ *** Commands ***
310
+ 1: status 2: update 3: revert 4: add untracked
311
+ 5: patch 6: diff 7: quit 8: help
312
+ What now> 3
313
+ staged unstaged path
314
+ 1: +0/-1 nothing TODO
315
+ 2: +1/-1 nothing index.html
316
+ 3: unchanged +5/-1 lib/simplegit.rb
317
+ Revert>> 1
318
+ staged unstaged path
319
+ * 1: +0/-1 nothing TODO
320
+ 2: +1/-1 nothing index.html
321
+ 3: unchanged +5/-1 lib/simplegit.rb
322
+ Revert>> [enter]
323
+ reverted one path
324
+
325
+ Rivedendo lo stato di Git, puoi vedere che hai disassemblato il file TODO:
326
+
327
+ *** Commands ***
328
+ 1: status 2: update 3: revert 4: add untracked
329
+ 5: patch 6: diff 7: quit 8: help
330
+ What now> 1
331
+ staged unstaged path
332
+ 1: unchanged +0/-1 TODO
333
+ 2: +1/-1 nothing index.html
334
+ 3: unchanged +5/-1 lib/simplegit.rb
335
+
336
+ Per vedere le differenze di ciò che hai assemblato puoi digitare `6` o `d` (come differenza). Ti mostrerà un elenco dei tuoi file assemblati, e potrai selezionare quelli di cui vuoi vedere le modifiche assemblate. Questo fa la stessa cosa del comando `git diff --cached`:
337
+
338
+ *** Commands ***
339
+ 1: status 2: update 3: revert 4: add untracked
340
+ 5: patch 6: diff 7: quit 8: help
341
+ What now> 6
342
+ staged unstaged path
343
+ 1: +1/-1 nothing index.html
344
+ Review diff>> 1
345
+ diff --git a/index.html b/index.html
346
+ index 4d07108..4335f49 100644
347
+ --- a/index.html
348
+ +++ b/index.html
349
+ @@ -16,7 +16,7 @@ Date Finder
350
+
351
+ <p id="out">...</p>
352
+
353
+ -<div id="footer">contact : support@github.com</div>
354
+ +<div id="footer">contact : email.support@github.com</div>
355
+
356
+ <script type="text/javascript">
357
+
358
+ Con questi comandi elementari puoi usare la modalità interattiva per interaggire un po' più facilmente con l'area di assemblagio.
359
+
360
+ ### Assemblare i pezzi ###
361
+
362
+ Git può anche assemblare solo alcune parti di un file e non il resto. Se per esempio fai due modifiche al tuo simplegit.rb file e vuoi assemblarne solo una, con Git puoi farlo molto semplicemente. Al `prompt` digita `5` o `p` (come pezzo, `patch` ndt). Git ti chiederà quali file vuoi assemblare parzialmente e, per ciascuna sezione dei file selezionati, mostrerà blocchi di differenze chiedendoti se vuoi assemblarle, una per una:
363
+
364
+ diff --git a/lib/simplegit.rb b/lib/simplegit.rb
365
+ index dd5ecc4..57399e0 100644
366
+ --- a/lib/simplegit.rb
367
+ +++ b/lib/simplegit.rb
368
+ @@ -22,7 +22,7 @@ class SimpleGit
369
+ end
370
+
371
+ def log(treeish = 'master')
372
+ - command("git log -n 25 #{treeish}")
373
+ + command("git log -n 30 #{treeish}")
374
+ end
375
+
376
+ def blame(path)
377
+ Stage this hunk [y,n,a,d,/,j,J,g,e,?]?
378
+
379
+ A questo punto hai molte opzioni. Digitando `?` vedrai la lista di ciò che puoi fare:
380
+
381
+ Assemblare questo blocco [y,n,a,d,/,j,J,g,e,?]? ?
382
+ y - assembla questo blocco
383
+ n - non assemblare questo blocco
384
+ a - assembla questo blocco e tutti gli altri rimanenti nel file
385
+ d - non assemblare questo blocco né gli altri rimanenti nel file
386
+ g - seleziona un blocco per continuare
387
+ / - cerca un blocco con una regex
388
+ j - salta questo blocco e vedi il successivo saltato
389
+ J - salta questo blocco e vedi il prossimo blocco
390
+ k - salta questo blocco e vedi il precedente saltato
391
+ K - salta questo blocco e vedi il blocco precedente
392
+ s - dividi il blocco attuale in blocchi più piccoli
393
+ e - modifica manualmente il blocco attuale
394
+ ? - mostra l'aiuto
395
+
396
+ Generalmente digiterai `y` o `n` se vuoi assemblare tutti i blocchi, ma assemblare tutti quelli di un file o saltarne qualcuno per decidere in un secondo momento può essere molto prezioso. Se assembli solo alcuni blocchi di un file ma non gli altri, lo stato del tuo repository sarà così:
397
+
398
+ What now> 1
399
+ staged unstaged path
400
+ 1: unchanged +0/-1 TODO
401
+ 2: +1/-1 nothing index.html
402
+ 3: +1/-1 +4/-0 lib/simplegit.rb
403
+
404
+ È interessante lo stato di simplegit.rb, dove alcune righe sono assemblate ma non le altre. Hai assemblato parzialmente questo file. A questo punto puoi uscire dall'area interattiva ed eseguire `git commit` per committare la parte di file assemblata.
405
+
406
+ Non devi essere nell'area interattiva per assemblare solo una parte di un file: puoi avviare lo stesso script dalla riga di comando con `git add -p` o `git add --patch`.
407
+
408
+ ## Accantonare ##
409
+
410
+ Spesso, mentre stai lavorando ad una parte del tuo progetto, le cose possono essere in uno stato confusionario e tu vuoi passare a un'altra ramificazione per lavorare per un po' a qualcosa di diverso. Il problema è che non vuoi committare qualcosa fatta a metà per poi tornarci in un secondo momento. La risposta a questo problema è il comando `git stash`.
411
+
412
+ Questo comando prende tutte le modifiche della tua cartella di lavoro — cioè tutti i file tracciati che hai modificato e le modifiche assemblate — e le accantona in una pila di modifiche incomplete che puoi riapplicare in qualsiasi momento.
413
+
414
+ ### Accantona il tuo lavoro ###
415
+
416
+ Per dimostrare come funziona, vai nella cartella del tuo progetto e modifica un paio di file e assemblane alcuni. Se esegui `git status`, puoi vederne lo stato "sporco":
417
+
418
+ $ git status
419
+ # On branch master
420
+ # Changes to be committed:
421
+ # (use "git reset HEAD <file>..." to unstage)
422
+ #
423
+ # modified: index.html
424
+ #
425
+ # Changes not staged for commit:
426
+ # (use "git add <file>..." to update what will be committed)
427
+ #
428
+ # modified: lib/simplegit.rb
429
+ #
430
+
431
+ Ora vuoi passare a un'altra diramazione, ma non vuoi ancora committare il tuo lavoro perché non è ancora pronto; accantona quindi le tue modifiche. Per aggiungere un nuovo livello alla pila devi eseguire `git stash`:
432
+
433
+ $ git stash
434
+ Saved working directory and index state \
435
+ "WIP on master: 049d078 added the index file"
436
+ HEAD is now at 049d078 added the index file
437
+ (To restore them type "git stash apply")
438
+
439
+ La tua cartella di lavoro ora è pulita:
440
+
441
+ $ git status
442
+ # On branch master
443
+ nothing to commit, working directory clean
444
+
445
+ A questo punto puoi passare facilmente a un'altra diramazione e lavorare ad altro; le tue modifiche sono salvate nella tua pila di accantonamento. Per vedere cosa c'è nella tua pila usa `git stash list`:
446
+
447
+ $ git stash list
448
+ stash@{0}: WIP on master: 049d078 added the index file
449
+ stash@{1}: WIP on master: c264051 Revert "added file_size"
450
+ stash@{2}: WIP on master: 21d80a5 added number to log
451
+
452
+ In questo caso hai due accantonamenti precedenti, e hai così accesso a tre lavori differenti accantonati. Puoi riapplicare quello che hai appena accantonato usando il comando mostrato nell'output d'aiuto del comando che hai usato quanto hai accantonato le tue modifiche: `git stash apply`. Se vuoi applicare uno degli accantonamenti precedenti, puoi specificarlo usandone il nome così: `git stash apply stash@{2}`. Se non specifiche un accantonamento Git suppone che ti riferisca all'ultimo e prova ad applicarlo:
453
+
454
+ $ git stash apply
455
+ # On branch master
456
+ # Changes not staged for commit:
457
+ # (use "git add <file>..." to update what will be committed)
458
+ #
459
+ # modified: index.html
460
+ # modified: lib/simplegit.rb
461
+ #
462
+
463
+ Puoi vedere che Git ha rimodificato i file che aveva rimosso quando hai salvato l'accantonamento. In questo caso avevi una cartella di lavoro pulita quando provasti ad applicare l'accantonamento e stai provando a riappricarlo alla stessa ramificazione da cui l'avevi salvato; ma non è necessario avere una cartella pulita per applicare un accantonamento né che sia la stessa ramificazione. Puoi salvare un accantonamento da una ramificazione, passare a un'altra e applicare le modifiche accantonate. Nella tua cartella puoi anche avere modifiche non ancora committate quando applichi un accantonamento: Git ti darà un conflitto d'incorporamento nel caso che qualcosa non si possa applicare senza problemi.
464
+
465
+ Le modifiche vengono riapplicate ai tuoi file, ma quello che avevi assemblato ora non lo sono. Per farlo devi eseguire il comando `git stash apply` con il parametro `--index` perché provi a riapplicare le modifiche assemblate. Se lo avessi fatto ti saresti trovato nella stessa posizione originale:
466
+
467
+ $ git stash apply --index
468
+ # On branch master
469
+ # Changes to be committed:
470
+ # (use "git reset HEAD <file>..." to unstage)
471
+ #
472
+ # modified: index.html
473
+ #
474
+ # Changes not staged for commit:
475
+ # (use "git add <file>..." to update what will be committed)
476
+ #
477
+ # modified: lib/simplegit.rb
478
+ #
479
+
480
+ L'opzione `apply` prova solo ad applicare le modifiche assemblate: continua per averle nel tuo accantonamento. Per cancellare l'accantonamento devi eseguire `git stash drop` con il nome dell'accantonamento da rimuovere:
481
+
482
+ $ git stash list
483
+ stash@{0}: WIP on master: 049d078 added the index file
484
+ stash@{1}: WIP on master: c264051 Revert "added file_size"
485
+ stash@{2}: WIP on master: 21d80a5 added number to log
486
+ $ git stash drop stash@{0}
487
+ Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43)
488
+
489
+ Puoi eseguire anche `git stash pop` per applicare l'accantonamento e cancellare immediatamente dopo.
490
+
491
+ ### Annullare una modifica accantonata ###
492
+
493
+ In alcuni scenari potresti voler applicare delle modifiche accantonate, fare dell'altro lavoro e successivamente voler rimuovere le modifiche che venivano dall'accantonamento. Git non ha un comando `stash unapply`, ma è possibile ottenere lo stesso risultato richiamando la modifica associata all'accantonamento e applicarla al contrario:
494
+
495
+ $ git stash show -p stash@{0} | git apply -R
496
+
497
+ Di nuovo, se non specifichi un accantonamento, Git assume che sia l'ultimo:
498
+
499
+ $ git stash show -p | git apply -R
500
+
501
+ Puoi voler creare un alias per avere un comando `stash-unapply` nel tuo Git. Per esempio:
502
+
503
+ $ git config --global alias.stash-unapply '!git stash show -p | git apply -R'
504
+ $ git stash apply
505
+ $ #... work work work
506
+ $ git stash-unapply
507
+
508
+ ### Creare una diramazione da un accantonamento ###
509
+
510
+ Se accantoni del lavoro e lo lasci lì mentre continui a lavorare per un po' nella diramazione da cui hai creato l'accantonamento, potresti avere dei problemi a riapplicarlo. Se l'applicazione prova a modificare un file che avevi modificato successivamente, otterrai un conflitto d'incorporazione e dovrai risolverlo. Se vuoi un modo facile per ritestare le modifiche accantonate, puoi eseguire il comando `git stash branch`, che crea una diramazione, scarica la commit dov'eri quando hai accantonato il tuo lavoro, lo riapplica e, se ci riesce senza problemi, cancella l'accantonamento:
511
+
512
+ $ git stash branch testchanges
513
+ Switched to a new branch "testchanges"
514
+ # On branch testchanges
515
+ # Changes to be committed:
516
+ # (use "git reset HEAD <file>..." to unstage)
517
+ #
518
+ # modified: index.html
519
+ #
520
+ # Changes not staged for commit:
521
+ # (use "git add <file>..." to update what will be committed)
522
+ #
523
+ # modified: lib/simplegit.rb
524
+ #
525
+ Dropped refs/stash@{0} (f0dfc4d5dc332d1cee34a634182e168c4efc3359)
526
+
527
+ Questa è una bella accorciatoioa per recuperare il lavoro accantonato e lavorarci in una nuova diramazione.
528
+
529
+ ## Riscrivere la storia ##
530
+
531
+ Molto spesso, lavorando con Git, you may want to revise your commit history for some reason. One of the great things about Git is that it allows you to make decisions at the last possible moment. You can decide what files go into which commits right before you commit with the staging area, you can decide that you didn’t mean to be working on something yet with the stash command, and you can rewrite commits that already happened so they look like they happened in a different way. This can involve changing the order of the commits, changing messages or modifying files in a commit, squashing together or splitting apart commits, or removing commits entirely — all before you share your work with others.
532
+
533
+ In this section, you’ll cover how to accomplish these very useful tasks so that you can make your commit history look the way you want before you share it with others.
534
+ <!-- da tradurre fino a riga 840 -->
535
+ ### Changing the Last Commit ###
536
+
537
+ Changing your last commit is probably the most common rewriting of history that you’ll do. You’ll often want to do two basic things to your last commit: change the commit message, or change the snapshot you just recorded by adding, changing and removing files.
538
+
539
+ If you only want to modify your last commit message, it’s very simple:
540
+
541
+ $ git commit --amend
542
+
543
+ That drops you into your text editor, which has your last commit message in it, ready for you to modify the message. When you save and close the editor, the editor writes a new commit containing that message and makes it your new last commit.
544
+
545
+ If you’ve committed and then you want to change the snapshot you committed by adding or changing files, possibly because you forgot to add a newly created file when you originally committed, the process works basically the same way. You stage the changes you want by editing a file and running `git add` on it or `git rm` to a tracked file, and the subsequent `git commit --amend` takes your current staging area and makes it the snapshot for the new commit.
546
+
547
+ You need to be careful with this technique because amending changes the SHA-1 of the commit. It’s like a very small rebase — don’t amend your last commit if you’ve already pushed it.
548
+
549
+ ### Changing Multiple Commit Messages ###
550
+
551
+ To modify a commit that is farther back in your history, you must move to more complex tools. Git doesn’t have a modify-history tool, but you can use the rebase tool to rebase a series of commits onto the HEAD they were originally based on instead of moving them to another one. With the interactive rebase tool, you can then stop after each commit you want to modify and change the message, add files, or do whatever you wish. You can run rebase interactively by adding the `-i` option to `git rebase`. You must indicate how far back you want to rewrite commits by telling the command which commit to rebase onto.
552
+
553
+ For example, if you want to change the last three commit messages, or any of the commit messages in that group, you supply as an argument to `git rebase -i` the parent of the last commit you want to edit, which is `HEAD~2^` or `HEAD~3`. It may be easier to remember the `~3` because you’re trying to edit the last three commits; but keep in mind that you’re actually designating four commits ago, the parent of the last commit you want to edit:
554
+
555
+ $ git rebase -i HEAD~3
556
+
557
+ Remember again that this is a rebasing command — every commit included in the range `HEAD~3..HEAD` will be rewritten, whether you change the message or not. Don’t include any commit you’ve already pushed to a central server — doing so will confuse other developers by providing an alternate version of the same change.
558
+
559
+ Running this command gives you a list of commits in your text editor that looks something like this:
560
+
561
+ pick f7f3f6d changed my name a bit
562
+ pick 310154e updated README formatting and added blame
563
+ pick a5f4a0d added cat-file
564
+
565
+ # Rebase 710f0f8..a5f4a0d onto 710f0f8
566
+ #
567
+ # Commands:
568
+ # p, pick = use commit
569
+ # r, reword = use commit, but edit the commit message
570
+ # e, edit = use commit, but stop for amending
571
+ # s, squash = use commit, but meld into previous commit
572
+ # f, fixup = like "squash", but discard this commit's log message
573
+ # x, exec = run command (the rest of the line) using shell
574
+ #
575
+ # These lines can be re-ordered; they are executed from top to bottom.
576
+ #
577
+ # If you remove a line here THAT COMMIT WILL BE LOST.
578
+ #
579
+ # However, if you remove everything, the rebase will be aborted.
580
+ #
581
+ # Note that empty commits are commented out
582
+
583
+ It’s important to note that these commits are listed in the opposite order than you normally see them using the `log` command. If you run a `log`, you see something like this:
584
+
585
+ $ git log --pretty=format:"%h %s" HEAD~3..HEAD
586
+ a5f4a0d added cat-file
587
+ 310154e updated README formatting and added blame
588
+ f7f3f6d changed my name a bit
589
+
590
+ Notice the reverse order. The interactive rebase gives you a script that it’s going to run. It will start at the commit you specify on the command line (`HEAD~3`) and replay the changes introduced in each of these commits from top to bottom. It lists the oldest at the top, rather than the newest, because that’s the first one it will replay.
591
+
592
+ You need to edit the script so that it stops at the commit you want to edit. To do so, change the word pick to the word edit for each of the commits you want the script to stop after. For example, to modify only the third commit message, you change the file to look like this:
593
+
594
+ edit f7f3f6d changed my name a bit
595
+ pick 310154e updated README formatting and added blame
596
+ pick a5f4a0d added cat-file
597
+
598
+ When you save and exit the editor, Git rewinds you back to the last commit in that list and drops you on the command line with the following message:
599
+
600
+ <!-- This is actually weird, as the SHA-1 of 7482e0d is not present in the list,
601
+ nor is the commit message. Please review
602
+ -->
603
+
604
+ $ git rebase -i HEAD~3
605
+ Stopped at 7482e0d... updated the gemspec to hopefully work better
606
+ You can amend the commit now, with
607
+
608
+ git commit --amend
609
+
610
+ Once you’re satisfied with your changes, run
611
+
612
+ git rebase --continue
613
+
614
+ These instructions tell you exactly what to do. Type
615
+
616
+ $ git commit --amend
617
+
618
+ Change the commit message, and exit the editor. Then, run
619
+
620
+ $ git rebase --continue
621
+
622
+ This command will apply the other two commits automatically, and then you’re done. If you change pick to edit on more lines, you can repeat these steps for each commit you change to edit. Each time, Git will stop, let you amend the commit, and continue when you’re finished.
623
+
624
+ ### Reordering Commits ###
625
+
626
+ You can also use interactive rebases to reorder or remove commits entirely. If you want to remove the "added cat-file" commit and change the order in which the other two commits are introduced, you can change the rebase script from this
627
+
628
+ pick f7f3f6d changed my name a bit
629
+ pick 310154e updated README formatting and added blame
630
+ pick a5f4a0d added cat-file
631
+
632
+ to this:
633
+
634
+ pick 310154e updated README formatting and added blame
635
+ pick f7f3f6d changed my name a bit
636
+
637
+ When you save and exit the editor, Git rewinds your branch to the parent of these commits, applies `310154e` and then `f7f3f6d`, and then stops. You effectively change the order of those commits and remove the "added cat-file" commit completely.
638
+
639
+ ### Squashing Commits ###
640
+
641
+ It’s also possible to take a series of commits and squash them down into a single commit with the interactive rebasing tool. The script puts helpful instructions in the rebase message:
642
+
643
+ #
644
+ # Commands:
645
+ # p, pick = use commit
646
+ # r, reword = use commit, but edit the commit message
647
+ # e, edit = use commit, but stop for amending
648
+ # s, squash = use commit, but meld into previous commit
649
+ # f, fixup = like "squash", but discard this commit's log message
650
+ # x, exec = run command (the rest of the line) using shell
651
+ #
652
+ # These lines can be re-ordered; they are executed from top to bottom.
653
+ #
654
+ # If you remove a line here THAT COMMIT WILL BE LOST.
655
+ #
656
+ # However, if you remove everything, the rebase will be aborted.
657
+ #
658
+ # Note that empty commits are commented out
659
+
660
+ If, instead of "pick" or "edit", you specify "squash", Git applies both that change and the change directly before it and makes you merge the commit messages together. So, if you want to make a single commit from these three commits, you make the script look like this:
661
+
662
+ pick f7f3f6d changed my name a bit
663
+ squash 310154e updated README formatting and added blame
664
+ squash a5f4a0d added cat-file
665
+
666
+ When you save and exit the editor, Git applies all three changes and then puts you back into the editor to merge the three commit messages:
667
+
668
+ # This is a combination of 3 commits.
669
+ # The first commit's message is:
670
+ changed my name a bit
671
+
672
+ # This is the 2nd commit message:
673
+
674
+ updated README formatting and added blame
675
+
676
+ # This is the 3rd commit message:
677
+
678
+ added cat-file
679
+
680
+ When you save that, you have a single commit that introduces the changes of all three previous commits.
681
+
682
+ ### Splitting a Commit ###
683
+
684
+ Splitting a commit undoes a commit and then partially stages and commits as many times as commits you want to end up with. For example, suppose you want to split the middle commit of your three commits. Instead of "updated README formatting and added blame", you want to split it into two commits: "updated README formatting" for the first, and "added blame" for the second. You can do that in the `rebase -i` script by changing the instruction on the commit you want to split to "edit":
685
+
686
+ pick f7f3f6d changed my name a bit
687
+ edit 310154e updated README formatting and added blame
688
+ pick a5f4a0d added cat-file
689
+
690
+ When you save and exit the editor, Git rewinds to the parent of the first commit in your list, applies the first commit (`f7f3f6d`), applies the second (`310154e`), and drops you to the console. There, you can do a mixed reset of that commit with `git reset HEAD^`, which effectively undoes that commit and leaves the modified files unstaged. Now you can take the changes that have been reset, and create multiple commits out of them. Simply stage and commit files until you have several commits, and run `git rebase --continue` when you’re done:
691
+
692
+ $ git reset HEAD^
693
+ $ git add README
694
+ $ git commit -m 'updated README formatting'
695
+ $ git add lib/simplegit.rb
696
+ $ git commit -m 'added blame'
697
+ $ git rebase --continue
698
+
699
+ Git applies the last commit (`a5f4a0d`) in the script, and your history looks like this:
700
+
701
+ $ git log -4 --pretty=format:"%h %s"
702
+ 1c002dd added cat-file
703
+ 9b29157 added blame
704
+ 35cfb2b updated README formatting
705
+ f3cc40e changed my name a bit
706
+
707
+ Once again, this changes the SHAs of all the commits in your list, so make sure no commit shows up in that list that you’ve already pushed to a shared repository.
708
+
709
+ ### The Nuclear Option: filter-branch ###
710
+
711
+ There is another history-rewriting option that you can use if you need to rewrite a larger number of commits in some scriptable way — for instance, changing your e-mail address globally or removing a file from every commit. The command is `filter-branch`, and it can rewrite huge swaths of your history, so you probably shouldn’t use it unless your project isn’t yet public and other people haven’t based work off the commits you’re about to rewrite. However, it can be very useful. You’ll learn a few of the common uses so you can get an idea of some of the things it’s capable of.
712
+
713
+ #### Removing a File from Every Commit ####
714
+
715
+ This occurs fairly commonly. Someone accidentally commits a huge binary file with a thoughtless `git add .`, and you want to remove it everywhere. Perhaps you accidentally committed a file that contained a password, and you want to make your project open source. `filter-branch` is the tool you probably want to use to scrub your entire history. To remove a file named passwords.txt from your entire history, you can use the `--tree-filter` option to `filter-branch`:
716
+
717
+ $ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD
718
+ Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21)
719
+ Ref 'refs/heads/master' was rewritten
720
+
721
+ The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter "rm -f *~" HEAD`.
722
+
723
+ You’ll be able to watch Git rewriting trees and commits and then move the branch pointer at the end. It’s generally a good idea to do this in a testing branch and then hard-reset your master branch after you’ve determined the outcome is what you really want. To run `filter-branch` on all your branches, you can pass `--all` to the command.
724
+
725
+ #### Making a Subdirectory the New Root ####
726
+
727
+ Suppose you’ve done an import from another source control system and have subdirectories that make no sense (trunk, tags, and so on). If you want to make the `trunk` subdirectory be the new project root for every commit, `filter-branch` can help you do that, too:
728
+
729
+ $ git filter-branch --subdirectory-filter trunk HEAD
730
+ Rewrite 856f0bf61e41a27326cdae8f09fe708d679f596f (12/12)
731
+ Ref 'refs/heads/master' was rewritten
732
+
733
+ Now your new project root is what was in the `trunk` subdirectory each time. Git will also automatically remove commits that did not affect the subdirectory.
734
+
735
+ #### Changing E-Mail Addresses Globally ####
736
+
737
+ Another common case is that you forgot to run `git config` to set your name and e-mail address before you started working, or perhaps you want to open-source a project at work and change all your work e-mail addresses to your personal address. In any case, you can change e-mail addresses in multiple commits in a batch with `filter-branch` as well. You need to be careful to change only the e-mail addresses that are yours, so you use `--commit-filter`:
738
+
739
+ $ git filter-branch --commit-filter '
740
+ if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ];
741
+ then
742
+ GIT_AUTHOR_NAME="Scott Chacon";
743
+ GIT_AUTHOR_EMAIL="schacon@example.com";
744
+ git commit-tree "$@";
745
+ else
746
+ git commit-tree "$@";
747
+ fi' HEAD
748
+
749
+ This goes through and rewrites every commit to have your new address. Because commits contain the SHA-1 values of their parents, this command changes every commit SHA in your history, not just those that have the matching e-mail address.
750
+
751
+ ### The Very Fast Nuclear Option: Big Friendly Giant Repo Cleaner (BFG) ###
752
+
753
+ [Roberto Tyley](https://github.com/rtyley) has written a similar tool to `filter-branch` called the BFG. BFG cannot do as much as `filter-branch`, but it is _very_ fast and on a large repository this can make a big difference. If the change you want to make is in the scope of BFG capaility, and you have performance issues, then you should consider using it.
754
+
755
+ See the [BFG](http://rtyley.github.io/bfg-repo-cleaner/) website for details.
756
+
757
+ ## Debugging with Git ##
758
+
759
+ Git also provides a couple of tools to help you debug issues in your projects. Because Git is designed to work with nearly any type of project, these tools are pretty generic, but they can often help you hunt for a bug or culprit when things go wrong.
760
+
761
+ ### File Annotation ###
762
+
763
+ If you track down a bug in your code and want to know when it was introduced and why, file annotation is often your best tool. It shows you what commit was the last to modify each line of any file. So, if you see that a method in your code is buggy, you can annotate the file with `git blame` to see when each line of the method was last edited and by whom. This example uses the `-L` option to limit the output to lines 12 through 22:
764
+
765
+ $ git blame -L 12,22 simplegit.rb
766
+ ^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 12) def show(tree = 'master')
767
+ ^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 13) command("git show #{tree}")
768
+ ^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 14) end
769
+ ^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 15)
770
+ 9f6560e4 (Scott Chacon 2008-03-17 21:52:20 -0700 16) def log(tree = 'master')
771
+ 79eaf55d (Scott Chacon 2008-04-06 10:15:08 -0700 17) command("git log #{tree}")
772
+ 9f6560e4 (Scott Chacon 2008-03-17 21:52:20 -0700 18) end
773
+ 9f6560e4 (Scott Chacon 2008-03-17 21:52:20 -0700 19)
774
+ 42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 20) def blame(path)
775
+ 42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 21) command("git blame #{path}")
776
+ 42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 22) end
777
+
778
+ Notice that the first field is the partial SHA-1 of the commit that last modified that line. The next two fields are values extracted from that commit—the author name and the authored date of that commit — so you can easily see who modified that line and when. After that come the line number and the content of the file. Also note the `^4832fe2` commit lines, which designate that those lines were in this file’s original commit. That commit is when this file was first added to this project, and those lines have been unchanged since. This is a tad confusing, because now you’ve seen at least three different ways that Git uses the `^` to modify a commit SHA, but that is what it means here.
779
+
780
+ Another cool thing about Git is that it doesn’t track file renames explicitly. It records the snapshots and then tries to figure out what was renamed implicitly, after the fact. One of the interesting features of this is that you can ask it to figure out all sorts of code movement as well. If you pass `-C` to `git blame`, Git analyzes the file you’re annotating and tries to figure out where snippets of code within it originally came from if they were copied from elsewhere. Recently, I was refactoring a file named `GITServerHandler.m` into multiple files, one of which was `GITPackUpload.m`. By blaming `GITPackUpload.m` with the `-C` option, I could see where sections of the code originally came from:
781
+
782
+ $ git blame -C -L 141,153 GITPackUpload.m
783
+ f344f58d GITServerHandler.m (Scott 2009-01-04 141)
784
+ f344f58d GITServerHandler.m (Scott 2009-01-04 142) - (void) gatherObjectShasFromC
785
+ f344f58d GITServerHandler.m (Scott 2009-01-04 143) {
786
+ 70befddd GITServerHandler.m (Scott 2009-03-22 144) //NSLog(@"GATHER COMMI
787
+ ad11ac80 GITPackUpload.m (Scott 2009-03-24 145)
788
+ ad11ac80 GITPackUpload.m (Scott 2009-03-24 146) NSString *parentSha;
789
+ ad11ac80 GITPackUpload.m (Scott 2009-03-24 147) GITCommit *commit = [g
790
+ ad11ac80 GITPackUpload.m (Scott 2009-03-24 148)
791
+ ad11ac80 GITPackUpload.m (Scott 2009-03-24 149) //NSLog(@"GATHER COMMI
792
+ ad11ac80 GITPackUpload.m (Scott 2009-03-24 150)
793
+ 56ef2caf GITServerHandler.m (Scott 2009-01-05 151) if(commit) {
794
+ 56ef2caf GITServerHandler.m (Scott 2009-01-05 152) [refDict setOb
795
+ 56ef2caf GITServerHandler.m (Scott 2009-01-05 153)
796
+
797
+ This is really useful. Normally, you get as the original commit the commit where you copied the code over, because that is the first time you touched those lines in this file. Git tells you the original commit where you wrote those lines, even if it was in another file.
798
+
799
+ ### Binary Search ###
800
+
801
+ Annotating a file helps if you know where the issue is to begin with. If you don’t know what is breaking, and there have been dozens or hundreds of commits since the last state where you know the code worked, you’ll likely turn to `git bisect` for help. The `bisect` command does a binary search through your commit history to help you identify as quickly as possible which commit introduced an issue.
802
+
803
+ Let’s say you just pushed out a release of your code to a production environment, you’re getting bug reports about something that wasn’t happening in your development environment, and you can’t imagine why the code is doing that. You go back to your code, and it turns out you can reproduce the issue, but you can’t figure out what is going wrong. You can bisect the code to find out. First you run `git bisect start` to get things going, and then you use `git bisect bad` to tell the system that the current commit you’re on is broken. Then, you must tell bisect when the last known good state was, using `git bisect good [good_commit]`:
804
+
805
+ $ git bisect start
806
+ $ git bisect bad
807
+ $ git bisect good v1.0
808
+ Bisecting: 6 revisions left to test after this
809
+ [ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo
810
+
811
+ Git figured out that about 12 commits came between the commit you marked as the last good commit (v1.0) and the current bad version, and it checked out the middle one for you. At this point, you can run your test to see if the issue exists as of this commit. If it does, then it was introduced sometime before this middle commit; if it doesn’t, then the problem was introduced sometime after the middle commit. It turns out there is no issue here, and you tell Git that by typing `git bisect good` and continue your journey:
812
+
813
+ $ git bisect good
814
+ Bisecting: 3 revisions left to test after this
815
+ [b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing
816
+
817
+ Now you’re on another commit, halfway between the one you just tested and your bad commit. You run your test again and find that this commit is broken, so you tell Git that with `git bisect bad`:
818
+
819
+ $ git bisect bad
820
+ Bisecting: 1 revisions left to test after this
821
+ [f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table
822
+
823
+ This commit is fine, and now Git has all the information it needs to determine where the issue was introduced. It tells you the SHA-1 of the first bad commit and show some of the commit information and which files were modified in that commit so you can figure out what happened that may have introduced this bug:
824
+
825
+ $ git bisect good
826
+ b047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commit
827
+ commit b047b02ea83310a70fd603dc8cd7a6cd13d15c04
828
+ Author: PJ Hyett <pjhyett@example.com>
829
+ Date: Tue Jan 27 14:48:32 2009 -0800
830
+
831
+ secure this thing
832
+
833
+ :040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730
834
+ f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M config
835
+
836
+ When you’re finished, you should run `git bisect reset` to reset your HEAD to where you were before you started, or you’ll end up in a weird state:
837
+
838
+ $ git bisect reset
839
+
840
+ This is a powerful tool that can help you check hundreds of commits for an introduced bug in minutes. In fact, if you have a script that will exit 0 if the project is good or non-0 if the project is bad, you can fully automate `git bisect`. First, you again tell it the scope of the bisect by providing the known bad and good commits. You can do this by listing them with the `bisect start` command if you want, listing the known bad commit first and the known good commit second:
841
+
842
+ $ git bisect start HEAD v1.0
843
+ $ git bisect run test-error.sh
844
+
845
+ Doing so automatically runs `test-error.sh` on each checked-out commit until Git finds the first broken commit. You can also run something like `make` or `make tests` or whatever you have that runs automated tests for you.
846
+
847
+ ## Moduli ##
848
+
849
+ Capita spesso che, mentre stai lavorando a un progetto, debba includerne un altro. Potrebbe essere una libreria sviluppata da terze parti o che tu stai sviluppando separatamente e lo stai usando in vari super-progetti. In questi casi si pone un problema comune: si vuole essere in grado di trattare i due progetti separatamente ma essere tuttavia in grado di utilizzarne uno all'interno dell'altro.
850
+
851
+ Vediamo un esempio. Immagina di stare sviluppando un sito web creando dei feed Atom e, invece di scrivere da zero il codice per generare il contenuto Atom, decidi di utilizzare una libreria. Molto probabilmente dovrai includere del codice da una libreria condivisa come un’installazione di CPAN o una gem di Ruby, o copiare il sorgente nel tuo progetto. Il problema dell’includere la libreria è che è difficile personalizzarla e spesso più difficile da distribuire, perché è necessario assicurarsi che ogni client abbia a disposizione quella libreria. Il problema di includere il codice nel tuo progetto è che è difficile incorporare le modifiche eventualmente fatte nel progetto iniziale quando questo venisse aggiornato.
852
+
853
+ Git risolve questo problema utilizzando i moduli. I moduli consentono di avere un repository Git come una directory di un altro repository Git, che ti permette di clonare un altro repository nel tuo progetto e mantenere le commit separate.
854
+
855
+ ### Lavorare con i moduli ###
856
+
857
+ Si supponga di voler aggiungere la libreria Rack (un’interfaccia gateway per server web in Ruby) al progetto, mantenendo le tue modifiche alla libreria e continuando a integrare le modifiche fatte a monte alla libreria. La prima cosa da fare è clonare il repository esterno nella subdirectory: aggiungi i progetti esterni come moduli col comando `git modulo aggiungono`:
858
+
859
+ $ git submodule add git://github.com/chneukirchen/rack.git rack
860
+ Initialized empty Git repository in /opt/subtest/rack/.git/
861
+ remote: Counting objects: 3181, done.
862
+ remote: Compressing objects: 100% (1534/1534), done.
863
+ remote: Total 3181 (delta 1951), reused 2623 (delta 1603)
864
+ Receiving objects: 100% (3181/3181), 675.42 KiB | 422 KiB/s, done.
865
+ Resolving deltas: 100% (1951/1951), done.
866
+
867
+ Ora, all'interno del tuo progetto, hai la directory `rack` che contiene il progetto Rack. Puoi andare in questa directory, fare le tue modifiche e aggiungere il tuo repository remoto per fare la push delle tue modifiche e prendere quelle disponibili, così come incorporare le modifiche del repository originale, e molto altro. Se esegui `git status` subito dopo aver aggiunto il modulo, vedrai due cose:
868
+
869
+ $ git status
870
+ # On branch master
871
+ # Changes to be committed:
872
+ # (use "git reset HEAD <file>..." to unstage)
873
+ #
874
+ # new file: .gitmodules
875
+ # new file: rack
876
+ #
877
+
878
+ Prima di tutto nota il file `.gitmodules`: è un file di configurazione che memorizza la mappatura tra l’URL del progetto e la directory locale dove lo hai scaricato:
879
+
880
+ $ cat .gitmodules
881
+ [submodule "rack"]
882
+ path = rack
883
+ url = git://github.com/chneukirchen/rack.git
884
+
885
+ Se hai più di un modulo, avrei più voci in questo file. È importante notare che anche questo file è versionato con tutti gli altri file, come il tuo `.gitignore` e viene trasferito con tutto il resto del tuo progetto. Questo è il modo in cui gli altri che clonano questo progetto sanno dove trovare i progetti dei moduli.
886
+
887
+ L'altro elenco in stato git uscita `git status` è la voce rack. Se si esegue `git diff` su questo, si vede qualcosa di interessante:
888
+
889
+ $ git diff --cached rack
890
+ diff --git a/rack b/rack
891
+ new file mode 160000
892
+ index 0000000..08d709f
893
+ --- /dev/null
894
+ +++ b/rack
895
+ @@ -0,0 +1 @@
896
+ +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433
897
+
898
+ Sebbene `rack` sia una subdirectory della tua directory di lavoro, Git lo vede come un modulo e non tiene traccia del suo contenuto quando non sei in quella directory. Git invece lo memorizza come una commit particolare da quel repository. Quando committi delle modifiche in quella directory, il super-project nota che l’HEAD è cambiato e registra la commit esatta dove sei; In questo modo, quando altri clonano questo progetto, possono ricreare esattamente l'ambiente.
899
+
900
+ Questo è un punto importante con i moduli: li memorizzi come la commit esatta dove sono. Non puoi memorizzare un modulo su `master` o qualche altro riferimento simbolico.
901
+
902
+ Quando committi vedi una cosa simile:
903
+
904
+ $ git commit -m 'first commit with submodule rack'
905
+ [master 0550271] first commit with submodule rack
906
+ 2 files changed, 4 insertions(+), 0 deletions(-)
907
+ create mode 100644 .gitmodules
908
+ create mode 160000 rack
909
+
910
+ Nota il modo 160000 di ogni voce di rack. Questo è un modo speciale di Git che significa che stai memorizzando una commit per una directory piuttosto che una subdirectory o un file.
911
+
912
+ Puoi trattare la directory `rack` come un progetto separato e puoi aggiornare occasionalmente il tuo super-project con un puntatore all’ultima commit del sotto-project. Tutti i comandi di Git lavorano indipendentemente nelle due directories:
913
+
914
+ $ git log -1
915
+ commit 0550271328a0038865aad6331e620cd7238601bb
916
+ Author: Scott Chacon <schacon@gmail.com>
917
+ Date: Thu Apr 9 09:03:56 2009 -0700
918
+
919
+ first commit with submodule rack
920
+ $ cd rack/
921
+ $ git log -1
922
+ commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433
923
+ Author: Christian Neukirchen <chneukirchen@gmail.com>
924
+ Date: Wed Mar 25 14:49:04 2009 +0100
925
+
926
+ Document version change
927
+
928
+ ### Clonare un progetto con moduli ###
929
+
930
+ Cloneremo ora un progetto con dei moduli. Quando ne ricevi uno, avrai una directory che contiene i moduli, ma nessun file:
931
+
932
+ $ git clone git://github.com/schacon/myproject.git
933
+ Initialized empty Git repository in /opt/myproject/.git/
934
+ remote: Counting objects: 6, done.
935
+ remote: Compressing objects: 100% (4/4), done.
936
+ remote: Total 6 (delta 0), reused 0 (delta 0)
937
+ Receiving objects: 100% (6/6), done.
938
+ $ cd myproject
939
+ $ ls -l
940
+ total 8
941
+ -rw-r--r-- 1 schacon admin 3 Apr 9 09:11 README
942
+ drwxr-xr-x 2 schacon admin 68 Apr 9 09:11 rack
943
+ $ ls rack/
944
+ $
945
+
946
+ La directory `rack` c’è, ma è vuota. Devi eseguire due comandi: `git submodule init` per inizializzare il tuo file di configurazione locale e `git submodule update` per scaricare tutti i dati del progetto e scaricare le commit opportune elencate nel tuo super-progetto:
947
+
948
+ $ git submodule init
949
+ Submodule 'rack' (git://github.com/chneukirchen/rack.git) registered for path 'rack'
950
+ $ git submodule update
951
+ Initialized empty Git repository in /opt/myproject/rack/.git/
952
+ remote: Counting objects: 3181, done.
953
+ remote: Compressing objects: 100% (1534/1534), done.
954
+ remote: Total 3181 (delta 1951), reused 2623 (delta 1603)
955
+ Receiving objects: 100% (3181/3181), 675.42 KiB | 173 KiB/s, done.
956
+ Resolving deltas: 100% (1951/1951), done.
957
+ Submodule path 'rack': checked out '08d709f78b8c5b0fbeb7821e37fa53e69afcf433'
958
+
959
+ Ora la tua directory `rack` è nello stesso stato in cui era quando hai committal precedentemente. Se qualche altro sviluppatore facesse delle modifiche a rack e le committasse, quando tu scaricherai quel riferimento e lo integrerai nel tuo repository vedrai qualcosa di strano:
960
+
961
+ $ git merge origin/master
962
+ Updating 0550271..85a3eee
963
+ Fast forward
964
+ rack | 2 +-
965
+ 1 files changed, 1 insertions(+), 1 deletions(-)
966
+ [master*]$ git status
967
+ # On branch master
968
+ # Changes not staged for commit:
969
+ # (use "git add <file>..." to update what will be committed)
970
+ # (use "git checkout -- <file>..." to discard changes in working directory)
971
+ #
972
+ # modified: rack
973
+ #
974
+
975
+ Quello di cui hai fatto il merge è fondamentalmente un cambiamento al puntatore del tuo modulo, ma non aggiorna il codice nella directory del modulo e sembra quindi che la tua directory di lavoro sia in uno stato ‘sporco’:
976
+
977
+ $ git diff
978
+ diff --git a/rack b/rack
979
+ index 6c5e70b..08d709f 160000
980
+ --- a/rack
981
+ +++ b/rack
982
+ @@ -1 +1 @@
983
+ -Subproject commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0
984
+ +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433
985
+
986
+ Questo succede perché il tuo puntatore del modulo non è lo stesso della directory del modulo. Per correggerlo devi eseguire di nuovo `git submodule update` again:
987
+
988
+ $ git submodule update
989
+ remote: Counting objects: 5, done.
990
+ remote: Compressing objects: 100% (3/3), done.
991
+ remote: Total 3 (delta 1), reused 2 (delta 0)
992
+ Unpacking objects: 100% (3/3), done.
993
+ From git@github.com:schacon/rack
994
+ 08d709f..6c5e70b master -> origin/master
995
+ Submodule path 'rack': checked out '6c5e70b984a60b3cecd395edd5b48a7575bf58e0'
996
+
997
+ E devi farlo ogni volta che scarichi delle modifiche al modulo nel progetto principale: è strano, ma funziona.
998
+
999
+ Un problema comune si verifica quando uno sviluppatore fa delle modifiche in un modulo ma non le trasmette al server pubblico, ma committa il puntatore a questo stato quando fa la pusg del superproject. Quando altri sviluppatori provano ad eseguire `git submodule update`, il sistema del modulo non riesce a trovare la commit a cui fa riferimento perché esiste solo sul sistema del primo sviluppatore. Quando ciò accade, viene visualizzato un errore come questo:
1000
+
1001
+ $ git submodule update
1002
+ fatal: reference isn’t a tree: 6c5e70b984a60b3cecd395edd5b48a7575bf58e0
1003
+ Unable to checkout '6c5e70b984a60b3cecd395edd5ba7575bf58e0' in submodule path 'rack'
1004
+
1005
+ Devi quindi vedere chi è stato l’ultimo a cambiare il modulo:
1006
+
1007
+ $ git log -1 rack
1008
+ commit 85a3eee996800fcfa91e2119372dd4172bf76678
1009
+ Author: Scott Chacon <schacon@gmail.com>
1010
+ Date: Thu Apr 9 09:19:14 2009 -0700
1011
+
1012
+ added a submodule reference I will never make public. hahahahaha!
1013
+
1014
+ e mandarmi un’email e cazziarlo.
1015
+
1016
+ ### Super-progetto ###
1017
+
1018
+ A volte gli sviluppatori vogliono scaricare una combinazione di subdirectory di un progetto grande, a seconda del team in cui lavorano. Questo è comune se vieni da CVS o Subversion, dove hai definito un modulo o un insieme di subdirectory e vuoi mantenere questo tipo di flusso di lavoro.
1019
+
1020
+ Un buon modo per farlo in Git è quello di rendere ciascuna sottodirectory un repository Git separato e creare quindi un repository Git con il super-progetto che contenga più moduli. Un vantaggio di questo approccio è che puoi definire meglio i rapporti tra i progetti con tag e branch nei super-progetti.
1021
+
1022
+ ### Problemi con i moduli ###
1023
+
1024
+ Usare i moduli può comunque presentare qualche intoppo. Prima di tutto devi fare molta attenzione quando lavori nella directory del modulo. Quando esegui `git submodule update`, viene fatto il checkout della versione specifica del progetto, ma non del branch. Questo viene detto “avere l’HEAD separato: significa che il file HEAD punta direttamente alla commit, e non un riferimento simbolico. Il problema è che generalmente non vuoi lavorare in un ambiente separato perché è facile perdere commit, e non un riferimento simbolico. Il problema è che generalmente non vuoi lavorare in un ambiente separato perché è facile perdere le tue modifiche. Se inizi col comando `submodule update` e poi fai una commit nella directory del modulo senza aver creato prima un branch per lavorarci e quindi esegui una `git submodule update` dal super-progetto senz’aver committato nel frattempo, Git sovrascriverà le tue modifiche senza dirti nulla. Tecnicamente non hai perso il tuo lavoro, ma non avendo nessun branch che vi punti sarà difficile da recuperare.
1025
+
1026
+ Per evitare questo problema ti basta creare un branch quando lavori nella directory del modulo con `git checkout -b work` o qualcosa di equivalente. Quando successivamente aggiorni il modulo il tuo lavoro sarà di nuovo sovrascritto, ma avrai un puntatore per poterlo recuperare.
1027
+
1028
+ Cambiare branch in progetti con dei moduli può essere difficile. Se crei un nuovo branch, vi aggiungi un modulo e torni a un branch che non abbia il modulo, ti ritroverai la directory del modulo non ancora tracciata:
1029
+
1030
+ $ git checkout -b rack
1031
+ Switched to a new branch "rack"
1032
+ $ git submodule add git@github.com:schacon/rack.git rack
1033
+ Initialized empty Git repository in /opt/myproj/rack/.git/
1034
+ ...
1035
+ Receiving objects: 100% (3184/3184), 677.42 KiB | 34 KiB/s, done.
1036
+ Resolving deltas: 100% (1952/1952), done.
1037
+ $ git commit -am 'added rack submodule'
1038
+ [rack cc49a69] added rack submodule
1039
+ 2 files changed, 4 insertions(+), 0 deletions(-)
1040
+ create mode 100644 .gitmodules
1041
+ create mode 160000 rack
1042
+ $ git checkout master
1043
+ Switched to branch "master"
1044
+ $ git status
1045
+ # On branch master
1046
+ # Untracked files:
1047
+ # (use "git add <file>..." to include in what will be committed)
1048
+ #
1049
+ # rack/
1050
+
1051
+ Devi rimuoverla o spostarla e in entrambi i casi dovrai riclonarla quando torni al branch precedente e puoi quindi perdere le modifiche locali o i branch di cui non hai ancora fatto una push.
1052
+
1053
+ L'ultima avvertimento riguarda il passaggio da subdirectory a moduli. Se stai versionando dei file tuo nel progetto e vuoi spostarli in un modulo, è necessario devi fare attenzione, altrimenti Git si arrabbierà. Supponi di avere i file di rack in una directory del tuo progetto e decidi di trasformarla in un modulo. Se elimini la directory ed esegui il comando `submodule add`, Git ti strillerà:
1054
+
1055
+ $ rm -Rf rack/
1056
+ $ git submodule add git@github.com:schacon/rack.git rack
1057
+ 'rack' already exists in the index
1058
+
1059
+ Devi prima rimuovere la directory `rack` dalla tua area di staging per poter quindi aggiungerla come modulo:
1060
+
1061
+ $ git rm -r rack
1062
+ $ git submodule add git@github.com:schacon/rack.git rack
1063
+ Initialized empty Git repository in /opt/testsub/rack/.git/
1064
+ remote: Counting objects: 3184, done.
1065
+ remote: Compressing objects: 100% (1465/1465), done.
1066
+ remote: Total 3184 (delta 1952), reused 2770 (delta 1675)
1067
+ Receiving objects: 100% (3184/3184), 677.42 KiB | 88 KiB/s, done.
1068
+ Resolving deltas: 100% (1952/1952), done.
1069
+
1070
+ Immagina ora di averlo fatto in un branch. Se ora torni a un branch dove quei file sono ancora nell’albero corrente piuttosto che nel modulo vedrai questo errore:
1071
+
1072
+ $ git checkout master
1073
+ error: Untracked working tree file 'rack/AUTHORS' would be overwritten by merge.
1074
+ (errore: il file 'rack/AUTHORS' non è versionato e sarà sovrascritto)
1075
+
1076
+ Devi quindi spostare la directory del modulo `rack` prima di poter tornare al branch che non ce l’aveva:
1077
+
1078
+ $ mv rack /tmp/
1079
+ $ git checkout master
1080
+ Switched to branch "master"
1081
+ $ ls
1082
+ README rack
1083
+
1084
+ Ora, quando tornerai indietro, troverai la directory `rack` vuota. Ora puoi eseguire `git submodule update` per ripopolarla o rispostare la directory `/tmp/rack` nella directory vuota.
1085
+
1086
+ ## Subtree Merging ##
1087
+
1088
+ Ora che hai visto quali sono le difficoltà del sistema dei moduli vediamo un’alternativa per risolvere lo stesso problema. Quando Git fa dei merge vede prima quello di cui deve fare il merge e poi decide quale sia la strategia migliore da usare. Se stai facendo il merge due branch Git userà la strategia _ricorsiva_ (*recursive* in inglese). Se stai facendo il merge di più di due branch Git userà la strategia del polpo (*octopus* in inglese). Queste strategie sono scelte automaticamente, perché la strategia ricorsiva può gestire situazioni complesse di merge a tre vie (quando ci sono per esempio più antenati), ma può gestire solamente due branch alla volta. La strategia del polpo può gestire branch multipli ma agisce con più cautela per evitare conflitti difficili da risolvere, ed è quindi scelta come strategia predefinita se stai facendo il merge di più di due branch.
1089
+
1090
+ Ci sono comunque altre strategie tra cui scegliere. Una di questa è il merge *subtree* e la puoi usare per risolvere i problemi dei subprogetti. Vedremo ora come includere lo stesso rack come abbiamo fatto nella sezione precedente, usando però il merge subtree.
1091
+
1092
+ L’idea del merge subtree è che tu hai due progetti e uno di questi è mappato su una subdirectory dell’altro e viceversa. Quando specifichi il merge subtree Git è abbastanza intelligente da capire che uno è un albero dell’altro e farne il merge nel migliore dei modi: è piuttosto incredibile.
1093
+
1094
+ Aggiungi prima l’applicazione Rack al tuo progetto e aggiungi il progetto Rack come un riferimento remoto al tuo progetto, quindi fanne il checkout in un suo branch:
1095
+
1096
+ $ git remote add rack_remote git@github.com:schacon/rack.git
1097
+ $ git fetch rack_remote
1098
+ warning: no common commits
1099
+ remote: Counting objects: 3184, done.
1100
+ remote: Compressing objects: 100% (1465/1465), done.
1101
+ remote: Total 3184 (delta 1952), reused 2770 (delta 1675)
1102
+ Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, done.
1103
+ Resolving deltas: 100% (1952/1952), done.
1104
+ From git@github.com:schacon/rack
1105
+ * [new branch] build -> rack_remote/build
1106
+ * [new branch] master -> rack_remote/master
1107
+ * [new branch] rack-0.4 -> rack_remote/rack-0.4
1108
+ * [new branch] rack-0.9 -> rack_remote/rack-0.9
1109
+ $ git checkout -b rack_branch rack_remote/master
1110
+ Branch rack_branch set up to track remote branch refs/remotes/rack_remote/master.
1111
+ Switched to a new branch "rack_branch"
1112
+
1113
+ Ora hai la root del progetto Rack nel tuo branch `rack_branch` e il tuo progetto nel branch `master`. Se scarichi prima uno e poi l’altro vedrai che avranno due progetti sorgenti:
1114
+
1115
+ $ ls
1116
+ AUTHORS KNOWN-ISSUES Rakefile contrib lib
1117
+ COPYING README bin example test
1118
+ $ git checkout master
1119
+ Switched to branch "master"
1120
+ $ ls
1121
+ README
1122
+
1123
+ Ora vuoi inviare il progetto Rack nel tuo progetto `master` come una sottodirectory e in Git puoi farlo con `git read-tree`. Conoscerai meglio `read-tree` e i suoi amici nel Capitolo 9, ma per ora sappi che legge la radice di un branch nella tua area di staging della tua directory di lavoro. Sei appena ritornato nel tuo branch `master` e hai scaricato il branch `rack_branch` nella directory `rack` del branch `master` del tuo progetto principale:
1124
+
1125
+ $ git read-tree --prefix=rack/ -u rack_branch
1126
+
1127
+ Quando fai la commit sembra che tutti i file di Rack siano nella directory, come se li avessi copiati da un archivio. La cosa interessante è che può fare facilmente il merge da un branch all’altro, così che puoi importare gli aggiornamenti del progetto Rack passando a quel branch e facendo la pull:
1128
+
1129
+ $ git checkout rack_branch
1130
+ $ git pull
1131
+
1132
+ Tutte le modifiche del progetto Rack project vengono incorporate e sono pronte per essere committate in locale. Puoi fare anche l’opposto: modificare la directory `rack` e poi fare il merge nel branch `rack_branch` per inviarlo al mantenitore o farne la push al server remoto.
1133
+
1134
+ Per fare un confronto tra quello che hai nella directory `rack` e il codice nel branch `rack_branch` (e vedere se devi fare un merge o meno) non puoi usare il normale comando `diff`: devi usare invece `git diff-tree` con il branch con cui vuoi fare il confronto:
1135
+
1136
+ $ git diff-tree -p rack_branch
1137
+
1138
+ O confrontare quello che c’è nella directory `rack` con quello che c’era nel branch `master` l’ultima volta che l’hai scaricato, col comando
1139
+
1140
+ $ git diff-tree -p rack_remote/master
1141
+
1142
+ ## Sommario ##
1143
+
1144
+ Hai visto numerosi strumenti avanzati che ti permettono di manipolare le tue commit e la tua area di staging in modo più preciso. Quando incontrassi dei problemi dovresti essere facilmente in grado di capire quale commit li ha generati, quando e chi ne è l’autore. Se desideri usare dei sotto-progetti nel tuo progetto e hai appreso alcuni modi per soddisfare tali esigenze. A questo punto dovresti essere in grado di fare in Git la maggior parte delle cose sulla riga di comando di uso quotidiano, e sentirti a tuo agio facendole.