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,259 @@
1
+ # 開始 #
2
+
3
+ 本章介紹Git的相關知識。 先從講解一些版本控制工具的背景知識開始,然後試著在讀者的系統將Git跑起來,最後則是設定它。 在本章結束後,讀者應瞭解為什麼Git如 此流行、為什麼讀者應該利用它、以及完成使用它的準備工作。
4
+
5
+ ## 關於版本控制 ##
6
+
7
+ 什麼是版本控制? 以及為什麼讀者會在意它? 版本控制是一個能夠記錄一個或一組檔案在某一段時間的變更,使得讀者以後能取回特定版本的系統。 在本書的範例中,讀者會學到如何對軟體的原始碼做版本控制。 即使實際上讀者幾乎可以針對電腦上任意型態的檔案做版本控制。
8
+
9
+ 若讀者是繪圖或網頁設計師且想要記錄每一版影像或版面配置(這也通常是讀者想要做的),採用版本控制系統(VCS)做這件事是非常明智的。 它允許讀者將檔案復原到原本的狀態、將整個專案復原到先前的狀態、比對某一段時間的修改、查看最後是誰在哪個時間點做了錯誤的修改導致問題發生,等。 使用版本控制系統一般也意謂著若讀者做了一些傻事或者遺失檔案,讀者能很容易地回復到原先的狀態。 更進一步,僅需付出很小的代價即可得到這些優點。
10
+
11
+ ### 本地端版本控制 ###
12
+
13
+ 許多讀者採用複製檔案到其它目錄的方式來做版本控制(若他們夠聰明的話,或許會是有記錄時間戳記的目錄)。 因為它很簡單,這是個很常見的方法;但它也很容易出錯。 讀者很容易就忘記在哪個目錄,並不小心地把錯誤的檔案寫入、或者複製到不想要的檔案。
14
+
15
+ 為了解決這問題,程式設計師在很久以前開發了本地端的版本控制系統,具備簡單的資料庫,用來記載檔案的所有變更記錄(參考圖1-1)。
16
+
17
+ Insert 18333fig0101.png
18
+ 圖1-1. 本地端版本控制流程圖。
19
+
20
+ 這種版本控制工具中最流行的是rcs,目前仍存在於許多電腦。 即使是流行的Mac OS X作業系統,都會在讀者安裝開發工具時安裝rcs命令。 此工具基本上以特殊的格式記錄修補集合(patch set,即檔案從一個版本變更到另一個版本所需資訊),並儲存於磁碟上。 它就可以藉由套用各修補集合産生各時間點的檔案內容。
21
+
22
+ ### 集中式版本控制系統 ###
23
+
24
+ 接下來人們遇到的主要問題是需要在多種其它系統上的開發協同作業。 為了解決此問題,集中式版本控制系統(Centralized Version Control Systems,簡稱CVCSs)被發展出來。 此系統,如:CVS、Subversion及Perforce皆具備單一伺服器,記錄所有版本的檔案,且有多個客戶端從伺服器從伺服器取出檔案。 在多年後,這已經是版本控制系統的標準(參考圖1-2)。
25
+
26
+ Insert 18333fig0102.png
27
+ 圖1-2. 集中式版本控制系統
28
+
29
+ 這樣的配置提供了很多優點,特別是相較於本地端的版本控制系統來說。 例如:每個人皆能得知其它人對此專案做了些什麼修改有一定程度的瞭解。 管理員可調整存取權限,限制各使用者能做的事。 而且維護集中式版本控制系統也比維護散落在各使用者端的資料庫來的容易。
30
+
31
+ 然而,這樣的配置也有嚴重的缺點。 最明顯的就是無法連上伺服器時。 如果伺服器當機一個小時,在這段時間中沒有人能進行協同開發的工作或者將變更的部份傳遞給其他使用者。 如果伺服器用來儲存資料庫的硬碟損毀,而且沒有相關的偏份資料。 除了使用者已取到本地端電腦的版本外,包含該專案開發的歷史的所有資訊都會遺失。 本地端版本控制系統也會有同樣的問題,只要使用者將整個專案的開發歷史都放在同一個地方,就有遺失所有資料的風險。
32
+
33
+ ### 分散式版本控制系統 ###
34
+
35
+ 這就是分散式版本控制系統(Distributed Version Control Systems, 簡稱DVCSs)被引入的原因。 在分散式版本控制系統,諸如:Git、Mercurial、Bazaar、Darcs。 客戶端不只是取出最後一版的檔案,而是完整複製整個儲存庫。 即使是整個系統賴以運作的電腦損毀,皆可將任何一個客戶端先前複製的資料還原到伺服器。 每一次的取出動作實際上就是完整備份整個儲存庫。(參考圖1-3)
36
+
37
+ Insert 18333fig0103.png
38
+ 圖1-3. 分散式版本控制系統
39
+
40
+ 更進一步來說,許多這類型的系統皆能同時與數個遠端的機器同時運作。 因此讀者能同時與許多不同群組的人們協同開發同一個專案。 這允許讀者設定多種集中式系統做不到的工作流程,如:階層式模式。
41
+
42
+ ## Git 的簡史 ##
43
+
44
+ 如同許多生命中美好的事物一樣,Git從有一點創造性的破壞及激烈的討論中誕生。 Linux kernel 是開放原始碼中相當大的專案。 在 Linux kernel 大部份的維護時間內(1991~2002),修改該軟體的方式通常以多個修補檔及壓縮檔流通。 在2002年,Linux kernel 開始採用名為 BitKeeper 的商業分散式版本控制系統。
45
+
46
+ 在 2005年,開發 Linux kernel 的社群與開發 BitKeeper 的商業公司的關係走向決裂,也無法再免費使用該工具。 這告訴了 Linux 社群及 Linux 之父 Linus Torvalds,該是基於使用 BitKeeper 得到的經驗,開發自有的工具的時候。 這個系統必須達成下列目標:
47
+
48
+ * 快速
49
+ * 簡潔的設計
50
+ * 完整支援非線性的開發(上千個同時進行的分支)
51
+ * 完全的分散式系統
52
+ * 能夠有效地處理像 Linux kernel 規模的專案(速度及資料大小)
53
+
54
+ 自從 2005 年誕生後,Git已相當成熟,也能很容易上手,並保持著最一開始的要求的品質。 它不可思議的快速、處理大型專案非常有效率、也具備相當優秀足以應付非線性開發的分支系統。(參考第三章)
55
+
56
+ ## Git 基礎要點 ##
57
+
58
+ 那麼,簡單地說,Git是一個什麼樣的系統? 這一章節是非常重要的。 若讀者瞭解Git的本質以及運作的基礎,那麼使用起來就會很輕鬆且有效率。 在學習之前,試著忘記以前所知道的其它版本控制系統,如:Subversion 及 Perforce。 這將會幫助讀者使用此工具時發生不必要的誤會。 Git儲存資料及運作它們的方式遠異於其它系統,即使它們的使用者介面是很相似的。 瞭解這些差異會幫助讀者更準確的使用此工具。
59
+
60
+ ### 記錄檔案快照,而不是差異的部份 ###
61
+
62
+ Git與其它版本控制系統(包含Subversion以及與它相關的)的差別是如何處理資料的方式。 一般來說,大部份其它系統記錄資訊是一連串檔案更動的內容。 如圖1-4所示。 這些系統(CVS、Subversion、Perforce、Bazaar等等)儲存一組基本的檔案以及對應這些檔案隨時間遞增的更動資料。
63
+
64
+ Insert 18333fig0104.png
65
+ 圖1-4. 其它系統傾向儲存每個檔案更動的資料。
66
+
67
+ Git並不以此種方式儲存資料。 而是將其視為小型檔案系統的一組快照(Snapshot)。 每一次讀者提交更新時、或者儲存目前專案的狀態到Git時。 基本上它為當時的資料做一組快照並記錄參考到該快照的參考點。 為了講求效率,只要檔案沒有變更,Git不會再度儲存該檔案,而是記錄到前一次的相同檔案的連結。 Git的工作方式如圖1-5所示。
68
+
69
+ Insert 18333fig0105.png
70
+ 圖1-5. Git儲存每次專案更新時的快照。
71
+
72
+ 這是Git與所有其它版本控制系統最重要的區別。 它完全顛覆傳統版本控制的作法。 這使用Git更像一個上層具備更強大工具的小型檔案系統,而不只是版本控制系統。 我們將會在第三章介紹分支時,提到採用此種作法的優點。
73
+
74
+ ### 大部份的操作皆可在本地端完成 ###
75
+
76
+ 大部份Git的操作皆只需要本地端的檔案及資源即可完成。 一般來說並需要到網路上其它電腦提取的資訊。 若讀者使用集中式版本控制系統,大部份的動作皆包含網路延遲的成本。 這項特點讓你覺得Git處理資料的速度飛快。 因為整個專案的歷史皆存在你的硬碟中,大部份的運作看起來幾乎都是馬上完成。
77
+
78
+ 例如:想要瀏覽專案的歷史時,Git不需要到伺服器下載歷史,而是從本地端的資料庫讀取並顯示即可。 這意謂著讀者幾乎馬上就可以看到專案的歷史。 若讀者想瞭解某個檔案一個月前的版本及現在版本的差別,Git可在本地端找出一個月前的檔案並在比對兩者的差異,而不是要求遠端的伺服器執行這項工作,或者從伺服器取回舊版本的檔案並在本地端比對。
79
+
80
+ 這意謂著即使讀者已離線,或者切斷VPN連線後,也很少有讀者無法執行的動作。 若讀者在飛機或火車上,並想要做一些工作,讀者在取得可上傳的網路前仍可很快樂地提交更新。 若讀者回到家且無法讓VPN連線程式正常運作,讀者仍然可繼續工作。 在許多其它系統幾乎是無法做這些事或者必須付出很大代價。 以Perforce為例,在無法連到伺服器時讀者做不了多少事。以Subversion及CVS為例,雖然讀者能編輯檔案,但因為資料庫此時是離線的,讀者無法提交更新到資料庫。 這看起來可能還不是什麼大問題,但讀者可能驚訝Git有這麼大的不同。
81
+
82
+ ### Git能檢查完整性 ###
83
+
84
+ 在Git中所有的物件在儲存前都會被計算查核碼(`checksum`)並以查核碼檢索物件。 這意謂著Git不可能不清楚任何檔案或目錄的內容已被更動。 此功能內建在Git底層並整合到它的設計哲學。 Git能夠馬上察覺傳輸時的遺失或是檔案的毀損。
85
+
86
+ Git用來計算查核碼的機制稱為SHA-1雜湊法。 它由40個十六進制的字母(0–9 and a–f)組成的字串組成,基於Git的檔案內容或者目錄結構計算。 查核碼看起來如下所示:
87
+
88
+ 24b9da6552252987aa493b52f8696cd6d3b00373
89
+
90
+ 讀者會Git中到處都看到雜湊值,因為它到處被使用。 事實上Git以檔案內容的雜湊值定址出檔案在資料庫的位址,而不是以檔案的名稱定址。
91
+
92
+ ### Git 通常只增加資料 ###
93
+
94
+ 當讀者使用Git,幾乎所有的動作只是增加資料到Git的資料庫。 很難藉此讓做出讓系統無法復原或者清除資料的動作。 在任何版本控制系統,讀者有可能會遺失或者搞混尚未提交的更新。 但是在提交快照到Git後,很少會有遺失的情況,特別是讀者定期將資料庫更新到其它儲存庫。
95
+
96
+ 這讓使用Git可輕鬆地像在玩一樣,因為我們知道我們可以進行任何實驗而不會破壞任何東西。 在第九章的“底層細節”中,我們會進一步討論Git如何儲存資料,以及讀者如何復原看似遺失的資料。
97
+
98
+ ### 三種狀態 ###
99
+
100
+ 現在,注意。 若讀者希望接下來的學習過程順利些,這是關於Git的重要且需記住的事項。 Git有三種表達檔案的狀態:已提交(committed)、已修改(modified)及已暫存(staged)。 已提交意謂著資料己安全地存在讀者的本地端資料庫。 己修改代表著讀者已修改檔案但尚未提交到資料庫。 已暫存意謂著讀者標記已修改檔案目前的版本到下一次提供的快照。
101
+
102
+ 這帶領我們到Git專案的三個主要區域:Git目錄、工作目錄(working directory)以及暫存區域(staging area)。
103
+
104
+ Insert 18333fig0106.png
105
+ 圖1-6. 工作目錄、暫存區域及git目錄。
106
+
107
+ Git目錄是Git用來儲存讀者的專案的元數據及物件資料庫。 這是Git最重要的部份,而且它是當讀者從其它電腦複製儲存庫時會複製過來的。
108
+
109
+ 工作目錄是專案被取出的某一個版本。 這些檔案從Git目錄內被壓縮過的資料庫中拉出來並放在磁碟機供讀者使用或修改。
110
+
111
+ 暫存區域是一個單純的檔案,一般來說放在Git目錄,儲存關於下一個提交的資訊。 有時稱為索引,但現在將它稱為暫存區域已開始成為標準。
112
+
113
+ 基本Git工作流程大致如下:
114
+
115
+ 1. 讀者修改工作目錄內的檔案。
116
+ 2. 暫存檔案,將檔案的快照新增到暫存區域。
117
+ 3. 做提交的動作,這會讓存在暫存區域的檔案快照永久地儲存在Git目錄。
118
+
119
+ 在Git目錄內特定版本的檔案被認定為已提交。 若檔案被修改且被增加到暫存區域,稱為被暫存。 若檔案被取出後有被修改,但未被暫存,稱為被修改。 在第二章讀者會學到更多關於這些狀態以及如何利用它們的優點或者整個略過暫存步驟。
120
+
121
+ ## 安裝Git ##
122
+
123
+ 讓我們開始使用Git。 首先讀者要做的事是安裝Git。 讀者有很多取得它們的方法。 主要的兩種分別是從原始碼安裝或者從讀者使用平台現存的套件安裝。
124
+
125
+ ### 從原始碼安裝 ###
126
+
127
+ 若讀者有能力的話,從原始碼安裝是非常有用的。 因為讀者能取得最新版本。 每一版Git通常都會包含有用的UI改善。 因此取得最新版本通常是最好的,只要讀者覺得編譯軟體的原始碼是很容易的。 許多Linux發行套件通常都是附上非常舊的套件。 除非讀者使用的發行套件非常新或者使用向後相容的移植版本。 從原始碼安裝通常是最好的選擇。
128
+
129
+ 要安裝Git,讀者需要先安裝它需要的程式庫:curl、zlib、openssl、expat及libiconv。 例如:若讀者的系統有yum(如:Fedpra)或apt-get(如:以Debian為基礎的系統),讀者可使用下列任一命令安裝所有需要的程式庫:
130
+
131
+ $ yum install curl-devel expat-devel gettext-devel \
132
+ openssl-devel zlib-devel
133
+
134
+ $ apt-get install libcurl4-gnutls-dev libexpat1-dev gettext \
135
+ libz-dev libssl-dev
136
+
137
+ 當讀者安裝所有必要的程式庫,讀者可到Git的網站取得最新版本:
138
+
139
+ http://git-scm.com/download
140
+
141
+ 接著,編譯及安裝:
142
+
143
+ $ tar -zxf git-1.7.2.2.tar.gz
144
+ $ cd git-1.7.2.2
145
+ $ make prefix=/usr/local all
146
+ $ sudo make prefix=/usr/local install
147
+
148
+ 在這些工作完成後,讀者也可以使用Git取得Git的更新版:
149
+
150
+ $ git clone git://git.kernel.org/pub/scm/git/git.git
151
+
152
+ ### 在Linux系統安裝 ###
153
+
154
+ 若讀者想使用二進位安裝程式安裝Git到Linux,一般來說讀者可經由發行套件提供的套件管理工具完成此工作。 若讀者使用Fedora,可使用`yum`:
155
+
156
+ $ yum install git-core
157
+
158
+ 若讀者在以Debian為基礎的發行套件,如:Ubuntu。 試試`apt-get`:
159
+
160
+ $ apt-get install git
161
+
162
+ ### 在Mac系統安裝 ###
163
+
164
+ 有兩種很容易將Git安裝到Mac的方法。 最簡單的是使用圖形化界面的Git安裝程式,可從SourceForge下載)圖1-7):
165
+
166
+ http://sourceforge.net/projects/git-osx-installer/
167
+
168
+ Insert 18333fig0107.png
169
+ 圖1-7. Git OS X 安裝程式。
170
+
171
+ 藉由MacPorts安裝Git是另一種主要的方法。 若讀者已安裝MacPorts,使用下列命令安裝Git
172
+
173
+ $ sudo port install git-core +svn +doc +bash_completion +gitweb
174
+
175
+ 讀者完全不需要安裝所有的額外套件,但讀者可能會想要加上`+svn`參數,以利於使用Git讀寫Subversion儲存庫(參考第8章)。
176
+
177
+ ### 在Windows系統安裝 ###
178
+
179
+ 在Windows系統安裝Git相當地容易。 msysGit專案已提供相當容易安裝的程序。 只要從GitHub網頁下載安裝程式並執行即可:
180
+
181
+ http://msysgit.github.com/
182
+
183
+ 在安裝完畢後,讀者同時會有命令列版本(包含SSH客戶端程式)及標準的圖形界面版本。
184
+
185
+ Note on Windows usage: you should use Git with the provided msysGit shell (Unix style), it allows to use the complex lines of command given in this book. If you need, for some reason, to use the native Windows shell / command line console, you have to use double quotes instead of simple quotes (for parameters with spaces in them) and you must quote the parameters ending with the circumflex accent (^) if they are last on the line, as it is a continuation symbol in Windows.
186
+
187
+ ## 初次設定Git ##
188
+
189
+ 現在讀者的系統已安裝了Git,讀者可能想要做一些客製化的動作。 讀者應只需要做這些工作一次。 這些設定在更新版本時會被保留下來。 讀者可藉由再度執行命令的方式再度修改這些設定。
190
+
191
+ Git附帶名為`git config`的工具,允許讀者取得及設定組態參數,可用來決定Git外觀及運作。 這些參數可存放在以下三個地方:
192
+
193
+ * 檔案 `/etc/gitconfig`: 包含給該系統所有使用者的儲存庫使用的數值。 只要讀者傳遞 --system 參數給 git config,它就會讀取或者寫入參數到這個檔案
194
+ * 檔案 `~/.gitconfig`: 給讀者自己的帳號使用。 傳遞 --global 參數給 git config,它就會讀取或者寫入參數到這個檔案。
195
+ * 儲存庫內的設定檔,也就是 `.git/config`: 僅給所在的儲存庫使用。 每個階級的設定會覆寫上一層的。 因此,`git/config`內的設定值的優先權高過`/etc/config`。
196
+
197
+ 在Windows系統,Git在`$HOME`目錄(對大部份使用者來說是`C:\Documents and Settings\$USER`)內尋找`.gitconfig`。 它也會尋找`/etc/gitconfig`,只不過它是相對於Msys根目錄,取決於讀者當初在Windows系統執行Git的安裝程式時安裝的目的地。
198
+
199
+ ### 設定識別資料 ###
200
+
201
+ 讀者安裝Git後首先應該做的事是指定使用者名稱及電子郵件帳號。 這一點非常重要,因為每次Git提交會使用這些資訊,而且提交後不能再被修改:
202
+
203
+ $ git config --global user.name "John Doe"
204
+ $ git config --global user.email johndoe@example.com
205
+
206
+ 再說一次,若讀者有指定 `--global` 參數,只需要做這工作一次。 因為在此系統,不論Git做任何事都會採用此資訊。 若讀者想指定不同的名字或電子郵件給特定的專案, 只需要在該專案目錄內執行此命令,並確定未加上 `--global` 參數。
207
+
208
+ ### 指定編輯器 ###
209
+
210
+ 現在讀者的識別資料已設定完畢,讀者可設定預設的文書編輯器,當Git需要讀者輸入訊息時會叫用它。 預設情況下,Git會使用系統預設的編輯器,一般來說是Vi或Vim。 若讀者想指定不同的編輯器,例如:Emacs。可執行下列指令:
211
+
212
+ $ git config --global core.editor emacs
213
+
214
+ ### 指定合併工具 ###
215
+
216
+ 另外一個對讀者來說有用的選項是設定解決合併失敗時,讀者慣用的合併工具。 假設讀者想使用vimdiff:
217
+
218
+ $ git config --global merge.tool vimdiff
219
+
220
+ Git能接受kdiff3、tkdiff、meld、xxdiff、emerge、vimdiff、gvimdiff、ecmerge及opendiff做為合併工具。 讀者可設定自訂的工具。 詳情參考第七章。
221
+
222
+ ### 檢查讀者的設定 ###
223
+
224
+ 若讀者想確認設定值,可使用 `git config --list` 命令列出所有Git能找到的設定值:
225
+
226
+ $ git config --list
227
+ user.name=Scott Chacon
228
+ user.email=schacon@gmail.com
229
+ color.status=auto
230
+ color.branch=auto
231
+ color.interactive=auto
232
+ color.diff=auto
233
+ ...
234
+
235
+ 讀者可能會看到同一個設定名稱出現多次,因為Git從不同的檔案讀到同一個設定名稱(例如:`/etc/gitconfig`及`~/.gitconfig`)。 在這情況下,Git會使用最後一個設定名稱的設定值。
236
+
237
+ 使用者也可以下列命令 `git config` 設定名稱,檢視Git認為該設定名稱的設定值:
238
+
239
+ $ git config user.name
240
+ Scott Chacon
241
+
242
+ ## 取得說明文件 ##
243
+
244
+ 若讀者在使用Git時需要幫助,有三種方法取得任何Git命令的手冊:
245
+
246
+ $ git help <verb>
247
+ $ git <verb> --help
248
+ $ man git-<verb>
249
+
250
+ 例如:讀者可以下列命令取得config命令的手冊
251
+
252
+ $ git help config
253
+
254
+ 這些命令對讀者是很有幫助的,因為讀者可在任意地方取得它們,即使已離線。
255
+ 若手冊及這本書不足以幫助讀者,且讀者需要更進一步的協助。 讀者可試著進入Freenode IRC伺服器(irc.freenode.net)的`#git`或`#github`頻道。 這些頻道平時都有上百位對Git非常瞭解的高手而且通常樂意協助。
256
+
257
+ ## 總結 ##
258
+
259
+ 目前讀者應該對於Git有一些基本的瞭解,而且知道它與其它集中式版本控制系統的不同,其中有些可能是讀者正在使用的。 讀者的系統現在也應該有一套可動作的Git且已設定好讀者個人的識別資料。 現在正是學習一些Git基本操作的好時機。
@@ -0,0 +1,1183 @@
1
+ # Git 基礎 #
2
+
3
+ 讀完這一章,你就可以開始使用Git了。本章節涵蓋大部份最常被使用的Git基本指令。 在讀完本章節後,讀者應該有能力組態及初始化一個儲存庫(repository)、開始及停止追蹤檔案(track)、暫存(stage)及提交(commit)更新。 本章還會提到如何讓Git忽略某些檔案、如何輕鬆且很快地救回失誤、如何瀏覽讀者的專案歷史及觀看各個已提交的更新之間的變更、以及如何從遠端儲存庫`拉`(pull)更新下來或將更新`推`(push)上去。
4
+
5
+ ## 取得Git儲存庫 ##
6
+
7
+ 讀者可使用兩種主要的方法取得一個Git儲存庫。 第一種是將現有的專案或者目錄匯入Git。 第二種從其它伺服器複製一份已存在的Git儲存庫。
8
+
9
+ ### 在現有目錄初始化儲存庫 ###
10
+
11
+ 若讀者要開始使用 Git 追蹤現有的專案,只需要進入該專案的目錄並執行:
12
+
13
+ $ git init
14
+
15
+ 這個命令會建立名為 `.git` 的子目錄,該目錄包含一個Git儲存庫架構必要的所有檔案。 目前來說,專案內任何檔案都還沒有被追蹤。(關於.git目錄內有些什麼檔案,可參考第九章)
16
+
17
+ 若讀者想要開始對現有的檔案開始做版本控制(除了空的目錄以外),讀者也許應該開始追蹤這些檔案並做第一次的提交。 讀者能以少數的git add命令指定要追蹤的檔案,並將它們提交:
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取得的是大部份伺服器端所有的資料複本。 該專案歷史中所有檔案的所有版本都在讀者執行過 `git clone` 後拉回來。 事實上,若伺服器的磁碟機損毀,讀者可使用任何一個客戶端的複本還原伺服器為當初取得該複本的狀態(讀者可能會遺失一些僅存於伺服器的攔截程式,不過所有版本的資料都健在),參考第四章取得更多資訊。
28
+
29
+ 讀者可以 `git clone [url]`,複製一個儲存庫。 例如:若讀者想複製名為Grit的Ruby Git程式庫,可以執行下列命令:
30
+
31
+ $ git clone git://github.com/schacon/grit.git
32
+
33
+ 接下來會有個名為`grit`的目錄被建立,並在其下初始化名為`.git`的目錄。 拉下所有存在該儲存庫的所有資料,並取出最新版本為工作複本。 若讀者進入新建立的 `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 傳輸的協定。 在第四章會介紹設定存取伺服器上的 Git 儲存庫的所有可用的選項,以及它們的優點及缺點。
40
+
41
+ ## 提交更新到儲存庫 ##
42
+
43
+ 讀者現在有一個貨真價實的Git儲存庫,而且有一份已放到工作複本的該專案的檔案。 讀者需要做一些修改並提交這些更動的快照到儲存庫,當這些修改到達讀者想要記錄狀態的情況。
44
+
45
+ 記住工作目錄內的每個檔案可能為兩種狀態的任一種:追蹤或者尚未被追蹤。 被追蹤的檔案是最近的快照;它們可被復原、修改,或者暫存。 未被追蹤的檔案則是其它未在最近快照也未被暫存的任何檔案。 當讀者第一次複製儲存器時,讀者所有檔案都是被追蹤且未被修改的。 因為讀者剛取出它們而且尚未更改做任何修改。
46
+
47
+ 只要讀者編輯任何已被追蹤的檔案。 Git將它們視為被更動的,因為讀者將它們改成與最後一次提交不同。 讀者暫存這些已更動檔案並提供所有被暫存的更新, 並重複此週期。 此生命週期如圖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
+ Wokring directory clean意謂著目前的工作目錄沒有未被追蹤或已被修改的檔案。Git未看到任何未被追蹤的檔案,否則會將它們列出。 最後,這個命令告訴讀者目前在哪一個分支(branch)。到目前為止,一直都是master,這是預設的。下一個章節會詳細介紹分支(branch),目前我們先不考慮它。
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
+
72
+ nothing added to commit but untracked files present (use "git add" to track)
73
+
74
+ 我們可以看到新增的`README`尚未被追蹤,因為它被列在輸出訊息的 Untracked files 下方。 除非我們明確指定要將該檔案加入提交的快照,Git不會主動將它加入。這樣可以避免加入一些二進位格式的檔案或其它使用者不想列入追蹤的檔案。 不過在這個例子中,我們的確是要將 `README` 檔案加入追蹤:
75
+
76
+ ### 追蹤新檔案 ###
77
+
78
+ 要追蹤新增的檔案,我們可以使用`git add`命令。例如:要追蹤`README`檔案,可執行:
79
+
80
+ $ git add README
81
+
82
+ 如此一來,我們重新檢查狀態(status)時,可看到`README`檔案已被列入追蹤並且已被暫存:
83
+
84
+ $ git status
85
+ On branch master
86
+ Changes to be committed:
87
+ (use "git reset HEAD <file>..." to unstage)
88
+
89
+ new file: README
90
+
91
+
92
+ 因為它被放在Changes to be commited文字下方,讀者可得知它已被暫存起來。 若讀者此時提交更新,剛才執行`git add`加進來的檔案就會被記錄在歷史的快照。 讀者可能可回想一下先前執行`git init`後也有執行過`git add`,開始追蹤目錄內的檔案。`git add`命令可接受檔名或者目錄名。 若是目錄名,Git會以遞迴(recursive)的方式會將整個目錄下所有檔案及子目錄都加進來。
93
+
94
+ ### 暫存已修改檔案 ###
95
+
96
+ 讓我們修改已被追蹤的檔案。 若讀者修改先前已被追蹤的檔案,名為`benchmarks.rb`,並檢查目前儲存庫的狀態。我們會看到類似以下文字:
97
+
98
+ $ git status
99
+ On branch master
100
+ Changes to be committed:
101
+ (use "git reset HEAD <file>..." to unstage)
102
+
103
+ new file: README
104
+
105
+ Changes not staged for commit:
106
+ (use "git add <file>..." to update what will be committed)
107
+ (use "git checkout -- <file>..." to discard changes in working directory)
108
+
109
+ modified: benchmarks.rb
110
+
111
+
112
+ `benchmarks.rb`檔案出現在 “Changes not staged for commit” 下方,代表著這個檔案已被追蹤,而且位於工作目錄的該檔案已被修改,但尚未暫存。 要暫存該檔案,可執行`git add`命令(這是一個多重用途的指令)。現在,讀者使用 `git add` 將`benchmarks.rb`檔案暫存起來,並再度執行`git status`:
113
+
114
+ $ git add benchmarks.rb
115
+ $ git status
116
+ On branch master
117
+ Changes to be committed:
118
+ (use "git reset HEAD <file>..." to unstage)
119
+
120
+ new file: README
121
+ modified: benchmarks.rb
122
+
123
+
124
+ 這兩個檔案目前都被暫存起來,而且會進入下一次的提交。 假設讀者記得仍需要對`benchmarks.rb`做一點修改後才要提交,可再度開啟並編輯該檔案。 然而,當我們再度執行`git status`:
125
+
126
+ $ vim benchmarks.rb
127
+ $ git status
128
+ On branch master
129
+ Changes to be committed:
130
+ (use "git reset HEAD <file>..." to unstage)
131
+
132
+ new file: README
133
+ modified: benchmarks.rb
134
+
135
+ Changes not staged for commit:
136
+ (use "git add <file>..." to update what will be committed)
137
+ (use "git checkout -- <file>..." to discard changes in working directory)
138
+
139
+ modified: benchmarks.rb
140
+
141
+
142
+ 到底發生了什麼事? 現在`benchmarks.rb`同時被列在已被暫存及未被暫存。 這怎麼可能? 這表示Git的確在讀者執行`git add`命令後,將檔案暫存起來。 若讀者現在提交更新,最近一次執行`git add`命令時暫存的`benchmarks.rb`會被提交。 若讀者在`git add`後修改檔案,需要再度執行`git add`將最新版的檔案暫存起來:
143
+
144
+ $ git add benchmarks.rb
145
+ $ git status
146
+ On branch master
147
+ Changes to be committed:
148
+ (use "git reset HEAD <file>..." to unstage)
149
+
150
+ new file: README
151
+ modified: benchmarks.rb
152
+
153
+
154
+ ### 忽略某些檔案 ###
155
+
156
+ 通常讀者會有一類不想讓Git自動新增,也不希望它們被列入未被追蹤的檔案。 這些通常是自動產生的檔案,例如:記錄檔或者編譯系統產生的檔案。 在這情況下,讀者可建立一個名為`.gitignore`檔案,列出符合這些檔案檔名的特徵。 以下是一個範例:
157
+
158
+ $ cat .gitignore
159
+ *.[oa]
160
+ *~
161
+
162
+ 第一列告訴Git忽略任何檔名為`.o`或`.a`結尾的檔案,它們是可能是編譯系統建置讀者的程式碼時產生的目的檔及程式庫。 第二列告訴Git忽略所有檔名為~結尾的檔案,通常被很多文書編輯器,如:Emacs,使用的暫存檔案。 讀者可能會想一併將log、tmp、pid目錄及自動產生的文件等也一併加進來。 依據類推。在讀者要開始開發之前將`.gitignore`設定好,通常是一個不錯的點子。這樣子讀者不會意外地將真的不想追蹤的檔案提交到Git儲存庫。
163
+
164
+ 編寫`.gitignore`檔案的規則如下:
165
+
166
+ * 空白列或者以#開頭的列會被忽略。
167
+ * 可使用標準的Glob pattern。
168
+ * 可以/結尾,代表是目錄。
169
+ * 可使用!符號將特徵反過來使用。
170
+
171
+ Glob pattern就像是shell使用的簡化版正規運算式。 星號(`*`)匹配零個或多個字元;`[abc]`匹配中括弧內的任一字元(此例為`a`、`b`、`c`);問號(`?`)匹配單一個字元;中括孤內的字以連字符連接(如:`[0-9]`),用來匹配任何符合該範圍的字(此例為0到9)。
172
+
173
+ 以下是另一個`.gitignore`的範例檔案:
174
+
175
+ # 註解,會被忽略。
176
+ # 不要追蹤檔名為 .a 結尾的檔案
177
+ *.a
178
+ # 但是要追蹤 lib.a,即使上方已指定忽略所有的 .a 檔案
179
+ !lib.a
180
+ # 只忽略根目錄下的 TODO 檔案。 不包含子目錄下的 TODO
181
+ /TODO
182
+ # 忽略build/目錄下所有檔案
183
+ build/
184
+ # 忽略doc/notes.txt但不包含doc/server/arch.txt
185
+ doc/*.txt
186
+ # ignore all .txt files in the doc/ directory
187
+ doc/**/*.txt
188
+
189
+ A `**/` pattern is available in Git since version 1.8.2.
190
+
191
+ ### 檢視已暫存及尚未暫存的更動 ###
192
+
193
+ 在某些情況下,`git status`指令提供的資訊就太過簡要。
194
+ 有的時候我們不只想知道那些檔案被更動,而是想更進一步知道被檔案的內容被做了那些修改,這時我們可以使用`git diff`命令。稍後我們會有更詳盡講解該命令。讀者使用它時通常會是為了瞭解兩個問題:目前已做的修改但尚未暫存的內容是哪些?以及將被提交的暫存資料有哪些?儘管`git status`指令可以大略回答這些問題,但`git diff`可顯示檔案裡的哪些列被加入或刪除,以修補檔(patch)方式表達。
195
+
196
+ 假設讀者編輯並暫存(stage)`README`,接著修改`benchmarks.rb`檔案,卻未暫存。若讀者檢視目前的狀況,會看到類似下方文字:
197
+
198
+ $ git status
199
+ On branch master
200
+ Changes to be committed:
201
+ (use "git reset HEAD <file>..." to unstage)
202
+
203
+ new file: README
204
+
205
+ Changes not staged for commit:
206
+ (use "git add <file>..." to update what will be committed)
207
+ (use "git checkout -- <file>..." to discard changes in working directory)
208
+
209
+ modified: benchmarks.rb
210
+
211
+
212
+ 想瞭解尚未暫存的修改,執行`git diff`,不用帶任何參數:
213
+
214
+ $ git diff
215
+ diff --git a/benchmarks.rb b/benchmarks.rb
216
+ index 3cb747f..da65585 100644
217
+ --- a/benchmarks.rb
218
+ +++ b/benchmarks.rb
219
+ @@ -36,6 +36,10 @@ def main
220
+ @commit.parents[0].parents[0].parents[0]
221
+ end
222
+
223
+ + run_code(x, 'commits 1') do
224
+ + git.commits.size
225
+ + end
226
+ +
227
+ run_code(x, 'commits 2') do
228
+ log = git.commits('master', 15)
229
+ log.size
230
+
231
+ 這命令會比對目前工作目錄(working directory)及暫存區域(stage area)的版本,然後顯示尚未被存入暫存區(stage area)的變更。
232
+
233
+ 若讀者想比對暫存區域(stage)及最後一次提交(commit)的差異,可用`git diff --cached`指令(Git 1.6.1之後的版本,可用較易記的`git diff --staged` 指令):
234
+
235
+ $ git diff --cached
236
+ diff --git a/README b/README
237
+ new file mode 100644
238
+ index 0000000..03902a1
239
+ --- /dev/null
240
+ +++ b/README2
241
+ @@ -0,0 +1,5 @@
242
+ +grit
243
+ + by Tom Preston-Werner, Chris Wanstrath
244
+ + http://github.com/mojombo/grit
245
+ +
246
+ +Grit is a Ruby library for extracting information from a Git repository
247
+
248
+ 很重要的一點是`git diff`不會顯示最後一次commit後的所有變更;只會顯示尚未存入暫存區(即unstaged)的變更。這麼說可能會混淆,舉個例子來說,若讀者已暫存(stage)所有的變更,輸入`git diff`不會顯示任何資訊。
249
+
250
+ 舉其它例子,若讀者暫存`benchmarks.rb`檔案後又編輯,可使用`git diff`看已暫存的版本與工作目錄內版本尚未暫存的變更:
251
+
252
+ $ git add benchmarks.rb
253
+ $ echo '# test line' >> benchmarks.rb
254
+ $ git status
255
+ On branch master
256
+ Changes to be committed:
257
+ (use "git reset HEAD <file>..." to unstage)
258
+
259
+ modified: benchmarks.rb
260
+
261
+ Changes not staged for commit:
262
+ (use "git add <file>..." to update what will be committed)
263
+ (use "git checkout -- <file>..." to discard changes in working directory)
264
+
265
+ modified: benchmarks.rb
266
+
267
+
268
+ 現在讀者可使用`git diff`檢視哪些部份尚未被暫存:
269
+
270
+ $ git diff
271
+ diff --git a/benchmarks.rb b/benchmarks.rb
272
+ index e445e28..86b2f7c 100644
273
+ --- a/benchmarks.rb
274
+ +++ b/benchmarks.rb
275
+ @@ -127,3 +127,4 @@ end
276
+ main()
277
+
278
+ ##pp Grit::GitRuby.cache_client.stats
279
+ +# test line
280
+
281
+ 以及使用`git diff --cached`檢視目前已暫存的變更:
282
+
283
+ $ git diff --cached
284
+ diff --git a/benchmarks.rb b/benchmarks.rb
285
+ index 3cb747f..e445e28 100644
286
+ --- a/benchmarks.rb
287
+ +++ b/benchmarks.rb
288
+ @@ -36,6 +36,10 @@ def main
289
+ @commit.parents[0].parents[0].parents[0]
290
+ end
291
+
292
+ + run_code(x, 'commits 1') do
293
+ + git.commits.size
294
+ + end
295
+ +
296
+ run_code(x, 'commits 2') do
297
+ log = git.commits('master', 15)
298
+ log.size
299
+
300
+ ### 提交修改 ###
301
+
302
+ 現在讀者的暫存區域已被更新為讀者想要的,可開始提交變更的部份。 要記得任何尚未被暫存的新建檔案或已被修改但尚未使用git add暫存的檔案將不會被記錄在本次的提交中。 它們仍會以被修改的檔案的身份存在磁碟中。
303
+ 在這情況下,最後一次執行`git status`,讀者會看到所有已被暫存的檔案,讀者也準備好要提交修改。 最簡單的提交是執行`git commit`:
304
+
305
+ $ git commit
306
+
307
+ 執行此命令會叫出讀者指定的編輯器。(由讀者shell的$EDITOR環境變數指定,通常是vim或emacs。讀者也可以如同第1章介紹的,使用`git config --global core.editor` 命令指定)
308
+
309
+ 編輯器會顯示如下文字(此範例為Vim的畫面):
310
+
311
+ # Please enter the commit message for your changes. Lines starting
312
+ # with '#' will be ignored, and an empty message aborts the commit.
313
+ # On branch master
314
+ # Changes to be committed:
315
+ # new file: README
316
+ # modified: benchmarks.rb
317
+ #
318
+ ~
319
+ ~
320
+ ~
321
+ ".git/COMMIT_EDITMSG" 10L, 283C
322
+
323
+ 讀者可看到預設的提交訊息包含最近一次`git status`的輸出以註解方式呈現,以及螢幕最上方有一列空白列。 讀者可移除這些註解後再輸入提交的訊息,或者保留它們,提醒你現在正在進行提交。(若想知道更動的內容,可傳遞-v參數給`git commit`。如此一來連比對的結果也會一併顯示在編輯器內,方便讀者明確看到有什麼變更。) 當讀者離開編輯器,Git會利用這些提交訊息產生新的提交(註解及比對的結果會先被濾除)。
324
+
325
+ 另一種方式則是在commit命令後方以`-m`參數指定提交訊息,如下:
326
+
327
+ $ git commit -m "Story 182: Fix benchmarks for speed"
328
+ [master 463dc4f] Story 182: Fix benchmarks for speed
329
+ 2 files changed, 3 insertions(+)
330
+ create mode 100644 README
331
+
332
+ 現在讀者已建立第一個提交! 讀者可從輸出的訊息看到此提交、放到哪個分支(`master`)、SHA-1查核碼(`463dc4f`)、有多少檔案被更動,以及統計此提交有多少列被新增及移除。
333
+
334
+ 記得提交記錄讀者放在暫存區的快照。 任何讀者未暫存的仍然保持在已被修改狀態;讀者可進行其它的提交,將它增加到歷史。 每一次讀者執行提交,都是記錄專案的快照,而且以後可用來比對或者復原。
335
+
336
+ ### 跳過暫存區域 ###
337
+
338
+ 雖然優秀好用的暫存區域能很有技巧且精確的提交讀者想記錄的資訊,有時候暫存區域也比讀者實際需要的工作流程繁瑣。 若讀者想跳過暫存區域,Git提供了簡易的使用方式。 在`git commit`命令後方加上`-a`參數,Git自動將所有已被追蹤且被修改的檔案送到暫存區域並開始提交程序,讓讀者略過`git add`的步驟:
339
+
340
+ $ git status
341
+ On branch master
342
+ Changes not staged for commit:
343
+ (use "git add <file>..." to update what will be committed)
344
+ (use "git checkout -- <file>..." to discard changes in working directory)
345
+
346
+ modified: benchmarks.rb
347
+
348
+ no changes added to commit (use "git add" and/or "git commit -a")
349
+ $ git commit -a -m 'added new benchmarks'
350
+ [master 83e38c7] added new benchmarks
351
+ 1 files changed, 5 insertions(+)
352
+
353
+ 留意本次的提交之前,讀者並不需要執行`git add`將`benchmarks.rb`檔案加入。
354
+
355
+ ### 刪除檔案 ###
356
+
357
+ 要從Git刪除檔案,讀者需要將它從已被追蹤檔案中移除(更精確的來說,是從暫存區域移除),並且提交。 `git rm`命令除了完成此工作外,也會將該檔案從工作目錄移除。 因此讀者以後不會在未被追蹤檔案列表看到它。
358
+
359
+ 若讀者僅僅是將檔案從工作目錄移除,那麼在`git status`的輸出,可看見該檔案將會被視為“已被變更且尚未被更新”(也就是尚未存到暫存區域):
360
+
361
+ $ rm grit.gemspec
362
+ $ git status
363
+ On branch master
364
+ Changes not staged for commit:
365
+ (use "git add/rm <file>..." to update what will be committed)
366
+ (use "git checkout -- <file>..." to discard changes in working directory)
367
+
368
+ deleted: grit.gemspec
369
+
370
+ no changes added to commit (use "git add" and/or "git commit -a")
371
+
372
+ 接著,若執行`git rm`,則會將暫存區域內的該檔案移除:
373
+
374
+ $ git rm grit.gemspec
375
+ rm 'grit.gemspec'
376
+ $ git status
377
+ On branch master
378
+ Changes to be committed:
379
+ (use "git reset HEAD <file>..." to unstage)
380
+
381
+ deleted: grit.gemspec
382
+
383
+
384
+ 下一次提交時,該檔案將會消失而且不再被追蹤。 若已更動過該檔案且將它記錄到暫存區域。 必須使用`-f`參數才能將它強制移除。 這是為了避免已被記錄的快照意外被移除且再也無法使用Git復原。
385
+
386
+ 其它有用的技巧是保留工作目錄內的檔案,但從暫存區域移除。 換句話說,或許讀者想在磁碟機上的檔案且不希望Git繼續追蹤它。 這在讀者忘記將某些檔案記錄到`.gitignore`且不小心將它增加到暫存區域時特別有用。 比如說:巨大的記錄檔、或大量在編譯時期產生的`.a`檔案。 欲使用此功能,加上`--cached`參數:
387
+
388
+ $ git rm --cached readme.txt
389
+
390
+ 除了檔名、目錄名以外,還可以指定簡化的正規運算式給`git rm`命令。 這意謂著可執行類似下列指令:
391
+
392
+ $ git rm log/\*.log
393
+
394
+ 注意星號(`*`)前方的倒斜線(`\`)。 這是必須的,因為Git會在shell以上執行檔案的擴展。 此命令移除log目錄下所有檔名以`.log`結尾的檔案。 讀者也可以執行類似下列命令:
395
+
396
+ $ git rm \*~
397
+
398
+ 此命令移除所有檔名以`~`結尾的檔案。
399
+
400
+ ### 搬動檔案 ###
401
+
402
+ Git並不像其它檔案控制系統一樣,明確地追蹤檔案的移動。 若將被Git追蹤的檔名更名,並沒有任何元數據儲存在Git中去標示此更名動作。 然而Git能很聰明地指出這一點。 稍後會介紹關於偵測檔案的搬動。
403
+
404
+ 因此Git存在`mv`這個指令會造成一點混淆。 若想要在Git中更名某個檔案,可執行以下命令:
405
+
406
+ $ git mv file_from file_to
407
+
408
+ 而且這命令可正常工作。 事實上,在執行完更名的動作後檢視一下狀態。 可看到Git認為該檔案被更名:
409
+
410
+ $ git mv README.txt README
411
+ $ git status
412
+ On branch master
413
+ Changes to be committed:
414
+ (use "git reset HEAD <file>..." to unstage)
415
+
416
+ renamed: README.txt -> README
417
+
418
+
419
+ 不過,這就相當於執行下列命令:
420
+
421
+ $ mv README.txt README
422
+ $ git rm README.txt
423
+ $ git add README
424
+
425
+ Git會在背後判斷檔案是否被更名,因此不管是用上述方法還是'mv'命令都沒有差別。 實際上唯一不同的是'mv'是一個命令,而不是三個。 使用上較方便。 更重要的是讀者可使用任何慣用的工具更名,再使用add/rm,接著才提交。
426
+
427
+ ## 檢視提交的歷史記錄 ##
428
+
429
+ 在提交數個更新,或者複製已有一些歷史記錄的儲存庫後。 或許會想希望檢視之前發生過什麼事。 最基本也最具威力的工具就是 `git log` 命令。
430
+
431
+ 以下採用非常簡單,名為 `simplegit` 的專案做展示。 欲取得此專案,執行以下命令:
432
+
433
+ git clone git://github.com/schacon/simplegit-progit.git
434
+
435
+ 在此專案目錄內執行 `git log`,應該會看到類似以下訊息:
436
+
437
+ $ git log
438
+ commit ca82a6dff817ec66f44342007202690a93763949
439
+ Author: Scott Chacon <schacon@gee-mail.com>
440
+ Date: Mon Mar 17 21:52:11 2008 -0700
441
+
442
+ changed the version number
443
+
444
+ commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
445
+ Author: Scott Chacon <schacon@gee-mail.com>
446
+ Date: Sat Mar 15 16:40:33 2008 -0700
447
+
448
+ removed unnecessary test code
449
+
450
+ commit a11bef06a3f659402fe7563abf99ad00de2209e6
451
+ Author: Scott Chacon <schacon@gee-mail.com>
452
+ Date: Sat Mar 15 10:31:28 2008 -0700
453
+
454
+ first commit
455
+
456
+ 在未加任何參數情況下,`git log`以新到舊的順序列出儲存庫的提交的歷史記錄。 也就是說最新的更新會先被列出來。 同時也會列出每個更新的 SHA-1 查核值、作者大名及電子郵件地址、及提交時輸入的訊息。
457
+
458
+ `git log`命令有很多樣化的選項,供讀者精確指出想搜尋的結果。 接下來會介紹一些常用的選項。
459
+
460
+ 最常用的選項之一為 `-p`,用來顯示每個更新之間差別的內容。 另外還可以加上 `-2` 參數,限制為只輸出最後兩個更新。
461
+
462
+ $ git log -p -2
463
+ commit ca82a6dff817ec66f44342007202690a93763949
464
+ Author: Scott Chacon <schacon@gee-mail.com>
465
+ Date: Mon Mar 17 21:52:11 2008 -0700
466
+
467
+ changed the version number
468
+
469
+ diff --git a/Rakefile b/Rakefile
470
+ index a874b73..8f94139 100644
471
+ --- a/Rakefile
472
+ +++ b/Rakefile
473
+ @@ -5,5 +5,5 @@ require 'rake/gempackagetask'
474
+ spec = Gem::Specification.new do |s|
475
+ s.name = "simplegit"
476
+ - s.version = "0.1.0"
477
+ + s.version = "0.1.1"
478
+ s.author = "Scott Chacon"
479
+ s.email = "schacon@gee-mail.com
480
+
481
+ commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
482
+ Author: Scott Chacon <schacon@gee-mail.com>
483
+ Date: Sat Mar 15 16:40:33 2008 -0700
484
+
485
+ removed unnecessary test code
486
+
487
+ diff --git a/lib/simplegit.rb b/lib/simplegit.rb
488
+ index a0a60ae..47c6340 100644
489
+ --- a/lib/simplegit.rb
490
+ +++ b/lib/simplegit.rb
491
+ @@ -18,8 +18,3 @@ class SimpleGit
492
+ end
493
+
494
+ end
495
+ -
496
+ -if $0 == __FILE__
497
+ - git = SimpleGit.new
498
+ - puts git.show
499
+ -end
500
+
501
+
502
+ 這個選項除了顯示相同的資訊外,還另外附上每個更新的差異。 這對於重新檢視或者快速的瀏覽協同工作伙伴新增的更新非常有幫助。
503
+
504
+ 有時候用 word level 的方式比 line level 更容易看懂變化。在 `git log -p` 後面附加 `--word-diff` 選項,就可以取代預設的 line level 模式。當你在看原始碼的時候 word level 還挺有用的,還有一些大型文字檔,如書籍或論文就派上用場了,範例如下:
505
+
506
+ $ git log -U1 --word-diff
507
+ commit ca82a6dff817ec66f44342007202690a93763949
508
+ Author: Scott Chacon <schacon@gee-mail.com>
509
+ Date: Mon Mar 17 21:52:11 2008 -0700
510
+
511
+ changed the version number
512
+
513
+ diff --git a/Rakefile b/Rakefile
514
+ index a874b73..8f94139 100644
515
+ --- a/Rakefile
516
+ +++ b/Rakefile
517
+ @@ -7,3 +7,3 @@ spec = Gem::Specification.new do |s|
518
+ s.name = "simplegit"
519
+ s.version = [-"0.1.0"-]{+"0.1.1"+}
520
+ s.author = "Scott Chacon"
521
+
522
+ 如你所見,輸出範例中沒有列出新增與刪除的行,變動的地方用內嵌的方式顯示,你可以看到新增的字被包括在 `{+ +}` 內,而刪除的則包括在 `[- -]` 內,如果你想再減少顯示的資訊,將上述的三行再減少到只顯示變動的那行。你可以用 `-U1` 選項,就像上述的範例中那樣。
523
+
524
+ 另外也可以使用`git log`提供的一系統摘要選項。 例如:若想檢視每個更新的簡略統計資訊,可使用 `--stat` 選項:
525
+
526
+ $ git log --stat
527
+ commit ca82a6dff817ec66f44342007202690a93763949
528
+ Author: Scott Chacon <schacon@gee-mail.com>
529
+ Date: Mon Mar 17 21:52:11 2008 -0700
530
+
531
+ changed the version number
532
+
533
+ Rakefile | 2 +-
534
+ 1 file changed, 1 insertion(+), 1 deletion(-)
535
+
536
+ commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
537
+ Author: Scott Chacon <schacon@gee-mail.com>
538
+ Date: Sat Mar 15 16:40:33 2008 -0700
539
+
540
+ removed unnecessary test code
541
+
542
+ lib/simplegit.rb | 5 -----
543
+ 1 file changed, 5 deletions(-)
544
+
545
+ commit a11bef06a3f659402fe7563abf99ad00de2209e6
546
+ Author: Scott Chacon <schacon@gee-mail.com>
547
+ Date: Sat Mar 15 10:31:28 2008 -0700
548
+
549
+ first commit
550
+
551
+ README | 6 ++++++
552
+ Rakefile | 23 +++++++++++++++++++++++
553
+ lib/simplegit.rb | 25 +++++++++++++++++++++++++
554
+ 3 files changed, 54 insertions(+)
555
+
556
+ 如以上所示,`--stat`選項在每個更新項目的下方列出被更動的檔案、有多少檔案被更動,以及有多行列被加入或移出該檔案。 也會在最後印出摘要的訊息。
557
+ 其它實用的選項是 `--pretty`。 這個選項改變原本預設輸出的格式。 有數個內建的選項供讀者選用。 其中 `oneline` 選項將每一個更新印到單獨一行,對於檢視很多更新時很有用。 更進一步,`short`、`full`、`fuller` 選項輸出的格式大致相同,但會少一些或者多一些資訊。
558
+
559
+ $ git log --pretty=oneline
560
+ ca82a6dff817ec66f44342007202690a93763949 changed the version number
561
+ 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test code
562
+ a11bef06a3f659402fe7563abf99ad00de2209e6 first commit
563
+
564
+ 最有趣的選項是 `format`,允許讀者指定自訂的輸出格式。 當需要輸出給機器分析時特別有用。 因為明確地指定了格式,即可確定它不會因為更新 Git 而被更動:
565
+
566
+ $ git log --pretty=format:"%h - %an, %ar : %s"
567
+ ca82a6d - Scott Chacon, 11 months ago : changed the version number
568
+ 085bb3b - Scott Chacon, 11 months ago : removed unnecessary test code
569
+ a11bef0 - Scott Chacon, 11 months ago : first commit
570
+
571
+ 表格2-1列出一些 `format` 支援的選項。
572
+
573
+ <!-- Attention to translators: this is a table declaration.
574
+ The lines must be formatted as follows
575
+ <TAB><First column text><TAB><Second column text>
576
+ -->
577
+
578
+ 選項 選項的說明
579
+ %H 該更新的SHA1雜湊值
580
+ %h 該更新的簡短SHA1雜湊值
581
+ %T 存放該更新的根目錄的Tree物件的SHA1雜湊值
582
+ %t 存放該更新的根目錄的Tree物件的簡短SHA1雜湊值
583
+ %P 該更新的父更新的SHA1雜湊值
584
+ %p 該更新的父更新的簡短SHA1雜湊值
585
+ %an 作者名字
586
+ %ae 作者電子郵件
587
+ %ad 作者的日期 (格式依據 date 選項而不同)
588
+ %ar 相對於目前時間的作者的日期
589
+ %cn 提交者的名字
590
+ %ce 提交者的電子郵件
591
+ %cd 提交的日期
592
+ %cr 相對於目前時間的提交的日期
593
+ %s 標題
594
+
595
+ 讀者可能會好奇 __作者__ 與 __提交者__ 之間的差別。 __作者__ 是完成該工作的人,而 __提交者__ 則是最後將該工作提交出來的人。 因此,若讀者將某個專案的修補檔送出,而且該專案的核心成員中一員套用該更新,則讀者與該成員皆會被列入該更新。 讀者即 __作者__,而該成員則是 __提交者__。 在第五章會提到較多之間的差別。
596
+
597
+ `oneline` 及 `format` 選項對於另一個名為 `--graph` 的選項特別有用。 該選項以 ASCII 畫出分支的分歧及合併的歷史。 可參考我們的 Grit 的儲存庫:
598
+
599
+ $ git log --pretty=format:"%h %s" --graph
600
+ * 2d3acf9 ignore errors from SIGCHLD on trap
601
+ * 5e3ee11 Merge branch 'master' of git://github.com/dustin/grit
602
+ |\
603
+ | * 420eac9 Added a method for getting the current branch.
604
+ * | 30e367c timeout code and tests
605
+ * | 5a09431 add timeout protection to grit
606
+ * | e1193f8 support for heads with slashes in them
607
+ |/
608
+ * d6016bc require time for xmlschema
609
+ * 11d191e Merge branch 'defunkt' into local
610
+
611
+ 這些只是一些簡單的 `git log` 的選項,還有許多其它的。 表格2-2列出目前我們涵蓋的及一些可能有用的格式選項,以及它們如何更動 `log` 命令的輸出格式。
612
+
613
+ <!-- Attention to translators: this is a table declaration.
614
+ The lines must be formatted as follows
615
+ <TAB><First column text><TAB><Second column text>
616
+ -->
617
+
618
+ 選項 選項的說明
619
+ -p 顯示每個更新與上一個的差異。
620
+ --word-diff 使用 word diff 格式顯示 patch 內容。
621
+ --stat 顯示每個更新更動的檔案的統計及摘要資訊。
622
+ --shortstat 僅顯示--stat提供的的訊息中關於更動、插入、刪除的文字。
623
+ --name-only 在更新的訊息後方顯示更動的檔案列表。
624
+ --name-status 顯示新增、更動、刪除的檔案列表。
625
+ --abbrev-commit 僅顯示SHA1查核值的前幾位數,而不是顯示全部的40位數。
626
+ --relative-date 以相對於目前時間方式顯示日期(例如:“2 weeks ago”),而不是完整的日期格式。
627
+ --graph 以 ASCII 在 log 輸出旁邊畫出分支的分歧及合併。
628
+ --pretty 以其它格式顯示更新。 可用的選項包含oneline、short、full、fuller及可自訂格式的format。
629
+ --oneline `--pretty=oneline --abbrev-commit` 的簡短用法。
630
+
631
+ ### 限制 log 的輸出範圍 ###
632
+
633
+ 除了輸出格式的選項,`git log`也接受一些好用的選項。 也就是指定只顯示某一個子集合的更新。 先前已介紹過僅顯示最後兩筆更新的 `-2` 選項。 實際上可指定 `-<n>`,而 `n` 是任何整數,用來顯示最後的 `n` 個更新。 不過讀者可能不太會常用此選項,因為 Git 預設將所有的輸出導到分頁程式,故一次只會看到一頁。
634
+
635
+ 然而,像 `--since` 及 `--until` 限制時間的選項就很有用。 例如,以下命令列出最近兩週的更新:
636
+
637
+ $ git log --since=2.weeks
638
+
639
+ 此命令支援多種格式。 可指定特定日期(如:“2008-01-15”)或相對的日期,如:“2 years 1 day 3 minutes ago”。
640
+
641
+ 使用者也可以過濾出符合某些搜尋條件的更新。 `--author` 選項允許使用者過濾出特定作者,而 `--grep` 選項允許以關鍵字搜尋提交的訊息。(注意:若同時使用作者名字及字串比對,該命令會列出同時符合二個條件的更新。)
642
+
643
+ 若希望比對多個字串,需要再加上 `--all-match`;否則只會列出符合任一條件的更新。
644
+
645
+ 最後一個有用的選項是過濾路徑。 若指定目錄或檔案名稱,可僅印出更動到這些檔案的更新。 這選項永遠放在最後,而且一般來說會在前方加上 -- 以資區別。
646
+
647
+ 在表格2-3,我們列出這些選項以及少數其它常見選項以供參考。
648
+
649
+ <!-- Attention to translators: this is a table declaration.
650
+ The lines must be formatted as follows
651
+ <TAB><First column text><TAB><Second column text>
652
+ -->
653
+
654
+ 選項 選項的說明文字
655
+ -(n) 僅顯示最後 n 個更新
656
+ --since, --after 列出特定日期後的更新。
657
+ --until, --before 列出特定日期前的更新。
658
+ --author 列出作者名稱符合指定字串的更新。
659
+ --committer 列出提交者名稱符合指定字串的更新。
660
+
661
+ 例如:若想檢視 Git 的原始碼中,Junio Hamano 在 2008 年十月提交且不是合併用的更新。 可執行以下命令:
662
+
663
+ $ git log --pretty="%h - %s" --author=gitster --since="2008-10-01" \
664
+ --before="2008-11-01" --no-merges -- t/
665
+ 5610e3b - Fix testcase failure when extended attribute
666
+ acd3b9e - Enhance hold_lock_file_for_{update,append}()
667
+ f563754 - demonstrate breakage of detached checkout wi
668
+ d1a43f2 - reset --hard/read-tree --reset -u: remove un
669
+ 51a94af - Fix "checkout --track -b newbranch" on detac
670
+ b0ad11e - pull: allow "git pull origin $something:$cur
671
+
672
+ Git 原始碼的更新歷史接近二萬筆更新,本命令顯示符合條件的六筆更新。
673
+
674
+ ### 使用圖形界面檢視歷史 ###
675
+
676
+ 若讀者較偏向使用圖形界面檢視歷史,或許會想看一下隨著 Git 發佈的,名為 `gitk` 的 Tcl/Tk 程式。 Gitk 基本上就是 `git log` 的圖形界面版本,而且幾乎接受所有 `git log` 支援的過濾用選項。 若在專案所在目錄下執行 gitk 命令,將會看到如圖2-2的畫面。
677
+
678
+ Insert 18333fig0202.png
679
+ 圖2-2。 gitk檢視歷史程式。
680
+
681
+ 在上圖中可看到視窗的上半部顯示相當棒的更新歷史圖。 視窗下半部則顯示當時被點選的更新引入的變更。
682
+
683
+ ## 復原 ##
684
+
685
+ 在任何時間點,或許讀者會想要復原一些事情。 接下來我們會介紹一些基本的復原方式。 但要注意,由於有些復原動作所做的變更無法再被還原。 這是少數在使用 Git 時,執行錯誤的動作會遺失資料的情況。
686
+
687
+ ### 更動最後一筆更新 ###
688
+
689
+ 最常見的復原發生在太早提交更新,也許忘了加入某些檔案、或者搞砸了提交的訊息。 若想要試著重新提交,可試著加上 `--amend` 選項:
690
+
691
+ $ git commit --amend
692
+
693
+ 此命令取出暫存區資料並用來做本次的提交。 只要在最後一次提交後沒有做過任何修改(例如:在上一次提交後,馬上執行此命令),那麼整個快照看起來會與上次提交的一模一樣,唯一有更動的是提交時的訊息。
694
+
695
+ 同一個文書編輯器被帶出來,並且已包含先前提交的更新內的訊息。 讀者可像往常一樣編輯這些訊息,差別在於它們會覆蓋上一次提交。
696
+
697
+ 如下例,若提交了更新後發現忘了一併提交某些檔案,可執行最後一個命令:
698
+
699
+ $ git commit -m 'initial commit'
700
+ $ git add forgotten_file
701
+ $ git commit --amend
702
+
703
+ 這些命令的僅僅會提交一個更新,第二個被提交的更新會取代第一個。
704
+
705
+ ### 取消已被暫存的檔案 ###
706
+
707
+ 接下來兩節展示如何應付暫存區及工作目錄的復原。 用來判斷這兩個區域狀態的命令也以相當好的方式提示如何復原。 比如說已經修改兩個檔案,並想要以兩個不同的更新提交它們,不過不小心執行 `git add *` 將它們同時都加入暫存區。 應該如何將其中一個移出暫存區? `git status` 命令已附上相關的提示:
708
+
709
+ $ git add .
710
+ $ git status
711
+ On branch master
712
+ Changes to be committed:
713
+ (use "git reset HEAD <file>..." to unstage)
714
+
715
+ modified: README.txt
716
+ modified: benchmarks.rb
717
+
718
+
719
+ 在 “Changes to be commited” 文字下方,註明著使用 “`git reset HEAD <file>...`,將 file 移出暫存區”。 因此,讓我們依循該建議將 `benchmarks.rb` 檔案移出暫存區:
720
+
721
+ $ git reset HEAD benchmarks.rb
722
+ Unstaged changes after reset:
723
+ M benchmarks.rb
724
+ $ git status
725
+ On branch master
726
+ Changes to be committed:
727
+ (use "git reset HEAD <file>..." to unstage)
728
+
729
+ modified: README.txt
730
+
731
+ Changes not staged for commit:
732
+ (use "git add <file>..." to update what will be committed)
733
+ (use "git checkout -- <file>..." to discard changes in working directory)
734
+
735
+ modified: benchmarks.rb
736
+
737
+
738
+ 這個命令看起來有點奇怪,不過它的確可行。 `benchmarks.rb` 檔案被移出暫存區了。
739
+
740
+ ### 復原已被更動的檔案 ###
741
+
742
+ 若讀者發現其者並不需要保留 `benchmarks.rb` 檔案被更動部份,應該如何做才能很容易的復原為最後一次提交的狀態(或者最初複製儲存庫時、或放到工作目錄時的版本)? 很幸運的,`git status` 同樣也告訴讀者如何做。 在最近一次檢視狀態時,暫存區看起來應如下所示:
743
+
744
+ Changes not staged for commit:
745
+ (use "git add <file>..." to update what will be committed)
746
+ (use "git checkout -- <file>..." to discard changes in working directory)
747
+
748
+ modified: benchmarks.rb
749
+
750
+
751
+ 在這訊息中已很明確的說明如何拋棄所做的修改(至少需升級為 Git 1.6.1或更新版本。 若讀者使用的是舊版,強烈建議升級,以取得更好用的功能。) 讓我們依據命令執行:
752
+
753
+ $ git checkout -- benchmarks.rb
754
+ $ git status
755
+ On branch master
756
+ Changes to be committed:
757
+ (use "git reset HEAD <file>..." to unstage)
758
+
759
+ modified: README.txt
760
+
761
+
762
+ 在上述文字可看到該變更已被復原。 讀者應該瞭解這是危險的命令,任何對該檔案做的修改將不復存在,就好像複製別的檔案將它覆蓋。 除非很清楚真的不需要該檔案,絕不要使用此檔案。 若需要將這些修改排除,我們在下一章節會介紹備份及分支。 一般來說會比此方法來的好。
763
+
764
+ 切記,任何在 Git 提交的更新幾乎都是可復原的。 即使是分支中的更新被刪除或被 `--amend` 覆寫,皆能被復原。(參考第九章關於資料的復原) 然而,未被提交的則幾乎無法救回。
765
+
766
+ ## 與遠端協同工作 ##
767
+
768
+ 想要在任何Git控管的專案協同作業,需要瞭解如何管理遠端的儲存庫。 遠端儲存庫是置放在網際網路或網路其它地方中的專案版本。 讀者可設定多個遠端儲存庫,具備唯讀或可讀寫的權限。 與他人協同作業時,需要管理這些遠端儲存庫,並在需要分享工作時上傳或下載資料。
769
+ 管理遠端儲存庫包含瞭解如何新增遠端儲存庫、移除已失效的儲存庫、管理許多分支及定義是否要追蹤它們等等。 本節包含如何遠端管理的技巧。
770
+
771
+ ### 顯示所有的遠端儲存庫 ###
772
+
773
+ 欲瞭解目前已加進來的遠端儲存庫,可執行 `git remote` 命令。 它會列出當初加入遠端儲存庫時指定的名稱。 若目前所在儲存庫是從其它儲存庫複製過來的,至少應該看到 *origin*,也就是 Git 複製儲存庫時預設名字:
774
+
775
+ $ git clone git://github.com/schacon/ticgit.git
776
+ Cloning into 'ticgit'...
777
+ remote: Reusing existing pack: 1857, done.
778
+ remote: Total 1857 (delta 0), reused 0 (delta 0)
779
+ Receiving objects: 100% (1857/1857), 374.35 KiB | 193.00 KiB/s, done.
780
+ Resolving deltas: 100% (772/772), done.
781
+ Checking connectivity... done.
782
+ $ cd ticgit
783
+ $ git remote
784
+ origin
785
+
786
+ 也可以再加上 `-v` 參數,將會在名稱後方顯示其URL:
787
+
788
+ $ git remote -v
789
+ origin git://github.com/schacon/ticgit.git (fetch)
790
+ origin git://github.com/schacon/ticgit.git (push)
791
+
792
+ 若有一個以上遠端儲存庫,此命令會全部列出。 例如:我的 Grit 儲存庫包含以下遠端儲存庫。
793
+
794
+ $ cd grit
795
+ $ git remote -v
796
+ bakkdoor git://github.com/bakkdoor/grit.git
797
+ cho45 git://github.com/cho45/grit.git
798
+ defunkt git://github.com/defunkt/grit.git
799
+ koke git://github.com/koke/grit.git
800
+ origin git@github.com:mojombo/grit.git
801
+
802
+ 這意謂著我可以很容易從這些伙伴的儲存庫取得最新的更新。 要留意的是只有 origin 遠端的 URL 是 SSH。 因此它是唯一我能上傳的遠端的儲存庫。(關於這部份將在第四章介紹)
803
+
804
+ ### 新增遠端儲存庫 ###
805
+
806
+ 在先前章節已提到並示範如何新增遠端儲存庫,這邊會很明確的說明如何做這項工作。 欲新增遠端儲存庫並取一個簡短的名字,執行 `git remote add [shortname] [url]`:
807
+
808
+ $ git remote
809
+ origin
810
+ $ git remote add pb git://github.com/paulboone/ticgit.git
811
+ $ git remote -v
812
+ origin git://github.com/schacon/ticgit.git
813
+ pb git://github.com/paulboone/ticgit.git
814
+
815
+ 現在可看到命令列中的 `pb` 字串取代了整個 URL。 例如,若想取得 Paul 上傳的且本地端儲存庫沒有的更新,可執行 `git fetch pb`:
816
+
817
+ $ git fetch pb
818
+ remote: Counting objects: 58, done.
819
+ remote: Compressing objects: 100% (41/41), done.
820
+ remote: Total 44 (delta 24), reused 1 (delta 0)
821
+ Unpacking objects: 100% (44/44), done.
822
+ From git://github.com/paulboone/ticgit
823
+ * [new branch] master -> pb/master
824
+ * [new branch] ticgit -> pb/ticgit
825
+
826
+ 現在可在本地端使用 `pb/master` 存取 Paul 的 master 分支。 讀者可將它合併到本地端任一分支、或者建立一個本地端的分支指向它,如果讀者想監看它。
827
+
828
+ ### 從遠端儲存庫擷取或合併 ###
829
+
830
+ 如剛才所示,欲從遠端擷取資料,可執行:
831
+
832
+ $ git fetch [remote-name]
833
+
834
+ 此命令到該遠端專案將所有本地端沒有的資料拉下來。 在執行此動作後,讀者應該有參考到該遠端專案所有分支的參考點,可在任何時間點用來合併或監看。(在第三章將會提及更多關於如何使用分支的細節)
835
+
836
+ 若複製了一個儲存庫,會自動將該遠端儲存庫命令為 *origin*。 因此 `git fetch origin` 取出所有在複製或最後一下擷取後被上傳到該儲存庫的更新。 需留意的是 `fetch` 命令僅僅將資料拉到本地端的儲存庫,並未自動將它合併進來,也沒有修改任何目前工作的項目。 讀者得在必要時將它們手動合併進來。
837
+
838
+ 若讀者設定一個會追蹤遠端分支的分支(參考下一節及第三章,取得更多資料),可使用 `git pull` 命令自動擷取及合併遠端分支到目錄的分支。 這對讀者來說或許是較合適的工作流程。 而且 `git clone` 命令預設情況下會自動設定本地端的 master 分支追蹤被複製的遠端儲存庫的 master 分支。(假設該儲存庫有 master 分支) 執行 `git pull` 一般來說會從當初複製時的來源儲存庫擷取資料並自動試著合併到目前工作的版本。
839
+
840
+ ### 上傳到遠端儲存庫 ###
841
+
842
+ 當讀者有想分享出去的專案,可將更新上傳到上游。 執行此動作的命令很簡單:`git push [remote-name] [branch-name]`。 若想要上傳 master 分支到 `origin` 伺服器(再說一次,複製時通常自動設定此名字),接著執行以下命令即可上傳到伺服器:
843
+
844
+ $ git push origin master
845
+
846
+ 此命令只有在被複製的伺服器開放寫入權限給使用者,而且同一時間內沒有其它人在上傳。 若讀者在其它同樣複製該伺服器的使用者上傳一些更新後上傳到上游,該上傳動作將會被拒絕。 讀者必須先將其它使用者上傳的資料拉下來並整合進來後才能上傳。 參考第三章瞭解如何上傳到遠端儲存庫的細節。
847
+
848
+ ### 監看遠端儲存庫 ###
849
+
850
+ 若讀者想取得遠端儲存庫某部份更詳盡的資料,可執行 `git remote show [remote-name]`。 若執行此命令時加上特定的遠端名字,比如說: `origin`。 會看到類似以下輸出:
851
+
852
+ $ git remote show origin
853
+ * remote origin
854
+ URL: git://github.com/schacon/ticgit.git
855
+ Remote branch merged with 'git pull' while on branch master
856
+ master
857
+ Tracked remote branches
858
+ master
859
+ ticgit
860
+
861
+ 它將同時列出遠端儲存庫的URL位置和追蹤分支資訊。特別是告訴你如果你在master分支時用`git pull`時,會去自動抓取數據合併到本地的master分支。它也列出所有曾經被抓取過的遠端分支。
862
+
863
+ 當你使用Git更頻繁之後,你或許會想利用 `git remote show` 去看到更多的資訊。
864
+
865
+ $ git remote show origin
866
+ * remote origin
867
+ URL: git@github.com:defunkt/github.git
868
+ Remote branch merged with 'git pull' while on branch issues
869
+ issues
870
+ Remote branch merged with 'git pull' while on branch master
871
+ master
872
+ New remote branches (next fetch will store in remotes/origin)
873
+ caching
874
+ Stale tracking branches (use 'git remote prune')
875
+ libwalker
876
+ walker2
877
+ Tracked remote branches
878
+ acl
879
+ apiv2
880
+ dashboard2
881
+ issues
882
+ master
883
+ postgres
884
+ Local branch pushed with 'git push'
885
+ master:master
886
+
887
+ 這個指令顯示當你執行`git push`會自動推送的哪個分支(最後兩行)。它也顯示哪些遠端分支還沒被同步到本地端(在這個例子是caching),哪些已同步到本地的遠端分支在遠端已被刪除(libwalker和walker2),以及當執行`git pull`時會自動被合併的分支。
888
+
889
+ ### 移除或更名遠端儲存庫 ###
890
+
891
+ 在新版 Git 中可以用 `git remote rename` 命令修改某個遠端儲存庫在本地的簡稱,舉例而言,想把 `pb` 改成 `paul`,可以執行下列指令:
892
+
893
+
894
+ $ git remote rename pb paul
895
+ $ git remote
896
+ origin
897
+ paul
898
+
899
+ 值得留意的是這也改變了遠端分支的名稱,原來的 `pb/master` 分支現在變成 `paul/master`。
900
+
901
+ 當你為了種種原因想要移除某個遠端,像是換伺服器或是已不再使用某個特別的鏡像,又或是某個貢獻者已不再貢獻時。你可以使用`git remote rm`:
902
+
903
+ $ git remote rm paul
904
+ $ git remote
905
+ origin
906
+
907
+ ## 標籤 ##
908
+
909
+ 就像大多數的版本管理系統,Git具備在特定時間點加入標籤去註明其重要性的功能。一般而言,我們會使用這個功能去標記出發行版本(如V1.0等等)。這個小節中,你將會學到如何列出既有的標籤、建立新標籤以及各種不同標籤間的差異。
910
+
911
+
912
+ ### 列出標籤 ###
913
+
914
+ 在Git中列出既有的標籤是非常簡單的。直接輸入`git tag`:
915
+
916
+ $ git tag
917
+ v0.1
918
+ v1.3
919
+
920
+ 這個指令將以字母順序列出標籤;所以這個順序並不代表其重要性。
921
+
922
+ 你也可以用特定的字串規則去搜尋標籤。以Git本身的儲存庫為例,其中包含超過240個標籤。當你只對1.4.2感興趣時,你可以執行以下指令:
923
+
924
+ $ git tag -l 'v1.4.2.*'
925
+ v1.4.2.1
926
+ v1.4.2.2
927
+ v1.4.2.3
928
+ v1.4.2.4
929
+
930
+ ### 建立標籤 ###
931
+
932
+ Git使用兩大類的標籤:輕量級(lightweight)和含附註(annotated)。輕量級標籤就像是沒有更動的分支,實際上它僅是指到特定commit的指標。然而,含附註的標籤則是實際存在Git資料庫上的完整物件。它具備檢查碼、e-mail和日期,也包含標籤訊息,並可以被GNU Privacy Guard (GPG)簽署和驗證。一般而言,我們都建議使用含附註的標籤以便保留相關訊息;但如果只是臨時加註標籤或不需要保留其他訊息,就是使用輕量級標籤的時機。
933
+
934
+ ### 含附註的標籤 ###
935
+
936
+ 建立一個含附註的標籤很簡單。最容易的方法是加入`-a`到`tag`指令上:
937
+
938
+ $ git tag -a v1.4 -m 'my version 1.4'
939
+ $ git tag
940
+ v0.1
941
+ v1.3
942
+ v1.4
943
+
944
+ 而`-m`選項用來設定標籤訊息。如果你沒有設定該訊息,Git會啟動文字編輯器讓你輸入。
945
+
946
+ 透過`git show`可看到指定標籤的資料與對應的commit。
947
+
948
+ $ git show v1.4
949
+ tag v1.4
950
+ Tagger: Scott Chacon <schacon@gee-mail.com>
951
+ Date: Mon Feb 9 14:45:11 2009 -0800
952
+
953
+ my version 1.4
954
+
955
+ commit 15027957951b64cf874c3557a0f3547bd83b3ff6
956
+ Merge: 4a447f7... a6b4c97...
957
+ Author: Scott Chacon <schacon@gee-mail.com>
958
+ Date: Sun Feb 8 19:02:46 2009 -0800
959
+
960
+ Merge branch 'experiment'
961
+
962
+ 在列出commit資訊前,我們可以看到這個標籤的設定者資訊,下標籤時間與附註訊息。
963
+
964
+ ### 簽署標籤 ###
965
+
966
+ 假設你有私鑰(private key),你也可以用GPG簽署在標籤上。只要用`-s`取代`-a`:
967
+
968
+ $ git tag -s v1.5 -m 'my signed 1.5 tag'
969
+ You need a passphrase to unlock the secret key for
970
+ user: "Scott Chacon <schacon@gee-mail.com>"
971
+ 1024-bit DSA key, ID F721C45A, created 2009-02-09
972
+
973
+ 再對這個標籤執行`git show`,你就能看到你的GPG簽章以經附在裡面:
974
+
975
+ $ git show v1.5
976
+ tag v1.5
977
+ Tagger: Scott Chacon <schacon@gee-mail.com>
978
+ Date: Mon Feb 9 15:22:20 2009 -0800
979
+
980
+ my signed 1.5 tag
981
+ -----BEGIN PGP SIGNATURE-----
982
+ Version: GnuPG v1.4.8 (Darwin)
983
+
984
+ iEYEABECAAYFAkmQurIACgkQON3DxfchxFr5cACeIMN+ZxLKggJQf0QYiQBwgySN
985
+ Ki0An2JeAVUCAiJ7Ox6ZEtK+NvZAj82/
986
+ =WryJ
987
+ -----END PGP SIGNATURE-----
988
+ commit 15027957951b64cf874c3557a0f3547bd83b3ff6
989
+ Merge: 4a447f7... a6b4c97...
990
+ Author: Scott Chacon <schacon@gee-mail.com>
991
+ Date: Sun Feb 8 19:02:46 2009 -0800
992
+
993
+ Merge branch 'experiment'
994
+
995
+ 稍後你會看到如何驗證已簽署的標籤。
996
+
997
+ ### 輕量級的標籤 ###
998
+
999
+ 另一種則是輕量級的標籤。基本上就是只保存commit檢查碼的文件。要建立這樣的標籤,不必下任何選項,直接設定標籤名稱即可。
1000
+
1001
+ $ git tag v1.4-lw
1002
+ $ git tag
1003
+ v0.1
1004
+ v1.3
1005
+ v1.4
1006
+ v1.4-lw
1007
+ v1.5
1008
+
1009
+ 這樣一來,當執行`git show`查看這個標籤時,你不會看到其他標籤資訊,只會顯示對應的commit:
1010
+
1011
+ $ git show v1.4-lw
1012
+ commit 15027957951b64cf874c3557a0f3547bd83b3ff6
1013
+ Merge: 4a447f7... a6b4c97...
1014
+ Author: Scott Chacon <schacon@gee-mail.com>
1015
+ Date: Sun Feb 8 19:02:46 2009 -0800
1016
+
1017
+ Merge branch 'experiment'
1018
+
1019
+ ### 驗證標籤 ###
1020
+
1021
+ 想要驗證已簽署的標籤,需要使用`git tag -v [tag-name]`。這個指令透過GPG去驗證簽章。而且在你的keyring中需要有簽署者的公鑰才能進行驗證:
1022
+
1023
+ $ git tag -v v1.4.2.1
1024
+ object 883653babd8ee7ea23e6a5c392bb739348b1eb61
1025
+ type commit
1026
+ tag v1.4.2.1
1027
+ tagger Junio C Hamano <junkio@cox.net> 1158138501 -0700
1028
+
1029
+ GIT 1.4.2.1
1030
+
1031
+ Minor fixes since 1.4.2, including git-mv and git-http with alternates.
1032
+ gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
1033
+ gpg: Good signature from "Junio C Hamano <junkio@cox.net>"
1034
+ gpg: aka "[jpeg image of size 1513]"
1035
+ Primary key fingerprint: 3565 2A26 2040 E066 C9A7 4A7D C0C6 D9A4 F311 9B9A
1036
+
1037
+ 如果沒有簽署者的公鑰,則會看到下列訊息:
1038
+
1039
+ gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
1040
+ gpg: Can't check signature: public key not found
1041
+ error: could not verify the tag 'v1.4.2.1'
1042
+
1043
+ ### 追加標籤 ###
1044
+
1045
+ 你也可以對過去的commit上加入標籤。假設你的commit歷史如下:
1046
+
1047
+ $ git log --pretty=oneline
1048
+ 15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
1049
+ a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support
1050
+ 0d52aaab4479697da7686c15f77a3d64d9165190 one more thing
1051
+ 6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'experiment'
1052
+ 0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc added a commit function
1053
+ 4682c3261057305bdd616e23b64b0857d832627b added a todo file
1054
+ 166ae0c4d3f420721acbb115cc33848dfcc2121a started write support
1055
+ 9fceb02d0ae598e95dc970b74767f19372d61af8 updated rakefile
1056
+ 964f16d36dfccde844893cac5b347e7b3d44abbc commit the todo
1057
+ 8a5cbc430f1a9c3d00faaeffd07798508422908a updated readme
1058
+
1059
+ 如果你之前忘了將"updated rakefile"這個commit加入v1.2標籤。仍然可在事後設定。要完成這個動作,你必須加入該次commit的檢查碼(或前幾碼即可)到以下指令:
1060
+
1061
+ $ git tag -a v1.2 9fceb02
1062
+
1063
+ 你可以看到標籤已經補上:
1064
+
1065
+ $ git tag
1066
+ v0.1
1067
+ v1.2
1068
+ v1.3
1069
+ v1.4
1070
+ v1.4-lw
1071
+ v1.5
1072
+
1073
+ $ git show v1.2
1074
+ tag v1.2
1075
+ Tagger: Scott Chacon <schacon@gee-mail.com>
1076
+ Date: Mon Feb 9 15:32:16 2009 -0800
1077
+
1078
+ version 1.2
1079
+ commit 9fceb02d0ae598e95dc970b74767f19372d61af8
1080
+ Author: Magnus Chacon <mchacon@gee-mail.com>
1081
+ Date: Sun Apr 27 20:43:35 2008 -0700
1082
+
1083
+ updated rakefile
1084
+ ...
1085
+
1086
+ ### 分享標籤 ###
1087
+
1088
+ 在預設的情況下,`git push`指令並不會將標籤傳到遠端伺服器上。當建立新標籤後,你必須特別下指令才會將它推送到遠端儲存庫上。類似將分支推送到遠端的過程,透過`git push origin [tagname]`指令。
1089
+
1090
+ $ git push origin v1.5
1091
+ Counting objects: 50, done.
1092
+ Compressing objects: 100% (38/38), done.
1093
+ Writing objects: 100% (44/44), 4.56 KiB, done.
1094
+ Total 44 (delta 18), reused 8 (delta 1)
1095
+ To git@github.com:schacon/simplegit.git
1096
+ * [new tag] v1.5 -> v1.5
1097
+
1098
+ 如果你有很多標籤需要一次推送上去,你也可以加入`--tags`選項到`git push`指令中。這將會傳送所有尚未在遠端伺服器上的標籤。
1099
+
1100
+ $ git push origin --tags
1101
+ Counting objects: 50, done.
1102
+ Compressing objects: 100% (38/38), done.
1103
+ Writing objects: 100% (44/44), 4.56 KiB, done.
1104
+ Total 44 (delta 18), reused 8 (delta 1)
1105
+ To git@github.com:schacon/simplegit.git
1106
+ * [new tag] v0.1 -> v0.1
1107
+ * [new tag] v1.2 -> v1.2
1108
+ * [new tag] v1.4 -> v1.4
1109
+ * [new tag] v1.4-lw -> v1.4-lw
1110
+ * [new tag] v1.5 -> v1.5
1111
+
1112
+ 現在,當其他使用者clone或pull你的儲存庫時,他們也同時會取得所有你的標籤。
1113
+
1114
+ ## 提示和技巧 ##
1115
+
1116
+ 在結束Git基礎這個章節前,我們將介紹有一些將會使你的Git使用經驗更簡單、方便和親切的提示和技巧。或許很多人從未運用過這些技巧,我們也不會假設你在本書的後續章節會使用它們。但你也許會想知道如何使用它們。
1117
+
1118
+ ### 自動補齊 ###
1119
+
1120
+ 如果你用的是 Bash shell,你可以啟動Git本身寫好的自動補齊腳本。下載Git原始碼,切到`contrib/completion`目錄;可以看到檔案名為`git-completion.bash`。將它複製到你的家目錄,並加入以下指令到你的`.bashrc`檔案裡:
1121
+
1122
+ source ~/git-completion.bash
1123
+
1124
+ 如果你想為所有使用者都自動設置Bash shell的補齊功能,在Mac系統上將這個腳本複製到`/opt/local/etc/bash_completion.d`目錄,若你使用Linux系統複製到 `/etc/bash_completion.d/`目錄。這兩個目錄中的脚本,都會在 Bash 啟動時自動載入。
1125
+
1126
+ 如果你在Windows使用Git Bash,也就是利用Windows with msysGit安裝Git,自動補齊功能已預先設定好,可以直接使用。
1127
+
1128
+ 在你輸入Git指令時,只要按下Tab鍵,便會列出所有合適的指令建議:
1129
+
1130
+ $ git co<tab><tab>
1131
+ commit config
1132
+
1133
+ 然後按下Tab鍵兩次,便會提示commit和config這些可用指令。當再輸入`m<tab>`便會自動補齊`git commit`。
1134
+
1135
+ 指令的選項也可以自動補齊,這或許是更實用的功能。舉例而言,當你下`git log`指令時,若忘記該輸入哪個選項,只要輸入開頭字元然後按下Tab去看看可能的選項:
1136
+
1137
+ $ git log --s<tab>
1138
+ --shortstat --since= --src-prefix= --stat --summary
1139
+
1140
+ 這是個好用的小技巧,或許可以省下許多輸入和查文件的時間
1141
+
1142
+ ### Git 命令別名 ###
1143
+
1144
+ 如果僅輸入命令的部份字元,Git並不會幫你推論出你想要下的完整命令。如果你想偷懶,不想輸入Git命令的所有字元,你可以輕易地利用`git config`設定別名(alias)。你也許會想要設定以下這幾個範例:
1145
+
1146
+ $ git config --global alias.co checkout
1147
+ $ git config --global alias.br branch
1148
+ $ git config --global alias.ci commit
1149
+ $ git config --global alias.st status
1150
+
1151
+ 這些例子顯示出,你可以只輸入`git ci`,取代輸入`git commit`。隨著你深入使用Git,將會發現某些命令用得頻繁;這時不妨建立新的別名提高使用效率。
1152
+
1153
+ 利用這個技術將有助於創造出你認為應該存在的命令。舉例而言,為了提高取消暫存檔案的便利性,你可以加入以下命令:
1154
+
1155
+ $ git config --global alias.unstage 'reset HEAD --'
1156
+
1157
+ 這將使得下列兩個命令完全相等:
1158
+
1159
+ $ git unstage fileA
1160
+ $ git reset HEAD fileA
1161
+
1162
+ 使用別名看起來更清楚。另外,加入`last`別名也是很常用的技巧:
1163
+
1164
+ $ git config --global alias.last 'log -1 HEAD'
1165
+
1166
+ 如此一來,將可更簡單地看到最新的提交訊息:
1167
+
1168
+ $ git last
1169
+ commit 66938dae3329c7aebe598c2246a8e6af90d04646
1170
+ Author: Josh Goebel <dreamer3@example.com>
1171
+ Date: Tue Aug 26 19:48:51 2008 +0800
1172
+
1173
+ test for current head
1174
+
1175
+ Signed-off-by: Scott Chacon <schacon@example.com>
1176
+
1177
+ 你可以發現,Git只是簡單地在命令中替換你設定的別名。然而,你不僅希望執行Git 的子命令,而想執行外部命令。在這個情形中,你可以加入`!`字元在所要執行的命令前。這將有助於設計運作於Git儲存庫的自製工具。這個範例藉由設定`git visual`別名去執行`gitk`:
1178
+
1179
+ $ git config --global alias.visual '!gitk'
1180
+
1181
+ ## 總結 ##
1182
+
1183
+ 至此,讀者已具備所有Git的本地端操作,包括:創建和複製儲存庫、建立修改、暫存和提交這些修改,以及檢視在儲存庫中所有修改歷史。接下來,我們將觸及Git的殺手級特性,也就是他的分支模型。