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,689 @@
1
+ # Git 與其他系統 #
2
+
3
+ 世界不是完美的。大多數時候,將所有接觸到的專案全部轉向 Git 是不可能的。有時我們不得不為某個專案使用其他的版本控制系統(VCS, Version Control System ),其中比較常見的是 Subversion 。你將在本章的第一部分學習使用 `git svn`,這是 Git 為 Subversion 附帶的雙向橋接工具。
4
+
5
+ 或許現在你已經在考慮將先前的專案轉向 Git 。本章的第二部分將介紹如何將專案遷移到 Git:先介紹從 Subversion 的遷移,然後是 Perforce,最後介紹如何使用自訂的腳本進行非標準的導入。
6
+
7
+ ## Git 與 Subversion ##
8
+
9
+ 當前,大多數開發中的開源專案以及大量的商業專案都使用 Subversion 來管理源碼。作為最流行的開源版本控制系統,Subversion 已經存在了接近十年的時間。它在許多方面與 CVS 十分類似,後者是前者出現之前代碼控制世界的霸主。
10
+
11
+ Git 最為重要的特性之一是名為 `git svn` 的 Subversion 雙向橋接工具。該工具把 Git 變成了 Subversion 服務的用戶端,從而讓你在本地享受到 Git 所有的功能,而後直接向 Subversion 伺服器推送內容,仿佛在本地使用了 Subversion 用戶端。也就是說,在其他人忍受古董的同時,你可以在本地享受分支合併,使用暫存區域,衍合以及單項挑揀(cherry-picking)等等。這是個讓 Git 偷偷潛入合作開發環境的好東西,在幫助你的開發同伴們提高效率的同時,它還能幫你勸說團隊讓整個專案框架轉向對 Git 的支持。這個 Subversion 之橋是通向分散式版本控制系統(DVCS, Distributed VCS )世界的神奇隧道。
12
+
13
+ ### git svn ###
14
+
15
+ Git 中所有 Subversion 橋接命令的基礎是 `git svn` 。所有的命令都從它開始。相關的命令數目不少,你將通過幾個簡單的工作流程瞭解到其中常見的一些。
16
+
17
+ 值得注意的是,在使用 `git svn` 的時候,你實際是在與 Subversion 互動,Git 比它要高級複雜的多。儘管可以在本地隨意的進行分支和合併,最好還是通過衍合保持線性的提交歷史,儘量避免類似「與遠端 Git 倉庫同步互動」這樣的操作。
18
+
19
+ 避免修改歷史再重新推送的做法,也不要同時推送到並行的 Git 倉庫來試圖與其他 Git 用戶合作。Subersion 只能保存單一的線性提交歷史,一不小心就會被搞糊塗。合作團隊中同時有人用 SVN 和 Git,一定要確保所有人都使用 SVN 服務來協作——這會讓生活輕鬆很多。
20
+
21
+ ### 初始設定 ###
22
+
23
+ 為了展示功能,先要一個具有寫入許可權的 SVN 倉庫。如果想嘗試這個範例,你必須複製一份其中的測試倉庫。比較簡單的做法是使用一個名為 `svnsync` 的工具。較新的 Subversion 版本中都帶有該工具,它將資料編碼為用於網路傳輸的格式。
24
+
25
+ 要嘗試本例,先在本地新建一個 Subversion 倉庫:
26
+
27
+ $ mkdir /tmp/test-svn
28
+ $ svnadmin create /tmp/test-svn
29
+
30
+ 然後,允許所有用戶修改 revprop —— 簡單的做法是添加一個總是以 0 作為傳回值的 pre-revprop-change 腳本:
31
+
32
+ $ cat /tmp/test-svn/hooks/pre-revprop-change
33
+ #!/bin/sh
34
+ exit 0;
35
+ $ chmod +x /tmp/test-svn/hooks/pre-revprop-change
36
+
37
+ 現在可以呼叫 `svnsync init`,參數加目標倉庫,再加來源倉庫,就可以把該專案同步到本地了:
38
+
39
+ $ svnsync init file:///tmp/test-svn http://progit-example.googlecode.com/svn/
40
+
41
+ 這將建立進行同步所需的屬性(property)。可以通過執行以下命令來 clone 程式碼:
42
+
43
+ $ svnsync sync file:///tmp/test-svn
44
+ Committed revision 1.
45
+ Copied properties for revision 1.
46
+ Committed revision 2.
47
+ Copied properties for revision 2.
48
+ Committed revision 3.
49
+ ...
50
+
51
+ 別看這個操作只花掉幾分鐘,要是你想把源倉庫複製到另一個遠端倉庫,而不是本地倉庫,那將花掉接近一個小時,儘管專案中只有不到 100 次的提交。 Subversion 每次只複製一次修改,把它推送到另一個倉庫裡,然後周而復始——驚人的低效率,但是我們別無選擇。
52
+
53
+ ### 入門 ###
54
+
55
+ 有了可以寫入的 Subversion 倉庫以後,就可以嘗試一下典型的工作流程了。我們從 `git svn clone` 命令開始,它會把整個 Subversion 倉庫導入到一個本地的 Git 倉庫中。提醒一下,這裡導入的是一個貨真價實的 Subversion 倉庫,所以應該把下面的 `file:///tmp/test-svn` 換成你所用的 Subversion 倉庫的 URL:
56
+
57
+ $ git svn clone file:///tmp/test-svn -T trunk -b branches -t tags
58
+ Initialized empty Git repository in /Users/schacon/projects/testsvnsync/svn/.git/
59
+ r1 = b4e387bc68740b5af56c2a5faf4003ae42bd135c (trunk)
60
+ A m4/acx_pthread.m4
61
+ A m4/stl_hash.m4
62
+ ...
63
+ r75 = d1957f3b307922124eec6314e15bcda59e3d9610 (trunk)
64
+ Found possible branch point: file:///tmp/test-svn/trunk => \
65
+ file:///tmp/test-svn /branches/my-calc-branch, 75
66
+ Found branch parent: (my-calc-branch) d1957f3b307922124eec6314e15bcda59e3d9610
67
+ Following parent with do_switch
68
+ Successfully followed parent
69
+ r76 = 8624824ecc0badd73f40ea2f01fce51894189b01 (my-calc-branch)
70
+ Checked out HEAD:
71
+ file:///tmp/test-svn/branches/my-calc-branch r76
72
+
73
+ 這相當於針對所提供的 URL 運行了兩條命令—— `git svn init` 加上 `gitsvn fetch` 。可能會花上一段時間。我們所用的測試專案僅僅包含 75 次提交並且它的代碼量不算大,所以只有幾分鐘而已。不過,Git 仍然需要提取每一個版本,每次一個,再逐個提交。對於一個包含成百上千次提交的專案,花掉的時間則可能是幾小時甚至數天。
74
+
75
+ `-T trunk -b branches -t tags` 告訴 Git 該 Subversion 倉庫遵循了基本的分支和標籤命名法則。如果你的主幹(譯注:trunk,相當於非分散式版本控制裡的 master 分支,代表開發的主線)分支或者標籤以不同的方式命名,則應做出相應改變。由於該法則的常見性,可以使用 `-s` 來代替整條命令,它意味著標準佈局(s 是 Standard layout 的首字母),也就是前面選項的內容。下面的命令有相同的效果:
76
+
77
+ $ git svn clone file:///tmp/test-svn -s
78
+
79
+ 現在,你有了一個有效的 Git 倉庫,包含著導入的分支和標籤:
80
+
81
+ $ git branch -a
82
+ * master
83
+ my-calc-branch
84
+ tags/2.0.2
85
+ tags/release-2.0.1
86
+ tags/release-2.0.2
87
+ tags/release-2.0.2rc1
88
+ trunk
89
+
90
+ 值得注意的是,該工具分配命名空間時和遠端參照的方式不盡相同。clone 普通的 Git 倉庫時,可以用 `origin/[branch]` 的形式獲取遠端伺服器上所有可用的分支——分配到遠端服務的名稱下。然而 `git svn` 假定不存在多個遠端伺服器,所以把所有指向遠端服務的引用不加區分(no namespacing)的保存下來。可以用 Git 底層(plumbing)命令 `show-ref` 來查看所有引用的全名:
91
+
92
+ $ git show-ref
93
+ 1cbd4904d9982f386d87f88fce1c24ad7c0f0471 refs/heads/master
94
+ aee1ecc26318164f355a883f5d99cff0c852d3c4 refs/remotes/my-calc-branch
95
+ 03d09b0e2aad427e34a6d50ff147128e76c0e0f5 refs/remotes/tags/2.0.2
96
+ 50d02cc0adc9da4319eeba0900430ba219b9c376 refs/remotes/tags/release-2.0.1
97
+ 4caaa711a50c77879a91b8b90380060f672745cb refs/remotes/tags/release-2.0.2
98
+ 1c4cb508144c513ff1214c3488abe66dcb92916f refs/remotes/tags/release-2.0.2rc1
99
+ 1cbd4904d9982f386d87f88fce1c24ad7c0f0471 refs/remotes/trunk
100
+
101
+ 而普通的 Git 倉庫應該是這個模樣:
102
+
103
+ $ git show-ref
104
+ 83e38c7a0af325a9722f2fdc56b10188806d83a1 refs/heads/master
105
+ 3e15e38c198baac84223acfc6224bb8b99ff2281 refs/remotes/gitserver/master
106
+ 0a30dd3b0c795b80212ae723640d4e5d48cabdff refs/remotes/origin/master
107
+ 25812380387fdd55f916652be4881c6f11600d6f refs/remotes/origin/testing
108
+
109
+ 這裡有兩個遠端伺服器:一個名為 `gitserver` ,具有一個 `master` 分支;另一個叫 `origin`,具有 `master` 和 `testing` 兩個分支。
110
+
111
+ 注意本例中通過 `git svn` 導入的遠端參照,(Subversion 的)標籤是當作遠端分支添加的,而不是真正的 Git 標籤。導入的 Subversion 倉庫仿佛是有一個帶有不同分支的 tags 遠端伺服器。
112
+
113
+ ### 提交到 Subversion ###
114
+
115
+ 有了可以開展工作的(本地)倉庫以後,你可以開始對該專案做出貢獻並向上游倉庫提交內容了,Git 這時相當於一個 SVN 用戶端。假如編輯了一個檔並進行提交,那麼這次提交僅存在於本地的 Git 而非 Subversion 伺服器上:
116
+
117
+ $ git commit -am 'Adding git-svn instructions to the README'
118
+ [master 97031e5] Adding git-svn instructions to the README
119
+ 1 files changed, 1 insertions(+), 1 deletions(-)
120
+
121
+ 接下來,可以將作出的修改推送到上游。值得注意的是,Subversion 的使用流程也因此改變了——你可以在離線狀態下進行多次提交然後一次性的推送到 Subversion 的伺服器上。向 Subversion 伺服器推送的命令是 `git svn dcommit`:
122
+
123
+ $ git svn dcommit
124
+ Committing to file:///tmp/test-svn/trunk ...
125
+ M README.txt
126
+ Committed r79
127
+ M README.txt
128
+ r79 = 938b1a547c2cc92033b74d32030e86468294a5c8 (trunk)
129
+ No changes between current HEAD and refs/remotes/trunk
130
+ Resetting to the latest refs/remotes/trunk
131
+
132
+ 所有在原 Subversion 資料基礎上提交的 commit 會一一提交到 Subversion,然後你本地 Git 的 commit 將被重寫,加入一個特別標識。這一步很重要,因為它意味著所有 commit 的 SHA-1 指都會發生變化。這也是同時使用 Git 和 Subversion 兩種服務作為遠端服務不是個好主意的原因之一。檢視以下最後一個 commit,你會找到新添加的 `git-svn-id` (譯注:即本段開頭所說的特別標識):
133
+
134
+ $ git log -1
135
+ commit 938b1a547c2cc92033b74d32030e86468294a5c8
136
+ Author: schacon <schacon@4c93b258-373f-11de-be05-5f7a86268029>
137
+ Date: Sat May 2 22:06:44 2009 +0000
138
+
139
+ Adding git-svn instructions to the README
140
+
141
+ git-svn-id: file:///tmp/test-svn/trunk@79 4c93b258-373f-11de-be05-5f7a86268029
142
+
143
+ 注意看,原本以 `97031e5` 開頭的 SHA-1 校驗值在提交完成以後變成了 `938b1a5` 。如果既要向 Git 遠端伺服器推送內容,又要推送到 Subversion 遠端伺服器,則必須先向 Subversion 推送(`dcommit`),因為該操作會改變所提交的資料內容。
144
+
145
+ ### 拉取最新進展 ###
146
+
147
+ 如果要與其他開發者協作,總有那麼一天你推送完畢之後,其他人發現他們推送自己修改的時候(與你推送的內容)產生衝突。這些修改在你合併之前將一直被拒絕。在 `git svn` 裡這種情況像這樣:
148
+
149
+ $ git svn dcommit
150
+ Committing to file:///tmp/test-svn/trunk ...
151
+ Merge conflict during commit: Your file or directory 'README.txt' is probably \
152
+ out-of-date: resource out of date; try updating at /Users/schacon/libexec/git-\
153
+ core/git-svn line 482
154
+
155
+ 為了解決該問題,可以執行 `git svn rebase` ,它會拉取伺服器上所有最新的改變,再於此基礎上衍合你的修改:
156
+
157
+ $ git svn rebase
158
+ M README.txt
159
+ r80 = ff829ab914e8775c7c025d741beb3d523ee30bc4 (trunk)
160
+ First, rewinding head to replay your work on top of it...
161
+ Applying: first user change
162
+
163
+ 現在,你做出的修改都在 Subversion 伺服器上,所以可以順利的運行 `dcommit` :
164
+
165
+ $ git svn dcommit
166
+ Committing to file:///tmp/test-svn/trunk ...
167
+ M README.txt
168
+ Committed r81
169
+ M README.txt
170
+ r81 = 456cbe6337abe49154db70106d1836bc1332deed (trunk)
171
+ No changes between current HEAD and refs/remotes/trunk
172
+ Resetting to the latest refs/remotes/trunk
173
+
174
+ 需要牢記的一點是,Git 要求我們在推送之前先合併上游倉庫中最新的內容,而 `git svn` 只要求存在衝突的時候才這樣做。假如有人向一個檔推送了一些修改,這時你要向另一個文件推送一些修改,那麼 `dcommit` 將正常工作:
175
+
176
+ $ git svn dcommit
177
+ Committing to file:///tmp/test-svn/trunk ...
178
+ M configure.ac
179
+ Committed r84
180
+ M autogen.sh
181
+ r83 = 8aa54a74d452f82eee10076ab2584c1fc424853b (trunk)
182
+ M configure.ac
183
+ r84 = cdbac939211ccb18aa744e581e46563af5d962d0 (trunk)
184
+ W: d2f23b80f67aaaa1f6f5aaef48fce3263ac71a92 and refs/remotes/trunk differ, \
185
+ using rebase:
186
+ :100755 100755 efa5a59965fbbb5b2b0a12890f1b351bb5493c18 \
187
+ 015e4c98c482f0fa71e4d5434338014530b37fa6 M autogen.sh
188
+ First, rewinding head to replay your work on top of it...
189
+ Nothing to do.
190
+
191
+ 這一點需要牢記,因為它的結果是推送之後專案處於一個不完整存在於任何主機上的狀態。如果做出的修改無法相容但沒有產生衝突,則可能造成一些很難確診的難題。這和使用 Git 伺服器是不同的——在 Git 世界裡,發佈之前,你可以在用戶端系統裡完整的測試專案的狀態,而在 SVN 永遠都沒法確保提交前後專案的狀態完全一樣。
192
+
193
+ 即使還沒打算進行提交,你也應該用這個命令從 Subversion 伺服器拉取最新修改。你可以執行 `git svn fetch` 獲取最新的資料,不過 `git svn rebase` 才會在獲取之後在本地進行更新 。
194
+
195
+ $ git svn rebase
196
+ M generate_descriptor_proto.sh
197
+ r82 = bd16df9173e424c6f52c337ab6efa7f7643282f1 (trunk)
198
+ First, rewinding head to replay your work on top of it...
199
+ Fast-forwarded master to refs/remotes/trunk.
200
+
201
+ 不時地執行一下 `git svn rebase` 可以確保你的代碼沒有過時。不過,執行該命令時需要確保工作目錄的整潔。如果在本地做了修改,則必須在執行 `git svn rebase` 之前暫存工作、或暫時提交內容——否則,該命令會發現衍合的結果包含著衝突因而終止。
202
+
203
+ ### Git 分支問題 ###
204
+
205
+ 習慣了 Git 的工作流程以後,你可能會創建一些特性分支,完成相關的開發工作,然後合併他們。如果要用 git svn 向 Subversion 推送內容,那麼最好是每次用衍合來併入一個單一分支,而不是直接合併。使用衍合的原因是 Subversion 只有一個線性的歷史而不像 Git 那樣處理合併,所以 Git svn 在把快照轉換為 Subversion 的 commit 時只能包含第一個祖先。
206
+
207
+ 假設分支歷史如下:創建一個 `experiment` 分支,進行兩次提交,然後合併到 `master` 。在 `dcommit` 的時候會得到如下輸出:
208
+
209
+ $ git svn dcommit
210
+ Committing to file:///tmp/test-svn/trunk ...
211
+ M CHANGES.txt
212
+ Committed r85
213
+ M CHANGES.txt
214
+ r85 = 4bfebeec434d156c36f2bcd18f4e3d97dc3269a2 (trunk)
215
+ No changes between current HEAD and refs/remotes/trunk
216
+ Resetting to the latest refs/remotes/trunk
217
+ COPYING.txt: locally modified
218
+ INSTALL.txt: locally modified
219
+ M COPYING.txt
220
+ M INSTALL.txt
221
+ Committed r86
222
+ M INSTALL.txt
223
+ M COPYING.txt
224
+ r86 = 2647f6b86ccfcaad4ec58c520e369ec81f7c283c (trunk)
225
+ No changes between current HEAD and refs/remotes/trunk
226
+ Resetting to the latest refs/remotes/trunk
227
+
228
+ 在一個包含了合併歷史的分支上使用 `dcommit` 可以成功運行,不過在 Git 專案的歷史中,它沒有重寫你在 `experiment` 分支中的兩個 commit ——取而代之的是,這些改變出現在了 SVN 版本中同一個合併 commit 中。
229
+
230
+ 在別人 clone 該專案的時候,只能看到這個合併 commit 包含了所有發生過的修改;他們無法獲知修改的作者和時間等提交資訊。
231
+
232
+ ### Subversion 分支 ###
233
+
234
+ Subversion 的分支和 Git 中的不盡相同;避免過多的使用可能是最好方案。不過,用 git svn 創建和提交不同的 Subversion 分支仍是可行的。
235
+
236
+ #### 創建新的 SVN 分支 ####
237
+
238
+ 要在 Subversion 中建立一個新分支,可以執行 `git svn branch [分支名]`:
239
+
240
+ $ git svn branch opera
241
+ Copying file:///tmp/test-svn/trunk at r87 to file:///tmp/test-svn/branches/opera...
242
+ Found possible branch point: file:///tmp/test-svn/trunk => \
243
+ file:///tmp/test-svn/branches/opera, 87
244
+ Found branch parent: (opera) 1f6bfe471083cbca06ac8d4176f7ad4de0d62e5f
245
+ Following parent with do_switch
246
+ Successfully followed parent
247
+ r89 = 9b6fe0b90c5c9adf9165f700897518dbc54a7cbf (opera)
248
+
249
+ 這相當於在 Subversion 中的 `svn copy trunk branches/opera` 命令並且對 Subversion 伺服器進行了相關操作。值得提醒的是它沒有檢出(check out)並轉換到那個分支;如果現在進行提交,將提交到伺服器上的 `trunk`, 而非 `opera`。
250
+
251
+ ### 切換當前分支 ###
252
+
253
+ Git 通過搜尋提交歷史中 Subversion 分支的頭部(tip)來決定 dcommit 的目的地——而它應該只有一個,那就是當前分支歷史中最近一次包含 `git-svn-id` 的提交。
254
+
255
+ 如果需要同時在多個分支上提交,可以通過導入 Subversion 上某個其他分支的 commit 來建立以該分支為 `dcommit` 目的地的本地分支。比如你想擁有一個並行維護的 `opera` 分支,可以執行
256
+
257
+ $ git branch opera remotes/opera
258
+
259
+ 然後,如果要把 `opera` 分支併入 `trunk` (本地的 `master` 分支),可以使用普通的 `git merge`。不過最好提供一條描述提交的資訊(通過 `-m`),否則這次合併的記錄會是「Merge branch opera」,而不是任何有用的東西。
260
+
261
+ 記住,雖然使用了 `git merge` 來進行這次操作,並且合併過程可能比使用 Subversion 簡單一些(因為 Git 會自動找到適合的合併基礎),這並不是一次普通的 Git 合併提交。最終它將被推送回Subversion 伺服器上,而 Subversion 伺服器上無法處理包含多個祖先的 commit;因而在推送之後,它將變成一個包含了所有在其他分支上做出的改變的單一 commit。把一個分支合併到另一個分支以後,你沒法像在 Git 中那樣輕易的回到那個分支上繼續工作。提交時執行的 `dcommit` 命令擦掉了所有關於哪個分支被併入的資訊,因而以後的合併基礎計算將是不正確的—— dcommit 讓 `git merge` 的結果變得類似於 `git merge --squash`。不幸的是,我們沒有什麼好辦法來避免該情況—— Subversion 無法儲存這個資訊,所以在使用它作為伺服器的時候你將永遠為這個缺陷所困。為了不出現這種問題,在把本地分支(本例中的 `opera`)併入 trunk 以後應該立即將其刪除。
262
+
263
+ ### 對應 Subversion 的命令 ###
264
+
265
+ `git svn` 工具集合了若干個與 Subversion 類似的功能,對應的命令可以簡化向 Git 的轉化過程。下面這些命令能實現 Subversion 的這些功能。
266
+
267
+ #### SVN 風格的歷史紀錄 ####
268
+
269
+ 習慣了 Subversion 的人可能想以 SVN 的風格顯示歷史,運行 `git svn log` 可以讓提交歷史顯示為 SVN 格式:
270
+
271
+ $ git svn log
272
+ ------------------------------------------------------------------------
273
+ r87 | schacon | 2009-05-02 16:07:37 -0700 (Sat, 02 May 2009) | 2 lines
274
+
275
+ autogen change
276
+
277
+ ------------------------------------------------------------------------
278
+ r86 | schacon | 2009-05-02 16:00:21 -0700 (Sat, 02 May 2009) | 2 lines
279
+
280
+ Merge branch 'experiment'
281
+
282
+ ------------------------------------------------------------------------
283
+ r85 | schacon | 2009-05-02 16:00:09 -0700 (Sat, 02 May 2009) | 2 lines
284
+
285
+ updated the changelog
286
+
287
+ 關於 `git svn log` ,有兩點需要注意。首先,它可以離線工作,不像 `svn log 命令`,需要向 Subversion 伺服器索取資料。其次,它僅僅顯示已經提交到 Subversion 伺服器上的 commit。在本地尚未 dcommit 的 Git 資料不會出現在這裡;其他人向 Subversion 伺服器新提交的資料也不會顯示。等於說是顯示了最近已知 Subversion 伺服器上的狀態。
288
+
289
+ #### SVN Annotation ####
290
+
291
+ 類似 `git svn log` 命令模擬了 `svn log` 命令的離線操作,`svn annotate` 的等效命令是 `git svn blame [檔案名]`。其輸出如下:
292
+
293
+ $ git svn blame README.txt
294
+ 2 temporal Protocol Buffers - Google's data interchange format
295
+ 2 temporal Copyright 2008 Google Inc.
296
+ 2 temporal http://code.google.com/apis/protocolbuffers/
297
+ 2 temporal
298
+ 22 temporal C++ Installation - Unix
299
+ 22 temporal =======================
300
+ 2 temporal
301
+ 79 schacon Committing in git-svn.
302
+ 78 schacon
303
+ 2 temporal To build and install the C++ Protocol Buffer runtime and the Protocol
304
+ 2 temporal Buffer compiler (protoc) execute the following:
305
+ 2 temporal
306
+
307
+ 同樣,它不顯示本地的 Git 提交以及 Subversion 上後來更新的內容。
308
+
309
+ #### SVN 伺服器資訊 ####
310
+
311
+ 還可以使用 `git svn info` 來獲取與執行 `svn info` 類似的資訊:
312
+
313
+ $ git svn info
314
+ Path: .
315
+ URL: https://schacon-test.googlecode.com/svn/trunk
316
+ Repository Root: https://schacon-test.googlecode.com/svn
317
+ Repository UUID: 4c93b258-373f-11de-be05-5f7a86268029
318
+ Revision: 87
319
+ Node Kind: directory
320
+ Schedule: normal
321
+ Last Changed Author: schacon
322
+ Last Changed Rev: 87
323
+ Last Changed Date: 2009-05-02 16:07:37 -0700 (Sat, 02 May 2009)
324
+
325
+ 它與 blame 和 log 的相同點在於離線運行以及只更新到最後一次與 Subversion 伺服器通信的狀態。
326
+
327
+ #### 忽略 Subversion 所忽略的 ####
328
+
329
+ 假如 clone 了一個包含了 `svn:ignore` 屬性的 Subversion 倉庫,就有必要建立對應的 `.gitignore` 文件來防止意外提交一些不應該提交的文件。`git svn` 有兩個有助於改善該問題的命令。第一個是 `git svn create-ignore`,它自動建立對應的 `.gitignore` 檔,以便下次提交的時候可以包含它。
330
+
331
+ 第二個命令是 `git svn show-ignore`,它把需要放進 `.gitignore` 檔中的內容列印到標準輸出,方便我們把輸出重定向到專案的黑名單檔(exclude file):
332
+
333
+ $ git svn show-ignore > .git/info/exclude
334
+
335
+ 這樣一來,避免了 `.gitignore` 對專案的干擾。如果你是一個 Subversion 團隊裡唯一的 Git 用戶,而其他隊友不喜歡專案裏出現 `.gitignore` 檔案,該方法是你的不二之選。
336
+
337
+ ### Git-Svn 總結 ###
338
+
339
+ `git svn` 工具集在當前不得不使用 Subversion 伺服器或者開發環境要求使用 Subversion 伺服器的時候格外有用。不妨把它看成一個跛腳的 Git,然而,你還是有可能在轉換過程中碰到一些困惑你和合作者們的謎題。為了避免麻煩,試著遵守如下守則:
340
+
341
+ * 保持一個不包含由 `git merge` 產生的 commit 的線性提交歷史。將在主線分支外進行的開發通通衍合回主線;避免直接合併。
342
+ * 不要單獨建立和使用一個 Git 服務來搞合作。可以為了加速新開發者的 clone 進程建立一個,但是不要向它提供任何不包含 `git-svn-id` 條目的內容。甚至可以添加一個 `pre-receive` 掛鉤,在每一個提交資訊中檢查 `git-svn-id`,並拒絕提交那些不包含它的 commit。
343
+
344
+ 如果遵循這些守則,在 Subversion 上工作還可以接受。然而,如果能遷徙到真正的 Git 伺服器,則能為團隊帶來更多好處。
345
+
346
+ ## 遷移到 Git ##
347
+
348
+ 如果在其他版本控制系統(VCS)中保存了某專案的代碼而後決定轉而使用 Git,那麼該專案必須經歷某種形式的遷移。本節將介紹 Git 中包含的一些針對常見系統的導入腳本(importer),並將展示編寫自訂的導入腳本的方法。
349
+
350
+ ### 導入 ###
351
+
352
+ 你將學習到如何從專業重量級的版本控制系統(SCM)中匯入資料—— Subversion 和 Perforce —— 因為據我所知這二者的用戶是(向 Git)轉換的主要群體,而且 Git 為此二者附帶了高品質的轉換工具。
353
+
354
+ ### Subversion ###
355
+
356
+ 讀過前一節有關 `git svn` 的內容以後,你應該能輕而易舉的根據其中的指導來 `git svn clone` 一個倉庫了;然後,停止 Subversion 的使用,向一個新 Git server 推送,並開始使用它。想保留歷史記錄,所花的時間應該不過就是從 Subversion 伺服器拉取資料的時間(可能要等上好一會就是了)。
357
+
358
+ 然而,這樣的匯入並不完美;而且還要花那麼多時間,不如乾脆一次把它做對!首當其衝的任務是作者資訊。在 Subversion,每個提交者都在主機上有一個用戶名,記錄在提交資訊中。上節例子中多處顯示了 schacon ,比如 `blame` 的輸出以及 `git svn log`。如果想讓這條資訊更好的映射到 Git 作者資料裡,則需要從 Subversion 用戶名到 Git 作者的一個映射關係。建立一個叫做 `user.txt` 的檔,用如下格式表示映射關係:
359
+
360
+ schacon = Scott Chacon <schacon@geemail.com>
361
+ selse = Someo Nelse <selse@geemail.com>
362
+
363
+ 通過以下命令可以獲得 SVN 作者的列表:
364
+
365
+ $ svn log ^/ --xml | grep -P "^<author" | sort -u | \
366
+ perl -pe 's/<author>(.*?)<\/author>/$1 = /' > users.txt
367
+
368
+ 它將輸出 XML 格式的日誌——你可以找到作者,建立一個單獨的列表,然後從 XML 中抽取出需要的資訊。(顯而易見,本方法要求主機上安裝了`grep`,`sort` 和 `perl`.)然後把輸出重定向到 user.txt 檔,然後就可以在每一項的後面添加相應的 Git 使用者資料。
369
+
370
+ 為 `git svn` 提供該檔可以讓它更精確的映射作者資料。你還可以在 `clone` 或者 `init` 後面添加 `--no-metadata` 來阻止 `git svn` 包含那些 Subversion 的附加資訊。這樣 `import` 命令就變成了:
371
+
372
+ $ git svn clone http://my-project.googlecode.com/svn/ \
373
+ --authors-file=users.txt --no-metadata -s my_project
374
+
375
+ 現在 `my_project` 目錄下導入的 Subversion 應該比原來整潔多了。原來的 commit 看上去是這樣:
376
+
377
+ commit 37efa680e8473b615de980fa935944215428a35a
378
+ Author: schacon <schacon@4c93b258-373f-11de-be05-5f7a86268029>
379
+ Date: Sun May 3 00:12:22 2009 +0000
380
+
381
+ fixed install - go to trunk
382
+
383
+ git-svn-id: https://my-project.googlecode.com/svn/trunk@94 4c93b258-373f-11de-
384
+ be05-5f7a86268029
385
+ 現在是這樣:
386
+
387
+ commit 03a8785f44c8ea5cdb0e8834b7c8e6c469be2ff2
388
+ Author: Scott Chacon <schacon@geemail.com>
389
+ Date: Sun May 3 00:12:22 2009 +0000
390
+
391
+ fixed install - go to trunk
392
+
393
+ 不僅作者一項乾淨了不少,`git-svn-id` 也就此消失了。
394
+
395
+ 你還需要一點 post-import(導入後) 清理工作。最起碼的,應該清理一下 `git svn` 創建的那些怪異的索引結構。首先要移動標籤,把它們從奇怪的遠端分支變成實際的標籤,然後把剩下的分支移動到本地。
396
+
397
+ 要把標籤變成合適的 Git 標籤,執行
398
+
399
+ $ git for-each-ref refs/remotes/tags | cut -d / -f 4- | grep -v @ | while read tagname; do git tag "$tagname" "tags/$tagname"; git branch -r -d "tags/$tagname"; done
400
+
401
+ 該命令將原本以 `tag/` 開頭的遠端分支的索引變成真正的 (lightweight) 標籤。
402
+
403
+ 接下來,把 `refs/remotes` 下面剩下的索引(reference)變成本地分支:
404
+
405
+ $ git for-each-ref refs/remotes | cut -d / -f 3- | grep -v @ | while read branchname; do git branch "$branchname" "refs/remotes/$branchname"; git branch -r -d "$branchname"; done
406
+
407
+ 現在所有的舊分支都變成真正的 Git 分支,所有的舊標籤也變成真正的 Git 標籤。最後一項工作就是把新建的 Git 伺服器添加為遠端伺服器並且向它推送。為了讓所有的分支和標籤都得到上傳,我們使用這條命令:
408
+
409
+ $ git remote add origin git@my-git-server:myrepository.git
410
+
411
+ Because you want all your branches and tags to go up, you can now run this:
412
+
413
+ $ git push origin --all
414
+ $ git push origin --tags
415
+
416
+ 所有的分支和標籤現在都應該整齊乾淨的躺在新的 Git 伺服器裡了。
417
+
418
+ ### Perforce ###
419
+
420
+ 你將瞭解到的下一個被導入的系統是 Perforce. Git 發行的時候同時也附帶了一個 Perforce 導入腳本,不過它是包含在源碼的 `contrib` 部分——而不像 `git svn` 那樣預設就可以使用。執行它之前必須獲取 Git 的源碼,可以在 git.kernel.org 下載:
421
+
422
+ $ git clone git://git.kernel.org/pub/scm/git/git.git
423
+ $ cd git/contrib/fast-import
424
+
425
+ 在這個 `fast-import` 目錄下,應該有一個叫做 `git-p4` 的 Python 可執行腳本。主機上必須裝有 Python 和 `p4` 工具該導入才能正常進行。例如,你要從 Perforce 公共代碼倉庫(譯注: Perforce Public Depot,Perforce 官方提供的代碼寄存服務)導入 Jam 專案。為了設定用戶端,我們要把 P4PORT 環境變數 export 到 Perforce 倉庫:
426
+
427
+ $ export P4PORT=public.perforce.com:1666
428
+
429
+ 執行 `git-p4 clone` 命令將從 Perforce 伺服器導入 Jam 專案,我們需要給出倉庫和專案的路徑以及導入的目標路徑:
430
+
431
+ $ git-p4 clone //public/jam/src@all /opt/p4import
432
+ Importing from //public/jam/src@all into /opt/p4import
433
+ Reinitialized existing Git repository in /opt/p4import/.git/
434
+ Import destination: refs/remotes/p4/master
435
+ Importing revision 4409 (100%)
436
+
437
+ 現在去 `/opt/p4import` 目錄執行一下 `git log` ,就能看到導入的成果:
438
+
439
+ $ git log -2
440
+ commit 1fd4ec126171790efd2db83548b85b1bbbc07dc2
441
+ Author: Perforce staff <support@perforce.com>
442
+ Date: Thu Aug 19 10:18:45 2004 -0800
443
+
444
+ Drop 'rc3' moniker of jam-2.5. Folded rc2 and rc3 RELNOTES into
445
+ the main part of the document. Built new tar/zip balls.
446
+
447
+ Only 16 months later.
448
+
449
+ [git-p4: depot-paths = "//public/jam/src/": change = 4409]
450
+
451
+ commit ca8870db541a23ed867f38847eda65bf4363371d
452
+ Author: Richard Geiger <rmg@perforce.com>
453
+ Date: Tue Apr 22 20:51:34 2003 -0800
454
+
455
+ Update derived jamgram.c
456
+
457
+ [git-p4: depot-paths = "//public/jam/src/": change = 3108]
458
+
459
+ 每一個 commit 裡都有一個 `git-p4` 識別字。這個識別字可以保留,以防以後需要引用 Perforce 的修改版本號。然而,如果想刪除這些識別字,現在正是時候——開始在新倉庫上工作之前。可以通過 `git filter-branch` 來批量刪除這些識別字:
460
+
461
+ $ git filter-branch --msg-filter '
462
+ sed -e "/^\[git-p4:/d"
463
+ '
464
+ Rewrite 1fd4ec126171790efd2db83548b85b1bbbc07dc2 (123/123)
465
+ Ref 'refs/heads/master' was rewritten
466
+
467
+ 現在執行一下 `git log`,你會發現這些 commit 的 SHA-1 校驗值都發生了改變,而那些 `git-p4` 字串則從提交資訊裡消失了:
468
+
469
+ $ git log -2
470
+ commit 10a16d60cffca14d454a15c6164378f4082bc5b0
471
+ Author: Perforce staff <support@perforce.com>
472
+ Date: Thu Aug 19 10:18:45 2004 -0800
473
+
474
+ Drop 'rc3' moniker of jam-2.5. Folded rc2 and rc3 RELNOTES into
475
+ the main part of the document. Built new tar/zip balls.
476
+
477
+ Only 16 months later.
478
+
479
+ commit 2b6c6db311dd76c34c66ec1c40a49405e6b527b2
480
+ Author: Richard Geiger <rmg@perforce.com>
481
+ Date: Tue Apr 22 20:51:34 2003 -0800
482
+
483
+ Update derived jamgram.c
484
+
485
+ 至此導入已經完成,可以開始向新的 Git 伺服器推送了。
486
+
487
+ ### 自定導入腳本 ###
488
+
489
+ 如果你的系統不是 Subversion 或 Perforce 之一,先上網找一下有沒有與之對應的導入腳本——導入 CVS,Clear Case,Visual Source Safe,甚至存檔目錄的導入腳本已經存在。假如這些工具都不適用,或者使用的工具很少見,抑或你需要導入過程具有更多可制定性,則應該使用 `git fast-import`。該命令從標準輸入讀取簡單的指令來寫入具體的 Git 資料。這樣創建 Git 物件比執行純 Git 命令或者手動寫物件要簡單的多(更多相關內容見第九章)。通過它,你可以編寫一個導入腳本來從導入來源讀取必要的資訊,同時在標準輸出直接輸出相關指令(instructions)。你可以執行該腳本並把它的輸出管道連接(pipe)到 `git fast-import`。
490
+
491
+ 下面演示一下如何編寫一個簡單的導入腳本。假設你在進行一項工作,並且按時通過把工作目錄複寫為以時間戳記 back_YY_MM_DD 命名的目錄來進行備份,現在你需要把它們導入 Git 。目錄結構如下:
492
+
493
+ $ ls /opt/import_from
494
+ back_2009_01_02
495
+ back_2009_01_04
496
+ back_2009_01_14
497
+ back_2009_02_03
498
+ current
499
+
500
+ 為了導入到一個 Git 目錄,我們首先回顧一下 Git 儲存資料的方式。你可能還記得,Git 本質上是一個 commit 物件的鏈表,每一個物件指向一個內容的快照。而這裡需要做的工作就是告訴 `fast-import` 內容快照的位置,什麼樣的 commit 資料指向它們,以及它們的順序。我們採取一次處理一個快照的策略,為每一個內容目錄建立對應的 commit ,每一個 commit 與前一個 commit 建立連結。
501
+
502
+ 正如在第七章 “Git 執行策略一例” 一節中一樣,我們將使用 Ruby 來編寫這個腳本,因為它是我日常使用的語言而且閱讀起來簡單一些。你可以用任何其他熟悉的語言來重寫這個例子——它僅需要把必要的資訊列印到標準輸出而已。同時,如果你在使用 Windows,這意味著你要特別留意不要在換行的時候引入回車符(譯注:carriage returns,Windows 換行時加入的符號,通常說的 \r )—— Git 的 fast-import 對僅使用分行符號(LF)而非 Windows 的回車符(CRLF)要求非常嚴格。
503
+
504
+ 首先,進入目標目錄並且找到所有子目錄,每一個子目錄將作為一個快照被導入為一個 commit。我們將依次進入每一個子目錄並列印所需的命令來匯出它們。腳本的主迴圈大致是這樣:
505
+
506
+ last_mark = nil
507
+
508
+ # loop through the directories
509
+ Dir.chdir(ARGV[0]) do
510
+ Dir.glob("*").each do |dir|
511
+ next if File.file?(dir)
512
+
513
+ # move into the target directory
514
+ Dir.chdir(dir) do
515
+ last_mark = print_export(dir, last_mark)
516
+ end
517
+ end
518
+ end
519
+
520
+ 我們在每一個目錄裡執行 `print_export`,它會取出上一個快照的索引和標記並返回本次快照的索引和標記;由此我們就可以正確的把二者連接起來。”標記(mark)” 是 `fast-import` 中對 commit 識別字的叫法;在創建 commit 的同時,我們逐一賦予一個標記以便以後在把它連接到其他 commit 時使用。因此,在 `print_export` 方法中要做的第一件事就是根據目錄名產生一個標記:
521
+
522
+ mark = convert_dir_to_mark(dir)
523
+
524
+ 實現該函數的方法是建立一個目錄的陣列序列並使用陣列的索引值作為標記,因為標記必須是一個整數。這個方法大致是這樣的:
525
+
526
+ $marks = []
527
+ def convert_dir_to_mark(dir)
528
+ if !$marks.include?(dir)
529
+ $marks << dir
530
+ end
531
+ ($marks.index(dir) + 1).to_s
532
+ end
533
+
534
+ 有了整數來代表每個 commit,我們現在需要提交附加資訊中的日期。由於日期是用目錄名表示的,我們就從中解析出來。`print_export` 文件的下一行將是:
535
+
536
+ date = convert_dir_to_date(dir)
537
+
538
+ 而 `convert_dir_to_date` 則定義為
539
+
540
+ def convert_dir_to_date(dir)
541
+ if dir == 'current'
542
+ return Time.now().to_i
543
+ else
544
+ dir = dir.gsub('back_', '')
545
+ (year, month, day) = dir.split('_')
546
+ return Time.local(year, month, day).to_i
547
+ end
548
+ end
549
+
550
+ 它為每個目錄回傳一個 integer。提交附加資訊裡最後一項所需的是提交者資料,我們在一個全域變數中直接定義之:
551
+
552
+ $author = 'Scott Chacon <schacon@example.com>'
553
+
554
+ 我們差不多可以開始為導入腳本輸出提交資料了。第一項資訊指明我們定義的是一個 commit 物件以及它所在的分支,隨後是我們產生的標記、提交者資訊以及提交備註,然後是前一個 commit 的索引,如果有的話。程式碼大致像這樣:
555
+
556
+ # print the import information
557
+ puts 'commit refs/heads/master'
558
+ puts 'mark :' + mark
559
+ puts "committer #{$author} #{date} -0700"
560
+ export_data('imported from ' + dir)
561
+ puts 'from :' + last_mark if last_mark
562
+
563
+ 為了簡化,時區寫死(hardcode)為(-0700)。如果是從其他版本控制系統導入,則必須以變數的形式指明時區。
564
+ 提交訊息必須以特定格式給出:
565
+
566
+ data (size)\n(contents)
567
+
568
+ 該格式包含了「data」這個字、所讀取資料的大小、一個分行符號,最後是資料本身。由於隨後指明檔案內容的時候要用到相同的格式,我們寫一個輔助方法,`export_data`:
569
+
570
+ def export_data(string)
571
+ print "data #{string.size}\n#{string}"
572
+ end
573
+
574
+ 唯一剩下的就是每一個快照的內容了。這簡單的很,因為它們分別處於一個目錄——你可以輸出 `deleeall` 命令,隨後是目錄中每個檔的內容。Git 會正確的記錄每一個快照:
575
+
576
+ puts 'deleteall'
577
+ Dir.glob("**/*").each do |file|
578
+ next if !File.file?(file)
579
+ inline_data(file)
580
+ end
581
+
582
+ 注意:由於很多系統把每次修訂看作一個 commit 到另一個 commit 的變化量,fast-import 也可以依據每次提交獲取一個命令來指出哪些檔被添加,刪除或者修改過,以及修改的內容。我們將需要計算快照之間的差別並且僅僅給出這項資料,不過該做法要複雜很多——還不如直接把所有資料丟給 Git 讓它自己搞清楚。假如前面這個方法更適用於你的資料,參考 `fast-import` 的 man 説明頁面來瞭解如何以這種方式提供資料。
583
+
584
+ 列舉新檔內容或者指明帶有新內容的已修改檔的格式如下:
585
+
586
+ M 644 inline path/to/file
587
+ data (size)
588
+ (file contents)
589
+
590
+ 這裡,644 是許可權模式(如果有執行檔,則需要偵測之並設定為 755),而 inline 說明我們在本行結束之後立即列出檔的內容。我們的 `inline_data` 方法大致是:
591
+
592
+ def inline_data(file, code = 'M', mode = '644')
593
+ content = File.read(file)
594
+ puts "#{code} #{mode} inline #{file}"
595
+ export_data(content)
596
+ end
597
+
598
+ 我們再次使用了前面定義過的 `export_data`,因為這裡和指明提交注釋的格式如出一轍。
599
+
600
+ 最後一項工作是回傳當前的標記以便下次迴圈的使用。
601
+
602
+ return mark
603
+
604
+ 注意:如果你是在 Windows 上執行,一定記得添加一項額外的步驟。前面提過,Windows 使用 CRLF 作為換行字元而 Git fast-import 只接受 LF。為了避開這個問題來滿足 git fast-import,你需要讓 ruby 用 LF 取代 CRLF:
605
+
606
+ $stdout.binmode
607
+
608
+ 搞定了。現在執行該腳本,你將得到如下內容:
609
+
610
+ $ ruby import.rb /opt/import_from
611
+ commit refs/heads/master
612
+ mark :1
613
+ committer Scott Chacon <schacon@geemail.com> 1230883200 -0700
614
+ data 29
615
+ imported from back_2009_01_02deleteall
616
+ M 644 inline file.rb
617
+ data 12
618
+ version two
619
+ commit refs/heads/master
620
+ mark :2
621
+ committer Scott Chacon <schacon@geemail.com> 1231056000 -0700
622
+ data 29
623
+ imported from back_2009_01_04from :1
624
+ deleteall
625
+ M 644 inline file.rb
626
+ data 14
627
+ version three
628
+ M 644 inline new.rb
629
+ data 16
630
+ new version one
631
+ (...)
632
+
633
+ 要執行導入腳本,在需要導入的目錄把該內容用管道定向(pipe)到 `git fast-import`。你可以建立一個空目錄然後執行 `git init` 作為起點,然後執行該腳本:
634
+
635
+ $ git init
636
+ Initialized empty Git repository in /opt/import_to/.git/
637
+ $ ruby import.rb /opt/import_from | git fast-import
638
+ git-fast-import statistics:
639
+ ---------------------------------------------------------------------
640
+ Alloc'd objects: 5000
641
+ Total objects: 18 ( 1 duplicates )
642
+ blobs : 7 ( 1 duplicates 0 deltas)
643
+ trees : 6 ( 0 duplicates 1 deltas)
644
+ commits: 5 ( 0 duplicates 0 deltas)
645
+ tags : 0 ( 0 duplicates 0 deltas)
646
+ Total branches: 1 ( 1 loads )
647
+ marks: 1024 ( 5 unique )
648
+ atoms: 3
649
+ Memory total: 2255 KiB
650
+ pools: 2098 KiB
651
+ objects: 156 KiB
652
+ ---------------------------------------------------------------------
653
+ pack_report: getpagesize() = 4096
654
+ pack_report: core.packedGitWindowSize = 33554432
655
+ pack_report: core.packedGitLimit = 268435456
656
+ pack_report: pack_used_ctr = 9
657
+ pack_report: pack_mmap_calls = 5
658
+ pack_report: pack_open_windows = 1 / 1
659
+ pack_report: pack_mapped = 1356 / 1356
660
+ ---------------------------------------------------------------------
661
+
662
+ 你會發現,在它成功執行完畢以後,會給出一堆有關已完成工作的資料。上例在一個分支導入了5次提交資料,包含了18個物件。現在可以執行 `git log` 來檢視新的歷史:
663
+
664
+ $ git log -2
665
+ commit 10bfe7d22ce15ee25b60a824c8982157ca593d41
666
+ Author: Scott Chacon <schacon@example.com>
667
+ Date: Sun May 3 12:57:39 2009 -0700
668
+
669
+ imported from current
670
+
671
+ commit 7e519590de754d079dd73b44d695a42c9d2df452
672
+ Author: Scott Chacon <schacon@example.com>
673
+ Date: Tue Feb 3 01:00:00 2009 -0700
674
+
675
+ imported from back_2009_02_03
676
+
677
+ 就這樣——一個乾淨整潔的 Git 倉庫。需要注意的是此時沒有任何內容被檢出(checked out)——剛開始目前的目錄裡沒有任何檔。要獲取它們,你得轉到 `master` 分支的所在:
678
+
679
+ $ ls
680
+ $ git reset --hard master
681
+ HEAD is now at 10bfe7d imported from current
682
+ $ ls
683
+ file.rb lib
684
+
685
+ `fast-import` 還可以做更多——處理不同的檔案模式、二進位檔案、多重分支與合併、標籤、進展標識(progress indicators)等等。一些更加複雜的實例可以在 Git 源碼的 `contib/fast-import` 目錄裡找到;較佳的其中之一是前面提過的 `git-p4` 腳本。
686
+
687
+ ## 總結 ##
688
+
689
+ 現在的你應該掌握了在 Subversion 上使用 Git,以及把幾乎任何現存倉庫在不遺漏資料的情況下導入為 Git 倉庫。下一章將介紹 Git 內部的原始資料格式,從而使你能親手鍛造其中的每一個位元組,如果需要的話。