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,1155 @@
1
+ # Основы Git #
2
+
3
+ Если вы хотите начать работать с Git'ом, прочитав всего одну главу, то эта глава — то, что вам нужно. Здесь рассмотрены все базовые команды, необходимые вам для решения подавляющего большинства задач возникающих при работе с Git'ом. После прочтения этой главы вы научитесь настраивать и инициализировать репозиторий, начинать и прекращать версионный контроль файлов, а также подготавливать и фиксировать изменения. Мы также продемонстрируем вам как настроить в Git'е игнорирование отдельных файлов или их групп, как быстро и просто отменить ошибочные изменения, как просмотреть историю вашего проекта и изменения между отдельными коммитами (commit), а также как отправлять (push) и получать (pull) изменения в/из удалённого (remote) репозитория.
4
+
5
+ ## Создание Git-репозитория ##
6
+
7
+ Для создания Git-репозитория существуют два основных подхода. Первый подход — импорт в Git уже существующего проекта или каталога. Второй — клонирование уже существующего репозитория с сервера.
8
+
9
+ ### Создание репозитория в существующем каталоге ###
10
+
11
+ Если вы собираетесь начать использовать Git для существующего проекта, то вам необходимо перейти в проектный каталог и в командной строке ввести
12
+
13
+ $ git init
14
+
15
+ Эта команда создаёт в текущем каталоге новый подкаталог с именем .git содержащий все необходимые файлы репозитория — основу Git-репозитория. На этом этапе ваш проект ещё не находится под версионным контролем. (В главе 9 приведено подробное описание файлов содержащихся в только что созданном вами каталоге `.git`)
16
+
17
+ Если вы хотите добавить под версионный контроль существующие файлы (в отличие от пустого каталога), вам стоит проиндексировать эти файлы и осуществить первую фиксацию изменений. Осуществить это вы можете с помощью нескольких команд `git add` указывающих индексируемые файлы, а затем `commit`:
18
+
19
+ $ git add *.c
20
+ $ git add README
21
+ $ git commit -m 'initial project version'
22
+
23
+ Мы разберём, что делают эти команды чуть позже. На данном этапе, у вас есть Git-репозиторий с добавленными файлами и начальным коммитом.
24
+
25
+ ### Клонирование существующего репозитория ###
26
+
27
+ Если вы желаете получить копию существующего репозитория Git, например, проекта, в котором вы хотите поучаствовать, то вам нужна команда `git clone`. Если вы знакомы с другими системами контроля версий, такими как Subversion, то заметите, что команда называется `clone`, а не `checkout`. Это важное отличие — Git получает копию практически всех данных, что есть на сервере. Каждая версия каждого файла из истории проекта забирается (pulled) с сервера, когда вы выполняете `git clone`. Фактически, если серверный диск выйдет из строя, вы можете использовать любой из клонов на любом из клиентов, для того чтобы вернуть сервер в то состояние, в котором он находился в момент клонирования (вы можете потерять часть серверных перехватчиков (server-side hooks) и т.п., но все данные, помещённые под версионный контроль, будут сохранены, подробнее см. в главе 4).
28
+
29
+ Клонирование репозитория осуществляется командой `git clone [url]`. Например, если вы хотите клонировать библиотеку Ruby Git, известную как Grit, вы можете сделать это следующим образом:
30
+
31
+ $ git clone git://github.com/schacon/grit.git
32
+
33
+ Эта команда создаёт каталог с именем `grit`, инициализирует в нём каталог `.git`, скачивает все данные для этого репозитория и создаёт (checks out) рабочую копию последней версии. Если вы зайдёте в новый каталог `grit`, вы увидите в нём проектные файлы, пригодные для работы и использования. Если вы хотите клонировать репозиторий в каталог, отличный от `grit`, можно это указать в следующем параметре командной строки:
34
+
35
+ $ git clone git://github.com/schacon/grit.git mygrit
36
+
37
+ Эта команда делает всё то же самое, что и предыдущая, только результирующий каталог будет назван mygrit.
38
+
39
+ В Git'е реализовано несколько транспортных протоколов, которые вы можете использовать. В предыдущем примере использовался протокол `git://`, вы также можете встретить `http(s)://` или `user@server:/path.git`, использующий протокол передачи SSH. В главе 4 мы познакомимся со всеми доступными вариантами конфигурации сервера для обеспечения доступа к вашему Git-репозиторию, а также рассмотрим их достоинства и недостатки.
40
+
41
+ ## Запись изменений в репозиторий ##
42
+
43
+ Итак, у вас имеется настоящий Git-репозиторий и рабочая копия файлов для некоторого проекта. Вам нужно делать некоторые изменения и фиксировать “снимки” состояния (snapshots) этих изменений в вашем репозитории каждый раз, когда проект достигает состояния, которое вам хотелось бы сохранить.
44
+
45
+ Запомните, каждый файл в вашем рабочем каталоге может находиться в одном из двух состояний: под версионным контролем (отслеживаемые) и нет (неотслеживаемые). Отслеживаемые файлы — это те файлы, которые были в последнем слепке состояния проекта (snapshot); они могут быть неизменёнными, изменёнными или подготовленными к коммиту (staged). Неотслеживаемые файлы — это всё остальное, любые файлы в вашем рабочем каталоге, которые не входили в ваш последний слепок состояния и не подготовлены к коммиту. Когда вы впервые клонируете репозиторий, все файлы будут отслеживаемыми и неизменёнными, потому что вы только взяли их из хранилища (checked them out) и ничего пока не редактировали.
46
+
47
+ Как только вы отредактируете файлы, Git будет рассматривать их как изменённые, т.к. вы изменили их с момента последнего коммита. Вы индексируете (stage) эти изменения и затем фиксируете все индексированные изменения, а затем цикл повторяется. Этот жизненный цикл изображён на рисунке 2-1.
48
+
49
+ Insert 18333fig0201.png
50
+ Рисунок 2-1. Жизненный цикл состояний файлов.
51
+
52
+ ### Определение состояния файлов ###
53
+
54
+ Основной инструмент, используемый для определения, какие файлы в каком состоянии находятся — это команда `git status`. Если вы выполните эту команду сразу после клонирования, вы увидите что-то вроде этого:
55
+
56
+ $ git status
57
+ # On branch master
58
+ nothing to commit, working directory clean
59
+
60
+ Это означает, что у вас чистый рабочий каталог, другими словами — в нём нет отслеживаемых изменённых файлов. Git также не обнаружил неотслеживаемых файлов, в противном случае они бы были перечислены здесь. И наконец, команда сообщает вам на какой ветке (branch) вы сейчас находитесь. Пока что это всегда ветка `master` — это ветка по умолчанию; в этой главе это не важно. В следующей главе будет подробно рассказано про ветки и ссылки.
61
+
62
+ Предположим, вы добавили в свой проект новый файл, простой файл README. Если этого файла раньше не было, и вы выполните `git status`, вы увидите свой неотслеживаемый файл вот так:
63
+
64
+ $ vim README
65
+ $ git status
66
+ # On branch master
67
+ # Untracked files:
68
+ # (use "git add <file>..." to include in what will be committed)
69
+ #
70
+ # README
71
+ nothing added to commit but untracked files present (use "git add" to track)
72
+
73
+ Понять, что новый файл README неотслеживаемый можно по тому, что он находится в секции "Untracked files" в выводе команды `status`. Статус "неотслеживаемый файл", по сути, означает, что Git видит файл, отсутствующий в предыдущем снимке состояния (коммите); Git не станет добавлять его в ваши коммиты, пока вы его явно об этом не попросите. Это предохранит вас от случайного добавления в репозиторий сгенерированных бинарных файлов или каких-либо других, которые вы и не думали добавлять. Мы хотели добавить README, так давайте сделаем это.
74
+
75
+ ### Отслеживание новых файлов ###
76
+
77
+ Для того чтобы начать отслеживать (добавить под версионный контроль) новый файл, используется команда `git add`. Чтобы начать отслеживание файла README, вы можете выполнить следующее:
78
+
79
+ $ git add README
80
+
81
+ Если вы снова выполните команду `status`, то увидите, что файл README теперь отслеживаемый и индексированный:
82
+
83
+ $ git status
84
+ # On branch master
85
+ # Changes to be committed:
86
+ # (use "git reset HEAD <file>..." to unstage)
87
+ #
88
+ # new file: README
89
+ #
90
+
91
+ Вы можете видеть, что файл проиндексирован по тому, что он находится в секции “Changes to be committed”. Если вы выполните коммит в этот момент, то версия файла, существовавшая на момент выполнения вами команды `git add`, будет добавлена в историю снимков состояния. Как вы помните, когда вы ранее выполнили `git init`, вы затем выполнили `git add (файлы)` — это было сделано для того, чтобы добавить файлы в вашем каталоге под версионный контроль. Команда `git add` принимает параметром путь к файлу или каталогу, если это каталог, команда рекурсивно добавляет (индексирует) все файлы в данном каталоге.
92
+
93
+ ### Индексация изменённых файлов ###
94
+
95
+ Давайте модифицируем файл, уже находящийся под версионным контролем. Если вы измените отслеживаемый файл benchmarks.rb и после этого снова выполните команду `status`, то результат будет примерно следующим:
96
+
97
+ $ git status
98
+ # On branch master
99
+ # Changes to be committed:
100
+ # (use "git reset HEAD <file>..." to unstage)
101
+ #
102
+ # new file: README
103
+ #
104
+ # Changes not staged for commit:
105
+ # (use "git add <file>..." to update what will be committed)
106
+ #
107
+ # modified: benchmarks.rb
108
+ #
109
+
110
+ Файл benchmarks.rb находится в секции “Changes not staged for commit” — это означает, что отслеживаемый файл был изменён в рабочем каталоге, но пока не проиндексирован. Чтобы проиндексировать его, необходимо выполнить команду `git add` (это многофункциональная команда, она используется для добавления под версионный контроль новых файлов, для индексации изменений, а также для других целей, например для указания файлов с исправленным конфликтом слияния). Выполним `git add`, чтобы проиндексировать benchmarks.rb, а затем снова выполним `git status`:
111
+
112
+ $ git add benchmarks.rb
113
+ $ git status
114
+ # On branch master
115
+ # Changes to be committed:
116
+ # (use "git reset HEAD <file>..." to unstage)
117
+ #
118
+ # new file: README
119
+ # modified: benchmarks.rb
120
+ #
121
+
122
+ Теперь оба файла проиндексированы и войдут в следующий коммит. В этот момент вы, предположим, вспомнили одно небольшое изменение, которое вы хотите сделать в benchmarks.rb до фиксации. Вы открываете файл, вносите и сохраняете необходимые изменения и вроде бы готовы к коммиту. Но давайте-ка ещё раз выполним `git status`:
123
+
124
+ $ vim benchmarks.rb
125
+ $ git status
126
+ # On branch master
127
+ # Changes to be committed:
128
+ # (use "git reset HEAD <file>..." to unstage)
129
+ #
130
+ # new file: README
131
+ # modified: benchmarks.rb
132
+ #
133
+ # Changes not staged for commit:
134
+ # (use "git add <file>..." to update what will be committed)
135
+ #
136
+ # modified: benchmarks.rb
137
+ #
138
+
139
+ Что за чёрт? Теперь benchmarks.rb отображается как проиндексированный и непроиндексированный одновременно. Как такое возможно? Такая ситуация наглядно демонстрирует, что Git индексирует файл в точности в том состоянии, в котором он находился, когда вы выполнили команду `git add`. Если вы выполните коммит сейчас, то файл benchmarks.rb попадёт в коммит в том состоянии, в котором он находился, когда вы последний раз выполняли команду `git add`, а не в том, в котором он находится в вашем рабочем каталоге в момент выполнения `git commit`. Если вы изменили файл после выполнения `git add`, вам придётся снова выполнить `git add`, чтобы проиндексировать последнюю версию файла:
140
+
141
+ $ git add benchmarks.rb
142
+ $ git status
143
+ # On branch master
144
+ # Changes to be committed:
145
+ # (use "git reset HEAD <file>..." to unstage)
146
+ #
147
+ # new file: README
148
+ # modified: benchmarks.rb
149
+ #
150
+
151
+ ### Игнорирование файлов ###
152
+
153
+ Зачастую, у вас имеется группа файлов, которые вы не только не хотите автоматически добавлять в репозиторий, но и видеть в списках неотслеживаемых. К таким файлам обычно относятся автоматически генерируемые файлы (различные логи, результаты сборки программ и т.п.). В таком случае, вы можете создать файл .gitignore с перечислением шаблонов соответствующих таким файлам. Вот пример файла .gitignore:
154
+
155
+ $ cat .gitignore
156
+ *.[oa]
157
+ *~
158
+
159
+ Первая строка предписывает Git'у игнорировать любые файлы заканчивающиеся на .o или .a — объектные и архивные файлы, которые могут появиться во время сборки кода. Вторая строка предписывает игнорировать все файлы заканчивающиеся на тильду (`~`), которая используется во многих текстовых редакторах, например Emacs, для обозначения временных файлов. Вы можете также включить каталоги log, tmp или pid; автоматически создаваемую документацию; и т.д. и т.п. Хорошая практика заключается в настройке файла .gitignore до того, как начать серьёзно работать, это защитит вас от случайного добавления в репозиторий файлов, которых вы там видеть не хотите.
160
+
161
+ К шаблонам в файле .gitignore применяются следующие правила:
162
+
163
+ * Пустые строки, а также строки, начинающиеся с #, игнорируются.
164
+ * Можно использовать стандартные glob шаблоны.
165
+ * Можно заканчивать шаблон символом слэша (`/`) для указания каталога.
166
+ * Можно инвертировать шаблон, использовав восклицательный знак (`!`) в качестве первого символа.
167
+
168
+ Glob-шаблоны представляют собой упрощённые регулярные выражения используемые командными интерпретаторами. Символ `*` соответствует 0 или более символам; последовательность `[abc]` — любому символу из указанных в скобках (в данном примере a, b или c); знак вопроса (`?`) соответствует одному символу; `[0-9]` соответствует любому символу из интервала (в данном случае от 0 до 9).
169
+
170
+ Вот ещё один пример файла .gitignore:
171
+
172
+ # комментарий — эта строка игнорируется
173
+ # не обрабатывать файлы, имя которых заканчивается на .a
174
+ *.a
175
+ # НО отслеживать файл lib.a, несмотря на то, что мы игнорируем все .a файлы с помощью предыдущего правила
176
+ !lib.a
177
+ # игнорировать только файл TODO находящийся в корневом каталоге, не относится к файлам вида subdir/TODO
178
+ /TODO
179
+ # игнорировать все файлы в каталоге build/
180
+ build/
181
+ # игнорировать doc/notes.txt, но не doc/server/arch.txt
182
+ doc/*.txt
183
+ # игнорировать все .txt файлы в каталоге doc/
184
+ doc/**/*.txt
185
+
186
+ Шаблон `**/` доступен в Git, начиная с версии 1.8.2.
187
+
188
+ ### Просмотр индексированных и неиндексированных изменений ###
189
+
190
+ Если результат работы команды `git status` недостаточно информативен для вас — вам хочется знать, что конкретно поменялось, а не только какие файлы были изменены — вы можете использовать команду `git diff`. Позже мы рассмотрим команду `git diff` подробнее; вы, скорее всего, будете использовать эту команду для получения ответов на два вопроса: что вы изменили, но ещё не проиндексировали, и что вы проиндексировали и собираетесь фиксировать. Если `git status` отвечает на эти вопросы слишком обобщённо, то `git diff` показывает вам непосредственно добавленные и удалённые строки — собственно заплатку (patch).
191
+
192
+ Допустим, вы снова изменили и проиндексировали файл README, а затем изменили файл benchmarks.rb без индексирования. Если вы выполните команду `status`, вы опять увидите что-то вроде:
193
+
194
+ $ git status
195
+ # On branch master
196
+ # Changes to be committed:
197
+ # (use "git reset HEAD <file>..." to unstage)
198
+ #
199
+ # new file: README
200
+ #
201
+ # Changes not staged for commit:
202
+ # (use "git add <file>..." to update what will be committed)
203
+ #
204
+ # modified: benchmarks.rb
205
+ #
206
+
207
+ Чтобы увидеть, что же вы изменили, но пока не проиндексировали, наберите `git diff` без аргументов:
208
+
209
+ $ git diff
210
+ diff --git a/benchmarks.rb b/benchmarks.rb
211
+ index 3cb747f..da65585 100644
212
+ --- a/benchmarks.rb
213
+ +++ b/benchmarks.rb
214
+ @@ -36,6 +36,10 @@ def main
215
+ @commit.parents[0].parents[0].parents[0]
216
+ end
217
+
218
+ + run_code(x, 'commits 1') do
219
+ + git.commits.size
220
+ + end
221
+ +
222
+ run_code(x, 'commits 2') do
223
+ log = git.commits('master', 15)
224
+ log.size
225
+
226
+ Эта команда сравнивает содержимое вашего рабочего каталога с содержимым индекса. Результат показывает ещё не проиндексированные изменения.
227
+
228
+ Если вы хотите посмотреть, что вы проиндексировали и что войдёт в следующий коммит, вы можете выполнить `git diff --cached`. (В Git'е версии 1.6.1 и выше, вы также можете использовать `git diff --staged`, которая легче запоминается.) Эта команда сравнивает ваши индексированные изменения с последним коммитом:
229
+
230
+ $ git diff --cached
231
+ diff --git a/README b/README
232
+ new file mode 100644
233
+ index 0000000..03902a1
234
+ --- /dev/null
235
+ +++ b/README2
236
+ @@ -0,0 +1,5 @@
237
+ +grit
238
+ + by Tom Preston-Werner, Chris Wanstrath
239
+ + http://github.com/mojombo/grit
240
+ +
241
+ +Grit is a Ruby library for extracting information from a Git repository
242
+
243
+ Важно отметить, что `git diff` сама по себе не показывает все изменения сделанные с последнего коммита — только те, что ещё не проиндексированы. Такое поведение может сбивать с толку, так как если вы проиндексируете все свои изменения, то `git diff` ничего не вернёт.
244
+
245
+ Другой пример: вы проиндексировали файл benchmarks.rb и затем изменили его, вы можете использовать `git diff` для просмотра как индексированных изменений в этом файле, так и тех, что пока не проиндексированы:
246
+
247
+ $ git add benchmarks.rb
248
+ $ echo '# test line' >> benchmarks.rb
249
+ $ git status
250
+ # On branch master
251
+ #
252
+ # Changes to be committed:
253
+ #
254
+ # modified: benchmarks.rb
255
+ #
256
+ # Changes not staged for commit:
257
+ #
258
+ # modified: benchmarks.rb
259
+ #
260
+
261
+ Теперь вы можете используя `git diff` посмотреть непроиндексированные изменения
262
+
263
+ $ git diff
264
+ diff --git a/benchmarks.rb b/benchmarks.rb
265
+ index e445e28..86b2f7c 100644
266
+ --- a/benchmarks.rb
267
+ +++ b/benchmarks.rb
268
+ @@ -127,3 +127,4 @@ end
269
+ main()
270
+
271
+ ##pp Grit::GitRuby.cache_client.stats
272
+ +# test line
273
+
274
+ а также уже проиндексированные, используя `git diff --cached`:
275
+
276
+ $ git diff --cached
277
+ diff --git a/benchmarks.rb b/benchmarks.rb
278
+ index 3cb747f..e445e28 100644
279
+ --- a/benchmarks.rb
280
+ +++ b/benchmarks.rb
281
+ @@ -36,6 +36,10 @@ def main
282
+ @commit.parents[0].parents[0].parents[0]
283
+ end
284
+
285
+ + run_code(x, 'commits 1') do
286
+ + git.commits.size
287
+ + end
288
+ +
289
+ run_code(x, 'commits 2') do
290
+ log = git.commits('master', 15)
291
+ log.size
292
+
293
+ ### Фиксация изменений ###
294
+
295
+ Теперь, когда ваш индекс настроен так, как вам и хотелось, вы можете зафиксировать свои изменения. Запомните, всё, что до сих пор не проиндексировано — любые файлы, созданные или изменённые вами, и для которых вы не выполнили `git add` после момента редактирования — не войдут в этот коммит. Они останутся изменёнными файлами на вашем диске.
296
+ В нашем случае, когда вы в последний раз выполняли `git status`, вы видели что всё проиндексировано, и вот, вы готовы к коммиту. Простейший способ зафиксировать изменения — это набрать `git commit`:
297
+
298
+ $ git commit
299
+
300
+ Эта команда откроет выбранный вами текстовый редактор. (Редактор устанавливается системной переменной `$EDITOR` — обычно это vim или emacs, хотя вы можете установить ваш любимый с помощью команды `git config --global core.editor`, как было показано в главе 1).
301
+
302
+ В редакторе будет отображён следующий текст (это пример окна Vim'а):
303
+
304
+ # Please enter the commit message for your changes. Lines starting
305
+ # with '#' will be ignored, and an empty message aborts the commit.
306
+ # On branch master
307
+ # Changes to be committed:
308
+ # (use "git reset HEAD <file>..." to unstage)
309
+ #
310
+ # new file: README
311
+ # modified: benchmarks.rb
312
+ ~
313
+ ~
314
+ ~
315
+ ".git/COMMIT_EDITMSG" 10L, 283C
316
+
317
+ Вы можете видеть, что комментарий по умолчанию для коммита содержит закомментированный результат работы ("выхлоп") команды `git status` и ещё одну пустую строку сверху. Вы можете удалить эти комментарии и набрать своё сообщение или же оставить их для напоминания о том, что вы фиксируете. (Для ещё более подробного напоминания, что же именно вы поменяли, можете передать аргумент `-v` в команду `git commit`. Это приведёт к тому, что в комментарий будет также помещена дельта/diff изменений, таким образом вы сможете точно увидеть всё, что сделано.) Когда вы выходите из редактора, Git создаёт для вас коммит с этим сообщением (удаляя комментарии и вывод diff'а).
318
+
319
+ Есть и другой способ — вы можете набрать свой комментарий к коммиту в командной строке вместе с командой `commit`, указав его после параметра -m, как в следующем примере:
320
+
321
+ $ git commit -m "Story 182: Fix benchmarks for speed"
322
+ [master]: created 463dc4f: "Fix benchmarks for speed"
323
+ 2 files changed, 3 insertions(+), 0 deletions(-)
324
+ create mode 100644 README
325
+
326
+ Итак, вы создали свой первый коммит! Вы можете видеть, что коммит вывел вам немного информации о себе: на какую ветку вы выполнили коммит (master), какая контрольная сумма SHA-1 у этого коммита (`463dc4f`), сколько файлов было изменено, а также статистику по добавленным/удалённым строкам в этом коммите.
327
+
328
+ Запомните, что коммит сохраняет снимок состояния вашего индекса. Всё, что вы не проиндексировали, так и торчит в рабочем каталоге как изменённое; вы можете сделать ещё один коммит, чтобы добавить эти изменения в репозиторий. Каждый раз, когда вы делаете коммит, вы сохраняете снимок состояния вашего проекта, который позже вы можете восстановить или с которым можно сравнить текущее состояние.
329
+
330
+ ### Игнорирование индексации ###
331
+
332
+ Несмотря на то, что индекс может быть удивительно полезным для создания коммитов именно такими, как вам и хотелось, он временами несколько сложнее, чем вам нужно в процессе работы. Если у вас есть желание пропустить этап индексирования, Git предоставляет простой способ. Добавление параметра `-a` в команду `git commit` заставляет Git автоматически индексировать каждый уже отслеживаемый на момент коммита файл, позволяя вам обойтись без `git add`:
333
+
334
+ $ git status
335
+ # On branch master
336
+ #
337
+ # Changes not staged for commit:
338
+ #
339
+ # modified: benchmarks.rb
340
+ #
341
+ $ git commit -a -m 'added new benchmarks'
342
+ [master 83e38c7] added new benchmarks
343
+ 1 files changed, 5 insertions(+), 0 deletions(-)
344
+
345
+ Обратите внимание на то, что в данном случае перед коммитом вам не нужно выполнять `git add` для файла benchmarks.rb.
346
+
347
+ ### Удаление файлов ###
348
+
349
+ Для того чтобы удалить файл из Git'а, вам необходимо удалить его из отслеживаемых файлов (точнее, удалить его из вашего индекса) а затем выполнить коммит. Это позволяет сделать команда `git rm`, которая также удаляет файл из вашего рабочего каталога, так что вы в следующий раз не увидите его как “неотслеживаемый”.
350
+
351
+ Если вы просто удалите файл из своего рабочего каталога, он будет показан в секции “Changes not staged for commit” (“Изменённые но не обновлённые” — читай не проиндексированные) вывода команды `git status`:
352
+
353
+ $ rm grit.gemspec
354
+ $ git status
355
+ # On branch master
356
+ #
357
+ # Changes not staged for commit:
358
+ # (use "git add/rm <file>..." to update what will be committed)
359
+ #
360
+ # deleted: grit.gemspec
361
+ #
362
+
363
+ Затем, если вы выполните команду `git rm`, удаление файла попадёт в индекс:
364
+
365
+ $ git rm grit.gemspec
366
+ rm 'grit.gemspec'
367
+ $ git status
368
+ # On branch master
369
+ #
370
+ # Changes to be committed:
371
+ # (use "git reset HEAD <file>..." to unstage)
372
+ #
373
+ # deleted: grit.gemspec
374
+ #
375
+
376
+ После следующего коммита файл исчезнет и больше не будет отслеживаться. Если вы изменили файл и уже проиндексировали его, вы должны использовать принудительное удаление с помощью параметра `-f`. Это сделано для повышения безопасности, чтобы предотвратить ошибочное удаление данных, которые ещё не были записаны в снимок состояния и которые нельзя восстановить из Git'а.
377
+
378
+ Другая полезная штука, которую вы можете захотеть сделать — это удалить файл из индекса, оставив его при этом в рабочем каталоге. Другими словами, вы можете захотеть оставить файл на винчестере, и убрать его из-под бдительного ока Git'а. Это особенно полезно, если вы забыли добавить что-то в файл `.gitignore` и по ошибке проиндексировали, например, большой файл с логами, или кучу промежуточных файлов компиляции. Чтобы сделать это, используйте опцию `--cached`:
379
+
380
+ $ git rm --cached readme.txt
381
+
382
+ В команду `git rm` можно передавать файлы, каталоги или glob-шаблоны. Это означает, что вы можете вытворять что-то вроде:
383
+
384
+ $ git rm log/\*.log
385
+
386
+ Обратите внимание на обратный слэш (`\`) перед `*`. Он необходим из-за того, что Git использует свой собственный обработчик имён файлов вдобавок к обработчику вашего командного интерпретатора. Эта команда удаляет все файлы, которые имеют расширение `.log` в каталоге `log/`. Или же вы можете сделать вот так:
387
+
388
+ $ git rm \*~
389
+
390
+ Эта команда удаляет все файлы, чьи имена заканчиваются на `~`.
391
+
392
+ ### Перемещение файлов ###
393
+
394
+ В отличие от многих других систем версионного контроля, Git не отслеживает перемещение файлов явно. Когда вы переименовываете файл в Git'е, в нём не сохраняется никаких метаданных, говорящих о том, что файл был переименован. Однако, Git довольно умён в плане обнаружения перемещений постфактум — мы рассмотрим обнаружение перемещения файлов чуть позже.
395
+
396
+ Таким образом, наличие в Git'е команды `mv` выглядит несколько странным. Если вам хочется переименовать файл в Git'е, вы можете сделать что-то вроде:
397
+
398
+ $ git mv file_from file_to
399
+
400
+ и это отлично сработает. На самом деле, если вы выполните что-то вроде этого и посмотрите на статус, вы увидите, что Git считает, что произошло переименование файла:
401
+
402
+ $ git mv README.txt README
403
+ $ git status
404
+ # On branch master
405
+ # Your branch is ahead of 'origin/master' by 1 commit.
406
+ #
407
+ # Changes to be committed:
408
+ # (use "git reset HEAD <file>..." to unstage)
409
+ #
410
+ # renamed: README.txt -> README
411
+ #
412
+
413
+ Однако, это эквивалентно выполнению следующих команд:
414
+
415
+ $ mv README.txt README
416
+ $ git rm README.txt
417
+ $ git add README
418
+
419
+ Git неявно определяет, что произошло переименование, поэтому неважно, переименуете вы файл так или используя команду `mv`. Единственное отличие состоит лишь в том, что `mv` — это одна команда вместо трёх — это функция для удобства. Важнее другое — вы можете использовать любой удобный способ, чтобы переименовать файл, и затем воспользоваться add/rm перед коммитом.
420
+
421
+ ## Просмотр истории коммитов ##
422
+
423
+ После того как вы создадите несколько коммитов, или же вы склонируете репозиторий с уже существующей историей коммитов, вы, вероятно, захотите оглянуться назад и узнать, что же происходило с этим репозиторием. Наиболее простой и в то же время мощный инструмент для этого — команда `git log`.
424
+
425
+ Данные примеры используют очень простой проект, названный simplegit, который я часто использую для демонстраций. Чтобы получить этот проект, выполните:
426
+
427
+ git clone git://github.com/schacon/simplegit-progit.git
428
+
429
+ В результате выполнения `git log` в данном проекте, вы должны получить что-то вроде этого:
430
+
431
+ $ git log
432
+ commit ca82a6dff817ec66f44342007202690a93763949
433
+ Author: Scott Chacon <schacon@gee-mail.com>
434
+ Date: Mon Mar 17 21:52:11 2008 -0700
435
+
436
+ changed the version number
437
+
438
+ commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
439
+ Author: Scott Chacon <schacon@gee-mail.com>
440
+ Date: Sat Mar 15 16:40:33 2008 -0700
441
+
442
+ removed unnecessary test code
443
+
444
+ commit a11bef06a3f659402fe7563abf99ad00de2209e6
445
+ Author: Scott Chacon <schacon@gee-mail.com>
446
+ Date: Sat Mar 15 10:31:28 2008 -0700
447
+
448
+ first commit
449
+
450
+ По умолчанию, без аргументов, `git log` выводит список коммитов созданных в данном репозитории в обратном хронологическом порядке. То есть самые последние коммиты показываются первыми. Как вы можете видеть, эта команда отображает каждый коммит вместе с его контрольной суммой SHA-1, именем и электронной почтой автора, датой создания и комментарием.
451
+
452
+ Существует превеликое множество параметров команды `git log` и их комбинаций, для того чтобы показать вам именно то, что вы ищете. Здесь мы покажем вам несколько наиболее часто применяемых.
453
+
454
+ Один из наиболее полезных параметров — это `-p`, который показывает дельту (разницу/diff), привнесенную каждым коммитом. Вы также можете использовать `-2`, что ограничит вывод до 2-х последних записей:
455
+
456
+ $ git log -p -2
457
+ commit ca82a6dff817ec66f44342007202690a93763949
458
+ Author: Scott Chacon <schacon@gee-mail.com>
459
+ Date: Mon Mar 17 21:52:11 2008 -0700
460
+
461
+ changed the version number
462
+
463
+ diff --git a/Rakefile b/Rakefile
464
+ index a874b73..8f94139 100644
465
+ --- a/Rakefile
466
+ +++ b/Rakefile
467
+ @@ -5,5 +5,5 @@ require 'rake/gempackagetask'
468
+ spec = Gem::Specification.new do |s|
469
+ s.name = "simplegit"
470
+ - s.version = "0.1.0"
471
+ + s.version = "0.1.1"
472
+ s.author = "Scott Chacon"
473
+ s.email = "schacon@gee-mail.com
474
+
475
+ commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
476
+ Author: Scott Chacon <schacon@gee-mail.com>
477
+ Date: Sat Mar 15 16:40:33 2008 -0700
478
+
479
+ removed unnecessary test code
480
+
481
+ diff --git a/lib/simplegit.rb b/lib/simplegit.rb
482
+ index a0a60ae..47c6340 100644
483
+ --- a/lib/simplegit.rb
484
+ +++ b/lib/simplegit.rb
485
+ @@ -18,8 +18,3 @@ class SimpleGit
486
+ end
487
+
488
+ end
489
+ -
490
+ -if $0 == __FILE__
491
+ - git = SimpleGit.new
492
+ - puts git.show
493
+ -end
494
+
495
+
496
+ Этот параметр показывает ту же самую информацию плюс внесённые изменения, отображаемые непосредственно после каждого коммита. Это очень удобно для инспекций кода или для того, чтобы быстро посмотреть, что происходило в результате последовательности коммитов, добавленных коллегой.
497
+
498
+ В некоторых ситуациях гораздо удобней просматривать внесённые изменения на уровне слов, а не на уровне строк. Чтобы получить дельту по словам вместо обычной дельты по строкам, нужно дописать после команды `git log -p` опцию `--word-diff`. Дельты на уровне слов практически бесполезны при работе над программным кодом, но они буду очень кстати при работе над длинным текстом, таким как книга или диссертация. Рассмотрим пример:
499
+
500
+ $ git log -U1 --word-diff
501
+ commit ca82a6dff817ec66f44342007202690a93763949
502
+ Author: Scott Chacon <schacon@gee-mail.com>
503
+ Date: Mon Mar 17 21:52:11 2008 -0700
504
+
505
+ changed the version number
506
+
507
+ diff --git a/Rakefile b/Rakefile
508
+ index a874b73..8f94139 100644
509
+ --- a/Rakefile
510
+ +++ b/Rakefile
511
+ @@ -7,3 +7,3 @@ spec = Gem::Specification.new do |s|
512
+ s.name = "simplegit"
513
+ s.version = [-"0.1.0"-]{+"0.1.1"+}
514
+ s.author = "Scott Chacon"
515
+
516
+ Как видите, в этом выводе нет ни добавленных ни удалённых строк, как для обычного diff'а. Вместо этого изменения показаны внутри строки. Добавленное слово заключено в `{+ +}`, а удалённое в `[- -]`. Также может быть полезно сократить обычные три строки контекста в выводе команды `diff` до одной строки, так как контекстом в данном случае являются слова, а не строки. Сделать это можно с помощью опции `-U1` как было показано в примере выше.
517
+
518
+ С командой `git log` вы также можете использовать группы суммирующих параметров. Например, если вы хотите получить некоторую краткую статистику по каждому коммиту, вы можете использовать параметр `--stat`:
519
+
520
+ $ git log --stat
521
+ commit ca82a6dff817ec66f44342007202690a93763949
522
+ Author: Scott Chacon <schacon@gee-mail.com>
523
+ Date: Mon Mar 17 21:52:11 2008 -0700
524
+
525
+ changed the version number
526
+
527
+ Rakefile | 2 +-
528
+ 1 files changed, 1 insertions(+), 1 deletions(-)
529
+
530
+ commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
531
+ Author: Scott Chacon <schacon@gee-mail.com>
532
+ Date: Sat Mar 15 16:40:33 2008 -0700
533
+
534
+ removed unnecessary test code
535
+
536
+ lib/simplegit.rb | 5 -----
537
+ 1 files changed, 0 insertions(+), 5 deletions(-)
538
+
539
+ commit a11bef06a3f659402fe7563abf99ad00de2209e6
540
+ Author: Scott Chacon <schacon@gee-mail.com>
541
+ Date: Sat Mar 15 10:31:28 2008 -0700
542
+
543
+ first commit
544
+
545
+ README | 6 ++++++
546
+ Rakefile | 23 +++++++++++++++++++++++
547
+ lib/simplegit.rb | 25 +++++++++++++++++++++++++
548
+ 3 files changed, 54 insertions(+), 0 deletions(-)
549
+
550
+ Как видно из лога, параметр `--stat` выводит под каждым коммитом список изменённых файлов, количество изменённых файлов, а также количество добавленных и удалённых строк в этих файлах. Он также выводит сводную информацию в конце.
551
+ Другой действительно полезный параметр — это `--pretty`. Он позволяет изменить формат вывода лога. Для вас доступны несколько предустановленных вариантов. Параметр `oneline` выводит каждый коммит в одну строку, что удобно если вы просматриваете большое количество коммитов. В дополнение к этому, параметры `short`, `full`, и `fuller`, практически не меняя формат вывода, позволяют выводить меньше или больше деталей соответственно:
552
+
553
+ $ git log --pretty=oneline
554
+ ca82a6dff817ec66f44342007202690a93763949 changed the version number
555
+ 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test code
556
+ a11bef06a3f659402fe7563abf99ad00de2209e6 first commit
557
+
558
+ Наиболее интересный параметр — это `format`, который позволяет вам полностью создать собственный формат вывода лога. Это особенно полезно, когда вы создаёте отчёты для автоматического разбора (парсинга) — поскольку вы явно задаёте формат и уверены в том, что он не будет изменяться при обновлениях Git'а:
559
+
560
+ $ git log --pretty=format:"%h - %an, %ar : %s"
561
+ ca82a6d - Scott Chacon, 11 months ago : changed the version number
562
+ 085bb3b - Scott Chacon, 11 months ago : removed unnecessary test code
563
+ a11bef0 - Scott Chacon, 11 months ago : first commit
564
+
565
+ Таблица 2-1 содержит список наиболее полезных параметров формата.
566
+
567
+ Параметр Описание выводимых данных
568
+ %H Хеш коммита
569
+ %h Сокращённый хеш коммита
570
+ %T Хеш дерева
571
+ %t Сокращённый хеш дерева
572
+ %P Хеши родительских коммитов
573
+ %p Сокращённые хеши родительских коммитов
574
+ %an Имя автора
575
+ %ae Электронная почта автора
576
+ %ad Дата автора (формат соответствует параметру `--date=`)
577
+ %ar Дата автора, относительная (пр. "2 мес. назад")
578
+ %cn Имя коммитера
579
+ %ce Электронная почта коммитера
580
+ %cd Дата коммитера
581
+ %cr Дата коммитера, относительная
582
+ %s Комментарий
583
+
584
+ Вас может заинтересовать, в чём же разница между _автором_ и _коммитером_. Автор — это человек, изначально сделавший работу, тогда как коммитер — это человек, который последним применил эту работу. Так что если вы послали патч (заплатку) в проект и один из основных разработчиков применил этот патч, вы оба не будете забыты — вы как автор, а разработчик как коммитер. Мы чуть подробнее рассмотрим это различие в главе 5.
585
+
586
+ Параметры `oneline` и `format` также полезны с другим параметром команды `log` — `--graph`. Этот параметр добавляет миленький ASCII-граф, показывающий историю ветвлений и слияний. Один из таких можно увидеть для нашей копии репозитория проекта Grit:
587
+
588
+ $ git log --pretty=format:"%h %s" --graph
589
+ * 2d3acf9 ignore errors from SIGCHLD on trap
590
+ * 5e3ee11 Merge branch 'master' of git://github.com/dustin/grit
591
+ |\
592
+ | * 420eac9 Added a method for getting the current branch.
593
+ * | 30e367c timeout code and tests
594
+ * | 5a09431 add timeout protection to grit
595
+ * | e1193f8 support for heads with slashes in them
596
+ |/
597
+ * d6016bc require time for xmlschema
598
+ * 11d191e Merge branch 'defunkt' into local
599
+
600
+ Мы рассмотрели только самые простые параметры форматирования вывода для `git log` — их гораздо больше. Таблица 2-2 содержит как уже рассмотренные нами параметры, так и другие полезные параметры вместе с описанием того, как они влияют на вывод команды `log`.
601
+
602
+ Параметр Описание
603
+ -p Для каждого коммита показывать дельту внесённых им изменений.
604
+ --word-diff Показывать изменения на уровне слов.
605
+ --stat Для каждого коммита дополнительно выводить статистику по изменённым файлам.
606
+ --shortstat Показывать только строку changed/insertions/deletions от вывода с опцией `--stat`.
607
+ --name-only Показывать список изменённых файлов после информации о коммите.
608
+ --name-status Выводить список изменённых файлов вместе с информацией о добавлении/изменении/удалении.
609
+ --abbrev-commit Выводить только первые несколько символов контрольной суммы SHA-1 вместо всех 40.
610
+ --relative-date Выводить дату в относительном формате (например, "2 weeks ago") вместо полной даты.
611
+ --graph Показывать ASCII-граф истории ветвлений и слияний рядом с выводом лога.
612
+ --pretty Отображать коммиты в альтернативном формате. Возможные параметры: `oneline`, `short`, `full`, `fuller` и `format` (где вы можете указать свой собственный формат).
613
+
614
+ ### Ограничение вывода команды log ###
615
+
616
+ Кроме опций для форматирования вывода, `git log` имеет ряд полезных ограничительных параметров, то есть параметров, которые дают возможность отобразить часть коммитов. Вы уже видели один из таких параметров — параметр `-2`, который отображает только два последних коммита. На самом деле, вы можете задать `-<n>`, где `n` это количество отображаемых коммитов. На практике вам вряд ли придётся часто этим пользоваться потому, что по умолчанию Git через канал (pipe) отправляет весь вывод на pager, так что вы всегда будете видеть только одну страницу.
617
+
618
+ А вот параметры, ограничивающие по времени, такие как `--since` и `--until`, весьма полезны. Например, следующая команда выдаёт список коммитов, сделанных за последние две недели:
619
+
620
+ $ git log --since=2.weeks
621
+
622
+ Такая команда может работать с множеством форматов — вы можете указать точную дату (“2008-01-15”) или относительную дату, такую как “2 years 1 day 3 minutes ago”.
623
+
624
+ Вы также можете отфильтровать список коммитов по какому-либо критерию поиска. Опция `--author` позволяет фильтровать по автору, опция `--grep` позволяет искать по ключевым словам в сообщении. (Заметим, что, если вы укажете и опцию `author`, и опцию `grep`, то будут найдены все коммиты, которые удовлетворяют первому ИЛИ второму критерию. Чтобы найти коммиты, которые удовлетворяют первому И второму критерию, следует добавить опцию `--all-match`.)
625
+
626
+ Последняя действительно полезная опция-фильтр для `git log` — это путь. Указав имя каталога или файла, вы ограничите вывод log теми коммитами, которые вносят изменения в указанные файлы. Эта опция всегда указывается последней и обычно предваряется двумя минусами (`--`), чтобы отделить пути от остальных опций.
627
+
628
+ В таблице 2-3 для справки приведён список часто употребляемых опций.
629
+
630
+ Опция Описание
631
+ -(n) Показать последние n коммитов
632
+ --since, --after Ограничить коммиты теми, которые сделаны после указанной даты.
633
+ --until, --before Ограничить коммиты теми, которые сделаны до указанной даты.
634
+ --author Показать только те коммиты, автор которых соответствует указанной строке.
635
+ --committer Показать только те коммиты, коммитер которых соответствует указанной строке.
636
+
637
+ Например, если вы хотите посмотреть из истории Git'а такие коммиты, которые вносят изменения в тестовые файлы, были сделаны Junio Hamano, не являются слияниями и были сделаны в октябре 2008го, вы можете выполнить что-то вроде такого:
638
+
639
+ $ git log --pretty="%h - %s" --author=gitster --since="2008-10-01" \
640
+ --before="2008-11-01" --no-merges -- t/
641
+ 5610e3b - Fix testcase failure when extended attribute
642
+ acd3b9e - Enhance hold_lock_file_for_{update,append}()
643
+ f563754 - demonstrate breakage of detached checkout wi
644
+ d1a43f2 - reset --hard/read-tree --reset -u: remove un
645
+ 51a94af - Fix "checkout --track -b newbranch" on detac
646
+ b0ad11e - pull: allow "git pull origin $something:$cur
647
+
648
+ Из примерно 20 000 коммитов в истории Git'а, данная команда выбрала всего 6 коммитов, соответствующих заданным критериям.
649
+
650
+ ### Использование графического интерфейса для визуализации истории ###
651
+
652
+ Если у вас есть желание использовать какой-нибудь графический инструмент для визуализации истории коммитов, можно попробовать распространяемую вместе с Git'ом программу gitk, написанную на Tcl/Tk. В сущности gitk — это наглядный вариант `git log`, к тому же он принимает почти те же фильтрующие опции, что и `git log`. Если наберёте в командной строке gitk, находясь в проекте, то увидите что-то наподобие рис. 2-2.
653
+
654
+ Insert 18333fig0202.png
655
+ Рисунок 2-2. Визуализация истории с помощью gitk.
656
+
657
+ В верхней части окна располагается история коммитов вместе с подробным графом наследников. Просмотрщик дельт в нижней половине окна отображает изменения, сделанные выбранным коммитом. Указать коммит можно с помощью щелчка мышью.
658
+
659
+ ## Отмена изменений ##
660
+
661
+ На любой стадии может возникнуть необходимость что-либо отменить. Здесь мы рассмотрим несколько основных инструментов для отмены произведённых изменений. Будьте осторожны, ибо не всегда можно отменить сами отмены. Это одно из немногих мест в Git'е, где вы можете потерять свою работу если сделаете что-то неправильно.
662
+
663
+ ### Изменение последнего коммита ###
664
+
665
+ Одна из типичных отмен происходит тогда, когда вы делаете коммит слишком рано, забыв добавить какие-то файлы, или напутали с комментарием к коммиту. Если вам хотелось бы сделать этот коммит ещё раз, вы можете выполнить commit с опцией `--amend`:
666
+
667
+ $ git commit --amend
668
+
669
+ Эта команда берёт индекс и использует его для коммита. Если после последнего коммита не было никаких изменений (например, вы запустили приведённую команду сразу после предыдущего коммита), то состояние проекта будет абсолютно таким же и всё, что вы измените, это комментарий к коммиту.
670
+
671
+ Появится всё тот же редактор для комментариев к коммитам, но уже с введённым комментарием к последнему коммиту. Вы можете отредактировать это сообщение так же, как обычно, и оно перепишет предыдущее.
672
+
673
+ Для примера, если после совершения коммита вы осознали, что забыли проиндексировать изменения в файле, которые хотели добавить в этот коммит, вы можете сделать что-то подобное:
674
+
675
+ $ git commit -m 'initial commit'
676
+ $ git add forgotten_file
677
+ $ git commit --amend
678
+
679
+ Все три команды вместе дают один коммит — второй коммит заменяет результат первого.
680
+
681
+ ### Отмена индексации файла ###
682
+
683
+ В следующих двух разделах мы продемонстрируем, как переделать изменения в индексе и в рабочем каталоге. Приятно то, что команда, используемая для определения состояния этих двух вещей, дополнительно напоминает о том, как отменить изменения в них. Приведём пример. Допустим, вы внесли изменения в два файла и хотите записать их как два отдельных коммита, но случайно набрали `git add *` и проиндексировали оба файла. Как теперь отменить индексацию одного из двух файлов? Команда `git status` напомнит вам об этом:
684
+
685
+ $ git add .
686
+ $ git status
687
+ # On branch master
688
+ # Changes to be committed:
689
+ # (use "git reset HEAD <file>..." to unstage)
690
+ #
691
+ # modified: README.txt
692
+ # modified: benchmarks.rb
693
+ #
694
+
695
+ Сразу после надписи “Changes to be committed”, написано использовать `git reset HEAD <файл>...` для исключения из индекса. Так что давайте последуем совету и отменим индексацию файла benchmarks.rb:
696
+
697
+ $ git reset HEAD benchmarks.rb
698
+ benchmarks.rb: locally modified
699
+ $ git status
700
+ # On branch master
701
+ # Changes to be committed:
702
+ # (use "git reset HEAD <file>..." to unstage)
703
+ #
704
+ # modified: README.txt
705
+ #
706
+ # Changes not staged for commit:
707
+ # (use "git add <file>..." to update what will be committed)
708
+ # (use "git checkout -- <file>..." to discard changes in working directory)
709
+ #
710
+ # modified: benchmarks.rb
711
+ #
712
+
713
+ Эта команда немного странновата, но она работает. Файл benchmarks.rb изменён, но снова не в индексе.
714
+
715
+ ### Отмена изменений файла ###
716
+
717
+ Что, если вы поняли, что не хотите оставлять изменения, внесённые в файл benchmarks.rb? Как быстро отменить изменения, вернуть то состояние, в котором он находился во время последнего коммита (или первоначального клонирования, или какого-то другого действия, после которого файл попал в рабочий каталог)? К счастью, `git status` говорит, как добиться и этого. В выводе для последнего примера, неиндексированная область выглядит следующим образом:
718
+
719
+ # Changes not staged for commit:
720
+ # (use "git add <file>..." to update what will be committed)
721
+ # (use "git checkout -- <file>..." to discard changes in working directory)
722
+ #
723
+ # modified: benchmarks.rb
724
+ #
725
+
726
+ Здесь довольно ясно сказано, как отменить сделанные изменения (по крайней мере новые версии Git'а, начиная с 1.6.1, делают это; если у вас версия старее, мы настоятельно рекомендуем обновиться, чтобы получать такие подсказки и сделать свою работу удобней). Давайте сделаем то, что написано:
727
+
728
+ $ git checkout -- benchmarks.rb
729
+ $ git status
730
+ # On branch master
731
+ # Changes to be committed:
732
+ # (use "git reset HEAD <file>..." to unstage)
733
+ #
734
+ # modified: README.txt
735
+ #
736
+
737
+ Как вы видите, изменения были отменены. Вы должны понимать, что это опасная команда: все сделанные вами изменения в этом файле пропали — вы просто скопировали поверх него другой файл. Никогда не используйте эту команду, если вы не полностью уверены, что этот файл вам не нужен. Если вам нужно просто сделать, чтобы он не мешался, мы рассмотрим прятание (stash) и ветвление в следующей главе; эти способы обычно более предпочтительны.
738
+
739
+ Помните, что всё, что является частью коммита в Git'е, почти всегда может быть восстановлено. Даже коммиты, которые находятся на ветках, которые были удалены, и коммиты переписанные с помощью `--amend` могут быть восстановлены (см. главу 9 для восстановления данных). Несмотря на это, всё, что никогда не попадало в коммит, вы скорее всего уже не увидите снова.
740
+
741
+ ## Работа с удалёнными репозиториями ##
742
+
743
+ Чтобы иметь возможность совместной работы над каким-либо Git-проектом, необходимо знать, как управлять удалёнными репозиториями. Удалённые репозитории — это модификации проекта, которые хранятся в интернете или ещё где-то в сети. Их может быть несколько, каждый из которых, как правило, доступен для вас либо только на чтение, либо на чтение и запись. Совместная работа включает в себя управление удалёнными репозиториями и помещение (push) и получение (pull) данных в и из них тогда, когда нужно обменяться результатами работы.
744
+ Управление удалёнными репозиториями включает умение добавлять удалённые репозитории, удалять те из них, которые больше не действуют, умение управлять различными удалёнными ветками и определять их как отслеживаемые (tracked) или нет и прочее. Данный раздел охватывает все перечисленные навыки по управлению удалёнными репозиториями.
745
+
746
+ ### Отображение удалённых репозиториев ###
747
+
748
+ Чтобы просмотреть, какие удалённые серверы у вас уже настроены, следует выполнить команду `git remote`. Она перечисляет список имён-сокращений для всех уже указанных удалённых дескрипторов. Если вы склонировали ваш репозиторий, у вас должен отобразиться, по крайней мере, origin — это имя по умолчанию, которое Git присваивает серверу, с которого вы склонировали:
749
+
750
+ $ git clone git://github.com/schacon/ticgit.git
751
+ Initialized empty Git repository in /private/tmp/ticgit/.git/
752
+ remote: Counting objects: 595, done.
753
+ remote: Compressing objects: 100% (269/269), done.
754
+ remote: Total 595 (delta 255), reused 589 (delta 253)
755
+ Receiving objects: 100% (595/595), 73.31 KiB | 1 KiB/s, done.
756
+ Resolving deltas: 100% (255/255), done.
757
+ $ cd ticgit
758
+ $ git remote
759
+ origin
760
+
761
+ Чтобы посмотреть, какому URL соответствует сокращённое имя в Git, можно указать команде опцию `-v`:
762
+
763
+ $ git remote -v
764
+ origin git://github.com/schacon/ticgit.git (fetch)
765
+ origin git://github.com/schacon/ticgit.git (push)
766
+
767
+ Если у вас больше одного удалённого репозитория, команда покажет их все. Например, мой репозиторий Grit выглядит следующим образом.
768
+
769
+ $ cd grit
770
+ $ git remote -v
771
+ bakkdoor git://github.com/bakkdoor/grit.git
772
+ cho45 git://github.com/cho45/grit.git
773
+ defunkt git://github.com/defunkt/grit.git
774
+ koke git://github.com/koke/grit.git
775
+ origin git@github.com:mojombo/grit.git
776
+
777
+ Это означает, что мы легко можем получить изменения от любого из этих пользователей. Но, заметьте, что origin — это единственный удалённый сервер прописанный как SSH-ссылка, поэтому он единственный, в который я могу помещать свои изменения (это будет рассмотрено в главе 4).
778
+
779
+ ### Добавление удалённых репозиториев ###
780
+
781
+ В предыдущих разделах мы упомянули и немного продемонстрировали добавление удалённых репозиториев, сейчас мы рассмотрим это более детально. Чтобы добавить новый удалённый Git-репозиторий под именем-сокращением, к которому будет проще обращаться, выполните `git remote add [сокращение] [url]`:
782
+
783
+ $ git remote
784
+ origin
785
+ $ git remote add pb git://github.com/paulboone/ticgit.git
786
+ $ git remote -v
787
+ origin git://github.com/schacon/ticgit.git
788
+ pb git://github.com/paulboone/ticgit.git
789
+
790
+ Теперь вы можете использовать в командной строке имя pb вместо полного URL. Например, если вы хотите извлечь (fetch) всю информацию, которая есть в репозитории Павла, но нет в вашем, вы можете выполнить `git fetch pb`:
791
+
792
+ $ git fetch pb
793
+ remote: Counting objects: 58, done.
794
+ remote: Compressing objects: 100% (41/41), done.
795
+ remote: Total 44 (delta 24), reused 1 (delta 0)
796
+ Unpacking objects: 100% (44/44), done.
797
+ From git://github.com/paulboone/ticgit
798
+ * [new branch] master -> pb/master
799
+ * [new branch] ticgit -> pb/ticgit
800
+
801
+ Ветка master Павла теперь доступна локально как `pb/master`. Вы можете слить (merge) её в одну из своих веток или перейти на эту ветку, если хотите её проверить.
802
+
803
+ ### Fetch и Pull ###
804
+
805
+ Как вы только что узнали, для получения данных из удалённых проектов, следует выполнить:
806
+
807
+ $ git fetch [имя удал. сервера]
808
+
809
+ Данная команда связывается с указанным удалённым проектом и забирает все те данные проекта, которых у вас ещё нет. После того как вы выполнили команду, у вас должны появиться ссылки на все ветки из этого удалённого проекта. Теперь эти ветки в любой момент могут быть просмотрены или слиты. (В главе 3 мы перейдём к более детальному рассмотрению, что такое ветки и как их использовать.)
810
+
811
+ Когда вы клонируете репозиторий, команда clone автоматически добавляет этот удалённый репозиторий под именем origin. Таким образом, `git fetch origin` извлекает все наработки, отправленные (push) на этот сервер после того, как вы склонировали его (или получили изменения с помощью fetch). Важно отметить, что команда `fetch` забирает данные в ваш локальный репозиторий, но не сливает их с какими-либо вашими наработками и не модифицирует то, над чем вы работаете в данный момент. Вам необходимо вручную слить эти данные с вашими, когда вы будете готовы.
812
+
813
+ Если у вас есть ветка, настроенная на отслеживание удалённой ветки (для дополнительной информации смотри следующий раздел и главу 3), то вы можете использовать команду `git pull`. Она автоматически извлекает и затем сливает данные из удалённой ветки в вашу текущую ветку. Этот способ может для вас оказаться более простым или более удобным. К тому же по умолчанию команда `git clone` автоматически настраивает вашу локальную ветку master на отслеживание удалённой ветки master на сервере, с которого вы клонировали (подразумевается, что на удалённом сервере есть ветка master). Выполнение `git pull`, как правило, извлекает (fetch) данные с сервера, с которого вы изначально склонировали, и автоматически пытается слить (merge) их с кодом, над которым вы в данный момент работаете.
814
+
815
+ ### Push ###
816
+
817
+ Когда вы хотите поделиться своими наработками, вам необходимо отправить (push) их в главный репозиторий. Команда для этого действия простая: `git push [удал. сервер] [ветка]`. Чтобы отправить вашу ветку master на сервер `origin` (повторимся, что клонирование, как правило, настраивает оба этих имени автоматически), вы можете выполнить следующую команду для отправки наработок на сервер:
818
+
819
+ $ git push origin master
820
+
821
+ Эта команда срабатывает только в случае, если вы клонировали с сервера, на котором у вас есть права на запись, и если никто другой с тех пор не выполнял команду push. Если вы и кто-то ещё одновременно клонируете, затем он выполняет команду push, а затем команду push выполняете вы, то ваш push точно будет отклонён. Вам придётся сначала вытянуть (pull) их изменения и объединить с вашими. Только после этого вам будет позволено выполнить push. Смотри главу 3 для более подробного описания, как отправлять (push) данные на удалённый сервер.
822
+
823
+ ### Инспекция удалённого репозитория ###
824
+
825
+ Если хотите получить побольше информации об одном из удалённых репозиториев, вы можете использовать команду `git remote show [удал. сервер]`. Если вы выполните эту команду с некоторым именем, например, `origin`, вы получите что-то подобное:
826
+
827
+ $ git remote show origin
828
+ * remote origin
829
+ URL: git://github.com/schacon/ticgit.git
830
+ Remote branch merged with 'git pull' while on branch master
831
+ master
832
+ Tracked remote branches
833
+ master
834
+ ticgit
835
+
836
+ Она выдаёт URL удалённого репозитория, а также информацию об отслеживаемых ветках. Эта команда любезно сообщает вам, что если вы, находясь на ветке master, выполните `git pull`, ветка master с удалённого сервера будет автоматически влита в вашу сразу после получения всех необходимых данных. Она также выдаёт список всех полученных ею ссылок.
837
+
838
+ Это был пример для простой ситуации, и наверняка вы встретились с чем-то подобным. Однако, если вы используете Git более интенсивно, вы можете увидеть гораздо большее количество информации от `git remote show`:
839
+
840
+ $ git remote show origin
841
+ * remote origin
842
+ URL: git@github.com:defunkt/github.git
843
+ Remote branch merged with 'git pull' while on branch issues
844
+ issues
845
+ Remote branch merged with 'git pull' while on branch master
846
+ master
847
+ New remote branches (next fetch will store in remotes/origin)
848
+ caching
849
+ Stale tracking branches (use 'git remote prune')
850
+ libwalker
851
+ walker2
852
+ Tracked remote branches
853
+ acl
854
+ apiv2
855
+ dashboard2
856
+ issues
857
+ master
858
+ postgres
859
+ Local branch pushed with 'git push'
860
+ master:master
861
+
862
+ Данная команда показывает какая именно локальная ветка будет отправлена на удалённый сервер по умолчанию при выполнении `git push`. Она также показывает, каких веток с удалённого сервера у вас ещё нет, какие ветки всё ещё есть у вас, но уже удалены на сервере. И для нескольких веток показано, какие удалённые ветки будут в них влиты при выполнении `git pull`.
863
+
864
+ ### Удаление и переименование удалённых репозиториев ###
865
+
866
+ Для переименования ссылок в новых версиях Git'а можно вылолнить `git remote rename`, это изменит сокращённое имя, используемое для удалённого репозитория. Например, если вы хотите переименовать `pb` в `paul`, вы можете сделать это следующим образом:
867
+
868
+ $ git remote rename pb paul
869
+ $ git remote
870
+ origin
871
+ paul
872
+
873
+ Стоит упомянуть, что это также меняет для вас имена удалённых веток. То, к чему вы обращались как `pb/master`, стало `paul/master`.
874
+
875
+ Если по какой-то причине вы хотите удалить ссылку (вы сменили сервер или больше не используете определённое зеркало, или, возможно, контрибьютор перестал быть активным), вы можете использовать `git remote rm`:
876
+
877
+ $ git remote rm paul
878
+ $ git remote
879
+ origin
880
+
881
+ ## Работа с метками ##
882
+
883
+ Как и большинство СКВ, Git имеет возможность помечать (tag) определённые моменты в истории как важные. Как правило, этот функционал используется для отметки моментов выпуска версий (v1.0, и т.п.). В этом разделе вы узнаете, как посмотреть имеющиеся метки (tag), как создать новые. А также вы узнаете, что из себя представляют разные типы меток.
884
+
885
+ ### Просмотр меток ###
886
+
887
+ Просмотр имеющихся меток (tag) в Git'е делается просто. Достаточно набрать `git tag`:
888
+
889
+ $ git tag
890
+ v0.1
891
+ v1.3
892
+
893
+ Данная команда перечисляет метки в алфавитном порядке; порядок их появления не имеет значения.
894
+
895
+ Для меток вы также можете осуществлять поиск по шаблону. Например, репозиторий Git'а содержит более 240 меток. Если вас интересует просмотр только выпусков 1.4.2, вы можете выполнить следующее:
896
+
897
+ $ git tag -l 'v1.4.2.*'
898
+ v1.4.2.1
899
+ v1.4.2.2
900
+ v1.4.2.3
901
+ v1.4.2.4
902
+
903
+ ### Создание меток ###
904
+
905
+ Git использует два основных типа меток: легковесные и аннотированные. Легковесная метка — это что-то весьма похожее на ветку, которая не меняется — это просто указатель на определённый коммит. А вот аннотированные метки хранятся в базе данных Git'а как полноценные объекты. Они имеют контрольную сумму, содержат имя поставившего метку, e-mail и дату, имеют комментарий и могут быть подписаны и проверены с помощью GNU Privacy Guard (GPG). Обычно рекомендуется создавать аннотированные метки, чтобы иметь всю перечисленную информацию; но если вы хотите сделать временную метку или по какой-то причине не хотите сохранять остальную информацию, то для этого годятся и легковесные метки.
906
+
907
+ ### Аннотированные метки ###
908
+
909
+ Создание аннотированной метки в Git'е выполняется легко. Самый простой способ это указать `-a` при выполнении команды `tag`:
910
+
911
+ $ git tag -a v1.4 -m 'my version 1.4'
912
+ $ git tag
913
+ v0.1
914
+ v1.3
915
+ v1.4
916
+
917
+ Опция `-m` задаёт меточное сообщение, которое будет храниться вместе с меткой. Если не указать сообщение для аннотированной метки, Git запустит редактор, чтоб вы смогли его ввести.
918
+
919
+ Вы можете посмотреть данные метки вместе с коммитом, который был помечен, с помощью команды `git show`:
920
+
921
+ $ git show v1.4
922
+ tag v1.4
923
+ Tagger: Scott Chacon <schacon@gee-mail.com>
924
+ Date: Mon Feb 9 14:45:11 2009 -0800
925
+
926
+ my version 1.4
927
+ commit 15027957951b64cf874c3557a0f3547bd83b3ff6
928
+ Merge: 4a447f7... a6b4c97...
929
+ Author: Scott Chacon <schacon@gee-mail.com>
930
+ Date: Sun Feb 8 19:02:46 2009 -0800
931
+
932
+ Merge branch 'experiment'
933
+
934
+ Она показывает информацию о выставившем метку, дату отметки коммита и аннотирующее сообщение перед информацией о коммите.
935
+
936
+ ### Подписанные метки ###
937
+
938
+ Вы также можете подписывать свои метки с помощью GPG, конечно, если у вас есть ключ. Всё что нужно сделать, это использовать `-s` вместо `-a`:
939
+
940
+ $ git tag -s v1.5 -m 'my signed 1.5 tag'
941
+ You need a passphrase to unlock the secret key for
942
+ user: "Scott Chacon <schacon@gee-mail.com>"
943
+ 1024-bit DSA key, ID F721C45A, created 2009-02-09
944
+
945
+ Если вы выполните `git show` на этой метке, то увидите прикреплённую к ней GPG-подпись:
946
+
947
+ $ git show v1.5
948
+ tag v1.5
949
+ Tagger: Scott Chacon <schacon@gee-mail.com>
950
+ Date: Mon Feb 9 15:22:20 2009 -0800
951
+
952
+ my signed 1.5 tag
953
+ -----BEGIN PGP SIGNATURE-----
954
+ Version: GnuPG v1.4.8 (Darwin)
955
+
956
+ iEYEABECAAYFAkmQurIACgkQON3DxfchxFr5cACeIMN+ZxLKggJQf0QYiQBwgySN
957
+ Ki0An2JeAVUCAiJ7Ox6ZEtK+NvZAj82/
958
+ =WryJ
959
+ -----END PGP SIGNATURE-----
960
+ commit 15027957951b64cf874c3557a0f3547bd83b3ff6
961
+ Merge: 4a447f7... a6b4c97...
962
+ Author: Scott Chacon <schacon@gee-mail.com>
963
+ Date: Sun Feb 8 19:02:46 2009 -0800
964
+
965
+ Merge branch 'experiment'
966
+
967
+ Чуть позже вы узнаете, как верифицировать метки с подписью.
968
+
969
+ ### Легковесные метки ###
970
+
971
+ Легковесная метка — это ещё один способ отметки коммитов. В сущности, это контрольная сумма коммита, сохранённая в файл — больше никакой информации не хранится. Для создания легковесной метки не передавайте опций `-a`, `-s` и `-m`:
972
+
973
+ $ git tag v1.4-lw
974
+ $ git tag
975
+ v0.1
976
+ v1.3
977
+ v1.4
978
+ v1.4-lw
979
+ v1.5
980
+
981
+ На этот раз при выполнении `git show` на этой метке вы не увидите дополнительной информации. Команда просто покажет помеченный коммит:
982
+
983
+ $ git show v1.4-lw
984
+ commit 15027957951b64cf874c3557a0f3547bd83b3ff6
985
+ Merge: 4a447f7... a6b4c97...
986
+ Author: Scott Chacon <schacon@gee-mail.com>
987
+ Date: Sun Feb 8 19:02:46 2009 -0800
988
+
989
+ Merge branch 'experiment'
990
+
991
+ ### Верификация меток ###
992
+
993
+ Для верификации подписанной метки, используйте `git tag -v [имя метки]`. Эта команда использует GPG для верификации подписи. Вам нужен открытый ключ автора подписи, чтобы команда работала правильно:
994
+
995
+ $ git tag -v v1.4.2.1
996
+ object 883653babd8ee7ea23e6a5c392bb739348b1eb61
997
+ type commit
998
+ tag v1.4.2.1
999
+ tagger Junio C Hamano <junkio@cox.net> 1158138501 -0700
1000
+
1001
+ GIT 1.4.2.1
1002
+
1003
+ Minor fixes since 1.4.2, including git-mv and git-http with alternates.
1004
+ gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
1005
+ gpg: Good signature from "Junio C Hamano <junkio@cox.net>"
1006
+ gpg: aka "[jpeg image of size 1513]"
1007
+ Primary key fingerprint: 3565 2A26 2040 E066 C9A7 4A7D C0C6 D9A4 F311 9B9A
1008
+
1009
+ Если у вас нет открытого ключа автора подписи, вы вместо этого получите что-то подобное:
1010
+
1011
+ gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
1012
+ gpg: Can't check signature: public key not found
1013
+ error: could not verify the tag 'v1.4.2.1'
1014
+
1015
+ ### Выставление меток позже ###
1016
+
1017
+ Также возможно помечать уже пройденные коммиты. Предположим, что история коммитов выглядит следующим образом:
1018
+
1019
+ $ git log --pretty=oneline
1020
+ 15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
1021
+ a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support
1022
+ 0d52aaab4479697da7686c15f77a3d64d9165190 one more thing
1023
+ 6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'experiment'
1024
+ 0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc added a commit function
1025
+ 4682c3261057305bdd616e23b64b0857d832627b added a todo file
1026
+ 166ae0c4d3f420721acbb115cc33848dfcc2121a started write support
1027
+ 9fceb02d0ae598e95dc970b74767f19372d61af8 updated rakefile
1028
+ 964f16d36dfccde844893cac5b347e7b3d44abbc commit the todo
1029
+ 8a5cbc430f1a9c3d00faaeffd07798508422908a updated readme
1030
+
1031
+ Теперь предположим, что вы забыли отметить версию проекта v1.2, которая была там, где находится коммит "updated rakefile". Вы можете добавить метку и позже. Для отметки коммита укажите его контрольную сумму (или её часть) в конце команды:
1032
+
1033
+ $ git tag -a v1.2 -m 'version 1.2' 9fceb02
1034
+
1035
+ Можете проверить, что коммит теперь отмечен:
1036
+
1037
+ $ git tag
1038
+ v0.1
1039
+ v1.2
1040
+ v1.3
1041
+ v1.4
1042
+ v1.4-lw
1043
+ v1.5
1044
+
1045
+ $ git show v1.2
1046
+ tag v1.2
1047
+ Tagger: Scott Chacon <schacon@gee-mail.com>
1048
+ Date: Mon Feb 9 15:32:16 2009 -0800
1049
+
1050
+ version 1.2
1051
+ commit 9fceb02d0ae598e95dc970b74767f19372d61af8
1052
+ Author: Magnus Chacon <mchacon@gee-mail.com>
1053
+ Date: Sun Apr 27 20:43:35 2008 -0700
1054
+
1055
+ updated rakefile
1056
+ ...
1057
+
1058
+ ### Обмен метками ###
1059
+
1060
+ По умолчанию, команда `git push` не отправляет метки на удалённые серверы. Необходимо явно отправить (push) метки на общий сервер после того, как вы их создали. Это делается так же, как и выкладывание в совместное пользование удалённых веток — нужно выполнить `git push origin [имя метки]`.
1061
+
1062
+ $ git push origin v1.5
1063
+ Counting objects: 50, done.
1064
+ Compressing objects: 100% (38/38), done.
1065
+ Writing objects: 100% (44/44), 4.56 KiB, done.
1066
+ Total 44 (delta 18), reused 8 (delta 1)
1067
+ To git@github.com:schacon/simplegit.git
1068
+ * [new tag] v1.5 -> v1.5
1069
+
1070
+ Если у вас есть много меток, которые хотелось бы отправить все за один раз, можно использовать опцию `--tags` для команды `git push`. В таком случае все ваши метки отправятся на удалённый сервер (если только их уже там нет).
1071
+
1072
+ $ git push origin --tags
1073
+ Counting objects: 50, done.
1074
+ Compressing objects: 100% (38/38), done.
1075
+ Writing objects: 100% (44/44), 4.56 KiB, done.
1076
+ Total 44 (delta 18), reused 8 (delta 1)
1077
+ To git@github.com:schacon/simplegit.git
1078
+ * [new tag] v0.1 -> v0.1
1079
+ * [new tag] v1.2 -> v1.2
1080
+ * [new tag] v1.4 -> v1.4
1081
+ * [new tag] v1.4-lw -> v1.4-lw
1082
+ * [new tag] v1.5 -> v1.5
1083
+
1084
+ Теперь, если кто-то склонирует (clone) или выполнит `git pull` из вашего репозитория, то он получит вдобавок к остальному и ваши метки.
1085
+
1086
+ ## Полезные советы ##
1087
+
1088
+ Перед тем как закончить данную главу об основах Git'а, дадим несколько полезных советов о том, как сделать ваш опыт работы с Git'ом проще, удобнее или привычнее. Многие люди используют Git, не прибегая к этим советам, и мы дальше в книге не будем ссылаться на них или подразумевать, что вы ими пользуетесь, но вам всё же стоит знать о них.
1089
+
1090
+ ### Автоматическое дополнение ###
1091
+
1092
+ Если вы используете командную оболочку Bash, Git поставляется с замечательным сценарием (script), который вы можете активировать. Скачайте исходный код Git'а и посмотрите в каталоге `contrib/completion`; там должен быть файл `git-completion.bash`. Скопируйте этот файл в свой домашний каталог и добавьте следующее в файл `.bashrc`:
1093
+
1094
+ source ~/.git-completion.bash
1095
+
1096
+ Если вы хотите настроить автоматическое дополнение в Bash'е для всех пользователей, скопируйте этот сценарий в каталог `/opt/local/etc/bash_completion.d` на Mac-системах или в каталог `/etc/bash_completion.d/` на Linux-системах. Это каталог, из которого Bash автоматически загружает сценарии для автодополнения.
1097
+
1098
+ Если вы используете Git Bash на Windows, что является стандартным при установке Git'а на Windows с помощью msysGit, то автодополнение должно быть настроено заранее.
1099
+
1100
+ Нажав Tab во время ввода команды для Git'а, вы должны получить набор вариантов на выбор:
1101
+
1102
+ $ git co<tab><tab>
1103
+ commit config
1104
+
1105
+ В данном случае, набрав `git co` и дважды нажав клавишу Tab, вы получите как варианты commit и config. Добавление `m<tab>` выполнит дополнение до `git commit` автоматически.
1106
+
1107
+ То же самое работает и для опций, что, возможно, полезней. Например, если вы хотите выполнить команду `git log` и не помните какую-то опцию, вы можете начать её печатать и затем нажать Tab, чтобы увидеть, что подходит:
1108
+
1109
+ $ git log --s<tab>
1110
+ --shortstat --since= --src-prefix= --stat --summary
1111
+
1112
+ Это довольно приятная уловка, которая может сэкономить вам немного рабочего времени от чтения документации.
1113
+
1114
+ ### Псевдонимы в Git ###
1115
+
1116
+ Git не будет пытаться сделать вывод о том, какую команду вы хотели ввести, если вы ввели её неполностью. Если вы не хотите печатать каждую команду для Git'а целиком, вы легко можете настроить псевдонимы (alias) для любой команды с помощью `git config`. Вот несколько примеров псевдонимов, которые вы, возможно, захотите задать:
1117
+
1118
+ $ git config --global alias.co checkout
1119
+ $ git config --global alias.br branch
1120
+ $ git config --global alias.ci commit
1121
+ $ git config --global alias.st status
1122
+
1123
+ Это означает, что, например, вместо набирания `git commit`, вам достаточно набрать только `git ci`. По мере освоения Git'а вам, вероятно, придётся часто пользоваться и другими командами. В этом случае без колебаний создавайте новые псевдонимы.
1124
+
1125
+ Такой способ может также быть полезен для создания команд, которые, вы думаете, должны существовать. Например, чтобы исправить неудобство, с которым мы столкнулись при исключении файла из индекса, можно добавить в Git свой собственный псевдоним unstage:
1126
+
1127
+ $ git config --global alias.unstage 'reset HEAD --'
1128
+
1129
+ Это делает следующие две команды эквивалентными:
1130
+
1131
+ $ git unstage fileA
1132
+ $ git reset HEAD fileA
1133
+
1134
+ Так как будто немного понятней. Также обычно добавляют команду `last` следующим образом:
1135
+
1136
+ $ git config --global alias.last 'log -1 HEAD'
1137
+
1138
+ Так легко можно просмотреть последний коммит:
1139
+
1140
+ $ git last
1141
+ commit 66938dae3329c7aebe598c2246a8e6af90d04646
1142
+ Author: Josh Goebel <dreamer3@example.com>
1143
+ Date: Tue Aug 26 19:48:51 2008 +0800
1144
+
1145
+ test for current head
1146
+
1147
+ Signed-off-by: Scott Chacon <schacon@example.com>
1148
+
1149
+ Можно сказать, что Git просто заменяет эти новые команды на то, для чего вы создавали псевдоним (alias). Однако, возможно, вы захотите выполнять внешнюю команду, а не подкоманду Git'а. В этом случае, следует начать команду с символа `!`. Такое полезно, если вы пишите свои утилиты для работы с Git-репозиторием. Продемонстрируем этот случай на примере создания псевдонима `git visual` для запуска `gitk`:
1150
+
1151
+ $ git config --global alias.visual '!gitk'
1152
+
1153
+ ## Итоги ##
1154
+
1155
+ К этому моменту вы умеете выполнять все базовые локальные операции с Git'ом: создавать или клонировать репозиторий, вносить изменения, индексировать и фиксировать эти изменения, а также просматривать историю всех изменений в репозитории. Дальше мы рассмотрим самую убийственную особенность Git'а — его модель ветвления.