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,262 @@
1
+ # Empezando #
2
+
3
+ Este capítulo tratará sobre cómo empezar con Git. Partiremos explicando algunos conceptos relativos a las herramientas de control de versiones, luego pasaremos a ver cómo tener Git funcionando en tu sistema, y finalmente cómo configurarlo para empezar a trabajar con él. Al final de este capítulo deberías entender por qué existe Git, por qué usarlo, y tendrías que tener todo preparado para comenzar.
4
+
5
+ ## Acerca del control de versiones ##
6
+
7
+ ¿Qué es el control de versiones, y por qué debería importarte? El control de versiones es un sistema que registra los cambios realizados sobre un archivo o conjunto de archivos a lo largo del tiempo, de modo que puedas recuperar versiones específicas más adelante. A pesar de que los ejemplos de este libro muestran código fuente como archivos bajo control de versiones, en realidad cualquier tipo de archivo que encuentres en un ordenador puede ponerse bajo control de versiones.
8
+
9
+ Si eres diseñador gráfico o web, y quieres mantener cada versión de una imagen o diseño (algo que sin duda quieres), un sistema de control de versiones (Version Control System o VCS en inglés) es una elección muy sabia. Te permite revertir archivos a un estado anterior, revertir el proyecto entero a un estado anterior, comparar cambios a lo largo del tiempo, ver quién modificó por última vez algo que puede estar causando un problema, quién introdujo un error y cuándo, y mucho más. Usar un VCS también significa generalmente que si fastidias o pierdes archivos, puedes recuperarlos fácilmente. Además, obtienes todos estos beneficios a un coste muy bajo.
10
+
11
+ ### Sistemas de control de versiones locales ###
12
+
13
+ Un método de control de versiones usado por mucha gente es copiar los archivos a otro directorio (quizás indicando la fecha y hora en que lo hicieron, si son avispados). Este enfoque es muy común porque es muy simple, pero también tremendamente propenso a errores. Es fácil olvidar en qué directorio te encuentras, y guardar accidentalmente en el archivo equivocado o sobrescribir archivos que no querías.
14
+
15
+ Para hacer frente a este problema, los programadores desarrollaron hace tiempo VCSs locales que contenían una simple base de datos en la que se llevaba registro de todos los cambios realizados sobre los archivos (véase Figura 1-1).
16
+
17
+ Insert 18333fig0101.png
18
+ Figura 1-1. Diagrama de control de versiones local.
19
+
20
+ Una de las herramientas de control de versiones más popular fue un sistema llamado rcs, que todavía podemos encontrar en muchos de los ordenadores actuales. Hasta el famoso sistema operativo Mac OS X incluye el comando rcs cuando instalas las herramientas de desarrollo. Esta herramienta funciona básicamente guardando conjuntos de parches (es decir, las diferencias entre archivos) de una versión a otra en un formato especial en disco; puede entonces recrear cómo era un archivo en cualquier momento sumando los distintos parches.
21
+
22
+ ### Sistemas de control de versiones centralizados ###
23
+
24
+ El siguiente gran problema que se encuentra la gente es que necesitan colaborar con desarrolladores en otros sistemas. Para solventar este problema, se desarrollaron los sistemas de control de versiones centralizados (Centralized Version Control Systems o CVCSs en inglés). Estos sistemas, como CVS, Subversion, y Perforce, tienen un único servidor que contiene todos los archivos versionados, y varios clientes que descargan los archivos desde ese lugar central. Durante muchos años éste ha sido el estándar para el control de versiones (véase Figura 1-2).
25
+
26
+ Insert 18333fig0102.png
27
+ Figura 1-2. Diagrama de control de versiones centralizado.
28
+
29
+ Esta configuración ofrece muchas ventajas, especialmente frente a VCSs locales. Por ejemplo, todo el mundo puede saber (hasta cierto punto) en qué están trabajando los otros colaboradores del proyecto. Los administradores tienen control detallado de qué puede hacer cada uno; y es mucho más fácil administrar un CVCS que tener que lidiar con bases de datos locales en cada cliente.
30
+
31
+ Sin embargo, esta configuración también tiene serias desventajas. La más obvia es el punto único de fallo que representa el servidor centralizado. Si ese servidor se cae durante una hora, entonces durante esa hora nadie puede colaborar o guardar cambios versionados de aquello en que están trabajando. Si el disco duro en el que se encuentra la base de datos central se corrompe, y no se han llevado copias de seguridad adecuadamente, pierdes absolutamente todo —toda la historia del proyecto salvo aquellas instantáneas que la gente pueda tener en sus máquinas locales. Los VCSs locales sufren de este mismo problema— cuando tienes toda la historia del proyecto en un único lugar, te arriesgas a perderlo todo.
32
+
33
+ ### Sistemas de control de versiones distribuidos ###
34
+
35
+ Es aquí donde entran los sistemas de control de versiones distribuidos (Distributed Version Control Systems o DVCSs en inglés). En un DVCS (como Git, Mercurial, Bazaar o Darcs), los clientes no sólo descargan la última instantánea de los archivos: replican completamente el repositorio. Así, si un servidor muere, y estos sistemas estaban colaborando a través de él, cualquiera de los repositorios de los clientes puede copiarse en el servidor para restaurarlo. Cada vez que se descarga una instantánea, en realidad se hace una copia de seguridad completa de todos los datos (véase Figura 1-3).
36
+
37
+ Insert 18333fig0103.png
38
+ Figura 1-3. Diagrama de control de versiones distribuido.
39
+
40
+ Es más, muchos de estos sistemas se las arreglan bastante bien teniendo varios repositorios con los que trabajar, por lo que puedes colaborar con distintos grupos de gente simultáneamente dentro del mismo proyecto. Esto te permite establecer varios flujos de trabajo que no son posibles en sistemas centralizados, como pueden ser los modelos jerárquicos.
41
+
42
+ ## Una breve historia de Git ##
43
+
44
+ Como muchas de las grandes cosas en esta vida, Git comenzó con un poco de destrucción creativa y encendida polémica. El núcleo de Linux es un proyecto de software de código abierto con un alcance bastante grande. Durante la mayor parte del mantenimiento del núcleo de Linux (1991-2002), los cambios en el software se pasaron en forma de parches y archivos. En 2002, el proyecto del núcleo de Linux empezó a usar un DVCS propietario llamado BitKeeper.
45
+
46
+ En 2005, la relación entre la comunidad que desarrollaba el núcleo de Linux y la compañía que desarrollaba BitKeeper se vino abajo, y la herramienta dejó de ser ofrecida gratuitamente. Esto impulsó a la comunidad de desarrollo de Linux (y en particular a Linus Torvalds, el creador de Linux) a desarrollar su propia herramienta basada en algunas de las lecciones que aprendieron durante el uso de BitKeeper. Algunos de los objetivos del nuevo sistema fueron los siguientes:
47
+
48
+ * Velocidad
49
+ * Diseño sencillo
50
+ * Fuerte apoyo al desarrollo no lineal (miles de ramas paralelas)
51
+ * Completamente distribuido
52
+ * Capaz de manejar grandes proyectos (como el núcleo de Linux) de manera eficiente (velocidad y tamaño de los datos)
53
+
54
+ Desde su nacimiento en 2005, Git ha evolucionado y madurado para ser fácil de usar y aún conservar estas cualidades iniciales. Es tremendamente rápido, muy eficiente con grandes proyectos, y tiene un increíble sistema de ramificación (branching) para desarrollo no lineal (véase el Capítulo 3).
55
+
56
+ ## Fundamentos de Git ##
57
+
58
+ Entonces, ¿qué es Git en pocas palabras? Es muy importante asimilar esta sección, porque si entiendes lo que es Git y los fundamentos de cómo funciona, probablemente te sea mucho más fácil usar Git de manera eficaz. A medida que aprendas Git, intenta olvidar todo lo que puedas saber sobre otros VCSs, como Subversion y Perforce; hacerlo te ayudará a evitar confusiones sutiles a la hora de utilizar la herramienta. Git almacena y modela la información de forma muy diferente a esos otros sistemas, a pesar de que su interfaz sea bastante similar; comprender esas diferencias evitará que te confundas a la hora de usarlo.
59
+
60
+ ### Instantáneas, no diferencias ###
61
+
62
+ La principal diferencia entre Git y cualquier otro VCS (Subversion y compañía incluidos) es cómo Git modela sus datos. Conceptualmente, la mayoría de los demás sistemas almacenan la información como una lista de cambios en los archivos. Estos sistemas (CVS, Subversion, Perforce, Bazaar, etc.) modelan la información que almacenan como un conjunto de archivos y las modificaciones hechas sobre cada uno de ellos a lo largo del tiempo, como ilustra la Figura 1-4.
63
+
64
+ Insert 18333fig0104.png
65
+ Figura 1-4. Otros sistemas tienden a almacenar los datos como cambios de cada archivo respecto a una versión base.
66
+
67
+ Git no modela ni almacena sus datos de este modo. En cambio, Git modela sus datos más como un conjunto de instantáneas de un mini sistema de archivos. Cada vez que confirmas un cambio, o guardas el estado de tu proyecto en Git, él básicamente hace una foto del aspecto de todos tus archivos en ese momento, y guarda una referencia a esa instantánea. Para ser eficiente, si los archivos no se han modificado, Git no almacena el archivo de nuevo, sólo un enlace al archivo anterior idéntico que ya tiene almacenado. Git modela sus datos más como en la Figura 1-5.
68
+
69
+ Insert 18333fig0105.png
70
+ Figura 1-5. Git almacena la información como instantáneas del proyecto a lo largo del tiempo.
71
+
72
+ Esta es una distinción importante entre Git y prácticamente todos los demás VCSs. Hace que Git reconsidere casi todos los aspectos del control de versiones que muchos de los demás sistemas copiaron de la generación anterior. Esto hace que Git se parezca más a un mini sistema de archivos con algunas herramientas tremendamente potentes construidas sobre él, que a un VCS. Exploraremos algunos de los beneficios que obtienes al modelar tus datos de esta manera cuando veamos ramificaciones (branching) en Git en el Capítulo 3.
73
+
74
+ ### Casi cualquier operación es local ###
75
+
76
+ La mayoría de las operaciones en Git sólo necesitan archivos y recursos locales para operar. Por lo general no se necesita información de ningún otro ordenador de tu red. Si estás acostumbrado a un CVCS donde la mayoría de las operaciones tienen esa sobrecarga del retardo de la red, este aspecto de Git te va a hacer pensar que los dioses de la velocidad han bendecido Git con poderes sobrenaturales. Como tienes toda la historia del proyecto ahí mismo, en tu disco local, la mayoría de las operaciones parecen prácticamente inmediatas.
77
+
78
+ Por ejemplo, para navegar por la historia del proyecto, Git no necesita salir al servidor para obtener la historia y mostrártela, simplemente la lee directamente de tu base de datos local. Esto significa que ves la historia del proyecto casi al instante. Si quieres ver los cambios introducidos en un archivo entre la versión actual y la de hace un mes, Git puede buscar el archivo hace un mes y hacer un cálculo de diferencias localmente, en lugar de tener que pedirle a un servidor remoto que lo haga, u obtener una versión antigua desde la red y hacerlo de manera local.
79
+
80
+ Esto también significa que hay muy poco que no puedas hacer si estás desconectado o sin VPN. Si te subes a un avión o a un tren y quieres trabajar un poco, puedes confirmar tus cambios felizmente hasta que consigas una conexión de red para subirlos. Si te vas a casa y no consigues que tu cliente VPN funcione correctamente, puedes seguir trabajando. En muchos otros sistemas, esto es imposible o muy doloroso. En Perforce, por ejemplo, no puedes hacer mucho cuando no estás conectado al servidor; y en Subversion y CVS, puedes editar archivos, pero no puedes confirmar los cambios a tu base de datos (porque tu base de datos no tiene conexión). Esto puede no parecer gran cosa, pero te sorprendería la diferencia que puede suponer.
81
+
82
+ ### Git tiene integridad ###
83
+
84
+ Todo en Git es verificado mediante una suma de comprobación (checksum en inglés) antes de ser almacenado, y es identificado a partir de ese momento mediante dicha suma. Esto significa que es imposible cambiar los contenidos de cualquier archivo o directorio sin que Git lo sepa. Esta funcionalidad está integrada en Git al más bajo nivel y es parte integral de su filosofía. No puedes perder información durante su transmisión o sufrir corrupción de archivos sin que Git lo detecte.
85
+
86
+ El mecanismo que usa Git para generar esta suma de comprobación se conoce como hash SHA-1. Se trata de una cadena de 40 caracteres hexadecimales (0-9 y a-f), y se calcula en base a los contenidos del archivo o estructura de directorios. Un hash SHA-1 tiene esta pinta:
87
+
88
+ 24b9da6552252987aa493b52f8696cd6d3b00373
89
+
90
+ Verás estos valores hash por todos lados en Git, ya que los usa con mucha frecuencia. De hecho, Git guarda todo no por nombre de archivo, sino por el valor hash de sus contenidos.
91
+
92
+ ### Git generalmente sólo añade información ###
93
+
94
+ Cuando realizas acciones en Git, casi todas ellas sólo añaden información a la base de datos de Git. Es muy difícil conseguir que el sistema haga algo que no se pueda deshacer, o que de algún modo borre información. Como en cualquier VCS, puedes perder o estropear cambios que no has confirmado todavía; pero después de confirmar una instantánea en Git, es muy difícil de perder, especialmente si envías (push) tu base de datos a otro repositorio con regularidad.
95
+
96
+ Esto hace que usar Git sea un placer, porque sabemos que podemos experimentar sin peligro de fastidiar gravemente las cosas. Para un análisis más exhaustivo de cómo almacena Git su información y cómo puedes recuperar datos aparentemente perdidos, ver Capítulo 9.
97
+
98
+ ### Los tres estados ###
99
+
100
+ Ahora presta atención. Esto es lo más importante a recordar acerca de Git si quieres que el resto de tu proceso de aprendizaje prosiga sin problemas. Git tiene tres estados principales en los que se pueden encontrar tus archivos: confirmado (committed), modificado (modified), y preparado (staged). Confirmado significa que los datos están almacenados de manera segura en tu base de datos local. Modificado significa que has modificado el archivo pero todavía no lo has confirmado a tu base de datos. Preparado significa que has marcado un archivo modificado en su versión actual para que vaya en tu próxima confirmación.
101
+
102
+ Esto nos lleva a las tres secciones principales de un proyecto de Git: el directorio de Git (Git directory), el directorio de trabajo (working directory), y el área de preparación (staging area).
103
+
104
+ Insert 18333fig0106.png
105
+ Figura 1-6. Directorio de trabajo, área de preparación y directorio de Git.
106
+
107
+ El directorio de Git es donde Git almacena los metadatos y la base de datos de objetos para tu proyecto. Es la parte más importante de Git, y es lo que se copia cuando clonas un repositorio desde otro ordenador.
108
+
109
+ El directorio de trabajo es una copia de una versión del proyecto. Estos archivos se sacan de la base de datos comprimida en el directorio de Git, y se colocan en disco para que los puedas usar o modificar.
110
+
111
+ El área de preparación es un sencillo archivo, generalmente contenido en tu directorio de Git, que almacena información acerca de lo que va a ir en tu próxima confirmación. A veces se le denomina índice, pero se está convirtiendo en estándar el referirse a ella como el área de preparación.
112
+
113
+ El flujo de trabajo básico en Git es algo así:
114
+
115
+ 1. Modificas una serie de archivos en tu directorio de trabajo.
116
+ 2. Preparas los archivos, añadiendolos a tu área de preparación.
117
+ 3. Confirmas los cambios, lo que toma los archivos tal y como están en el área de preparación, y almacena esas instantáneas de manera permanente en tu directorio de Git.
118
+
119
+ Si una versión concreta de un archivo está en el directorio de Git, se considera confirmada (committed). Si ha sufrido cambios desde que se obtuvo del repositorio, pero ha sido añadida al área de preparación, está preparada (staged). Y si ha sufrido cambios desde que se obtuvo del repositorio, pero no se ha preparado, está modificada (modified). En el Capítulo 2 aprenderás más acerca de estos estados, y de cómo puedes aprovecharte de ellos o saltarte toda la parte de preparación.
120
+
121
+ ## Instalando Git ##
122
+
123
+ Vamos a empezar a usar un poco de Git. Lo primero es lo primero: tienes que instalarlo. Puedes obtenerlo de varias maneras; las dos principales son instalarlo desde código fuente, o instalar un paquete existente para tu plataforma.
124
+
125
+ ### Instalando desde código fuente ###
126
+
127
+ Si puedes, en general es útil instalar Git desde código fuente, porque obtendrás la versión más reciente. Cada versión de Git tiende a incluir útiles mejoras en la interfaz de usuario, por lo que utilizar la última versión es a menudo el camino más adecuado si te sientes cómodo compilando software desde código fuente. También ocurre que muchas distribuciones de Linux contienen paquetes muy antiguos; así que a menos que estés en una distribución muy actualizada o estés usando backports, instalar desde código fuente puede ser la mejor opción.
128
+
129
+ Para instalar Git, necesitas tener las siguientes librerías de las que Git depende: curl, zlib, openssl, expat y libiconv. Por ejemplo, si estás en un sistema que tiene yum (como Fedora) o apt-get (como un sistema basado en Debian), puedes usar estos comandos para instalar todas las dependencias:
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
+ Cuando tengas todas las dependencias necesarias, puedes descargar la versión más reciente de Git desde su página web:
138
+
139
+ http://git-scm.com/download
140
+
141
+ Luego compila e instala:
142
+
143
+ $ tar -zxf git-1.6.0.5.tar.gz
144
+ $ cd git-1.6.0.5
145
+ $ make prefix=/usr/local all
146
+ $ sudo make prefix=/usr/local install
147
+
148
+ Una vez hecho esto, también puedes obtener Git, a través del propio Git, para futuras actualizaciones:
149
+
150
+ $ git clone git://git.kernel.org/pub/scm/git/git.git
151
+
152
+ ### Instalando en Linux ###
153
+
154
+ Si quieres instalar Git en Linux a través de un instalador binario, en general puedes hacerlo a través de la herramienta básica de gestión de paquetes que trae tu distribución. Si estás en Fedora, puedes usar yum:
155
+
156
+ $ yum install git-core
157
+
158
+ O si estás en una distribución basada en Debian como Ubuntu, prueba con apt-get:
159
+
160
+ $ apt-get install git
161
+
162
+ ### Instalando en Mac ###
163
+
164
+ Hay tres maneras fáciles de instalar Git en un Mac. La más sencilla es usar el instalador gráfico de Git, que puedes descargar desde la página de SourceForge (véase Figura 1-7):
165
+
166
+ http://sourceforge.net/projects/git-osx-installer/
167
+
168
+ Insert 18333fig0107.png
169
+ Figura 1-7. Instalador de Git para OS X.
170
+
171
+ Una alternativa es instalar Git a través de MacPorts (`http://www.macports.org`). Si tienes MacPorts instalado, instala Git con:
172
+
173
+ $ sudo port install git-core +svn +doc +bash_completion +gitweb
174
+
175
+ No necesitas añadir todos los extras, pero probablemente quieras incluir +svn en caso de que alguna vez necesites usar Git con repositorios Subversion (véase el Capítulo 8).
176
+
177
+ La segunda alternativa es Homebrew (`http://brew.sh/`). Si ya tienes instalado Homebrew, instala Git con:
178
+
179
+ $ brew install git
180
+
181
+ ### Instalando en Windows ###
182
+
183
+ Instalar Git en Windows es muy fácil. El proyecto msysGit tiene uno de los procesos de instalación más sencillos. Simplemente descarga el archivo exe del instalador desde la página de GitHub, y ejecútalo:
184
+
185
+ http://msysgit.github.com/
186
+
187
+ Una vez instalado, tendrás tanto la versión de línea de comandos (incluido un cliente SSH que nos será útil más adelante) como la interfaz gráfica de usuario estándar.
188
+
189
+ Nota para el uso en Windows: Se debería usar Git con la shell provista por msysGit (estilo Unix), lo cual permite usar las complejas líneas de comandos de este libro. Si por cualquier razón se necesitara usar la shell nativa de Windows, la consola de línea de comandos, se han de usar las comillas dobles en vez de las simples (para parámetros que contengan espacios) y se deben entrecomillar los parámetros terminándolos con el acento circunflejo (^) si están al final de la línea, ya que en Windows es uno de los símbolos de continuación.
190
+
191
+ ## Configurando Git por primera vez ##
192
+
193
+ Ahora que tienes Git en tu sistema, querrás hacer algunas cosas para personalizar tu entorno de Git. Sólo es necesario hacer estas cosas una vez; se mantendrán entre actualizaciones. También puedes cambiarlas en cualquier momento volviendo a ejecutar los comandos correspondientes.
194
+
195
+ Git trae una herramienta llamada `git config` que te permite obtener y establecer variables de configuración, que controlan el aspecto y funcionamiento de Git. Estas variables pueden almacenarse en tres sitios distintos:
196
+
197
+ * Archivo `/etc/gitconfig`: Contiene valores para todos los usuarios del sistema y todos sus repositorios. Si pasas la opción `--system` a `git config`, lee y escribe específicamente en este archivo.
198
+ * Archivo `~/.gitconfig` file: Específico a tu usuario. Puedes hacer que Git lea y escriba específicamente en este archivo pasando la opción `--global`.
199
+ * Archivo config en el directorio de Git (es decir, `.git/config`) del repositorio que estés utilizando actualmente: Específico a ese repositorio. Cada nivel sobrescribe los valores del nivel anterior, por lo que los valores de `.git/config` tienen preferencia sobre los de `/etc/gitconfig`.
200
+
201
+ En sistemas Windows, Git busca el archivo `.gitconfig` en el directorio `$HOME` (`%USERPROFILE%` in Windows’ environment), que es `C:\Documents and Settings\$USER` para la mayoría de usuarios, dependiendo de la versión (`$USER` es `%USERNAME%` en el entorno Windows). También busca en el directorio `/etc/gitconfig`, aunque esta ruta es relativa a la raíz MSys, que es donde quiera que decidieses instalar Git en tu sistema Windows cuando ejecutaste el instalador.
202
+
203
+ ### Tu identidad ###
204
+
205
+ Lo primero que deberías hacer cuando instalas Git es establecer tu nombre de usuario y dirección de correo electrónico. Esto es importante porque las confirmaciones de cambios (commits) en Git usan esta información, y es introducida de manera inmutable en los commits que envías:
206
+
207
+ $ git config --global user.name "John Doe"
208
+ $ git config --global user.email johndoe@example.com
209
+
210
+ De nuevo, sólo necesitas hacer esto una vez si especificas la opción `--global`, ya que Git siempre usará esta información para todo lo que hagas en ese sistema. Si quieres sobrescribir esta información con otro nombre o dirección de correo para proyectos específicos, puedes ejecutar el comando sin la opción `--global` cuando estés en ese proyecto.
211
+
212
+ ### Tu editor ###
213
+
214
+ Ahora que tu identidad está configurada, puedes elegir el editor de texto por defecto que se utilizará cuando Git necesite que introduzcas un mensaje. Si no indicas nada, Git usa el editor por defecto de tu sistema, que generalmente es Vi o Vim. Si quieres usar otro editor de texto, como Emacs, puedes hacer lo siguiente:
215
+
216
+ $ git config --global core.editor emacs
217
+
218
+ ### Tu herramienta de diferencias ###
219
+
220
+ Otra opción útil que puede que quieras configurar es la herramienta de diferencias por defecto, usada para resolver conflictos de unión (merge). Digamos que quieres usar vimdiff:
221
+
222
+ $ git config --global merge.tool vimdiff
223
+
224
+ Git acepta kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge, y opendiff como herramientas válidas. También puedes configurar la herramienta que tú quieras; véase el Capítulo 7 para más información sobre cómo hacerlo.
225
+
226
+ ### Comprobando tu configuración ###
227
+
228
+ Si quieres comprobar tu configuración, puedes usar el comando `git config --list` para listar todas las propiedades que Git ha configurado:
229
+
230
+ $ git config --list
231
+ user.name=Scott Chacon
232
+ user.email=schacon@gmail.com
233
+ color.status=auto
234
+ color.branch=auto
235
+ color.interactive=auto
236
+ color.diff=auto
237
+ ...
238
+
239
+ Puede que veas claves repetidas, porque Git lee la misma clave de distintos archivos (`/etc/gitconfig` y `~/.gitconfig`, por ejemplo). En ese caso, Git usa el último valor para cada clave única que ve.
240
+
241
+ También puedes comprobar qué valor cree Git que tiene una clave específica ejecutando `git config {clave}`:
242
+
243
+ $ git config user.name
244
+ Scott Chacon
245
+
246
+ ## Obteniendo ayuda ##
247
+
248
+ Si alguna vez necesitas ayuda usando Git, hay tres formas de ver la página del manual (manpage) para cualquier comando de Git:
249
+
250
+ $ git help <comando>
251
+ $ git <comando> --help
252
+ $ man git-<comando>
253
+
254
+ Por ejemplo, puedes ver la página del manual para el comando config ejecutando:
255
+
256
+ $ git help config
257
+
258
+ Estos comandos están bien porque puedes acceder a ellos desde cualquier sitio, incluso sin conexión. Si las páginas del manual y este libro no son suficientes y necesitas que te ayude una persona, puedes probar en los canales `#git` o `#github` del servidor de IRC Freenode (irc.freenode.net). Estos canales están llenos de cientos de personas muy entendidas en Git, y suelen estar dispuestos a ayudar.
259
+
260
+ ## Resumen ##
261
+
262
+ Deberías tener un conocimiento básico de qué es Git y en qué se diferencia del CVCS que puedes haber estado utilizando. También deberías tener funcionando en tu sistema una versión de Git configurada con tu identidad. Es el momento de aprender algunos fundamentos de Git.
@@ -0,0 +1,1165 @@
1
+ # Fundamentos de Git #
2
+
3
+ Si sólo puedes leer un capítulo para empezar a trabajar con Git, es éste. Este capítulo cubre todos los comandos básicos que necesitas para hacer la gran mayoría de las cosas a las que vas a dedicar tu tiempo en Git. Al final del capítulo, deberías ser capaz de configurar e inicializar un repositorio, comenzar y detener el seguimiento de archivos, y preparar (stage) y confirmar (commit) cambios. También te enseñaremos a configurar Git para que ignore ciertos archivos y patrones, cómo deshacer errores rápida y fácilmente, cómo navegar por la historia de tu proyecto y ver cambios entre confirmaciones, y cómo enviar (push) y recibir (pull) de repositorios remotos.
4
+
5
+ ## Obteniendo un repositorio Git ##
6
+
7
+ Puedes obtener un proyecto Git de dos maneras. La primera toma un proyecto o directorio existente y lo importa en Git. La segunda clona un repositorio Git existente desde otro servidor.
8
+
9
+ ### Inicializando un repositorio en un directorio existente ###
10
+
11
+ Si estás empezando el seguimiento en Git de un proyecto existente, necesitas ir al directorio del proyecto y escribir:
12
+
13
+ $ git init
14
+
15
+ Esto crea un nuevo subdirectorio llamado .git que contiene todos los archivos necesarios del repositorio —un esqueleto de un repositorio Git. Todavía no hay nada en tu proyecto que esté bajo seguimiento. (Véase el Capítulo 9 para obtener más información sobre qué archivos están contenidos en el directorio `.git` que acabas de crear.)
16
+
17
+ Si deseas empezar a controlar versiones de archivos existentes (a diferencia de un directorio vacío), probablemente deberías comenzar el seguimiento de esos archivos y hacer una confirmación inicial. Puedes conseguirlo con unos pocos comandos `git add` para especificar qué archivos quieres controlar, seguidos de un `commit` para confirmar los cambios:
18
+
19
+ $ git add *.c
20
+ $ git add README
21
+ $ git commit –m 'versión inicial del proyecto'
22
+
23
+ Veremos lo que hacen estos comandos dentro de un minuto. En este momento, tienes un repositorio Git con archivos bajo seguimiento, y una confirmación inicial.
24
+
25
+ ### Clonando un repositorio existente ###
26
+
27
+ Si deseas obtener una copia de un repositorio Git existente —por ejemplo, un proyecto en el que te gustaría contribuir— el comando que necesitas es `git clone`. Si estás familizarizado con otros sistemas de control de versiones como Subversion, verás que el comando es `clone` y no `checkout`. Es una distinción importante, ya que Git recibe una copia de casi todos los datos que tiene el servidor. Cada versión de cada archivo de la historia del proyecto es descargado cuando ejecutas `git clone`. De hecho, si el disco de tu servidor se corrompe, puedes usar cualquiera de los clones en cualquiera de los clientes para devolver al servidor al estado en el que estaba cuando fue clonado (puede que pierdas algunos *hooks* del lado del servidor y demás, pero toda la información versionada estaría ahí —véase el Capítulo 4 para más detalles—).
28
+
29
+ Puedes clonar un repositorio con `git clone [url]`. Por ejemplo, si quieres clonar la librería Ruby llamada Grit, harías algo así:
30
+
31
+ $ git clone git://github.com/schacon/grit.git
32
+
33
+ Esto crea un directorio llamado "grit", inicializa un directorio `.git` en su interior, descarga toda la información de ese repositorio, y saca una copia de trabajo de la última versión. Si te metes en el nuevo directorio `grit`, verás que están los archivos del proyecto, listos para ser utilizados. Si quieres clonar el repositorio a un directorio con otro nombre que no sea grit, puedes especificarlo con la siguiente opción de línea de comandos:
34
+
35
+ $ git clone git://github.com/schacon/grit.git mygrit
36
+
37
+ Ese comando hace lo mismo que el anterior, pero el directorio de destino se llamará mygrit.
38
+
39
+ Git te permite usar distintos protocolos de transferencia. El ejemplo anterior usa el protocolo `git://`, pero también te puedes encontrar con `http(s)://` o `usuario@servidor:/ruta.git`, que utiliza el protocolo de transferencia SSH. En el Capítulo 4 se introducirán todas las opciones disponibles a la hora de configurar el acceso a tu repositorio Git, y las ventajas e inconvenientes de cada una.
40
+
41
+ ## Guardando cambios en el repositorio ##
42
+
43
+ Tienes un repositorio Git completo, y una copia de trabajo de los archivos de ese proyecto. Necesitas hacer algunos cambios, y confirmar instantáneas de esos cambios a tu repositorio cada vez que el proyecto alcance un estado que desees grabar.
44
+
45
+ Recuerda que cada archivo de tu directorio de trabajo puede estar en uno de estos dos estados: bajo seguimiento (tracked), o sin seguimiento (untracked). Los archivos bajo seguimiento son aquellos que existían en la última instantánea; pueden estar sin modificaciones, modificados, o preparados. Los archivos sin seguimiento son todos los demás —cualquier archivo de tu directorio que no estuviese en tu última instantánea ni está en tu área de preparación—. La primera vez que clonas un repositorio, todos tus archivos estarán bajo seguimiento y sin modificaciones, ya que los acabas de copiar y no has modificado nada.
46
+
47
+ A medida que editas archivos, Git los ve como modificados, porque los has cambiado desde tu última confirmación. Preparas estos archivos modificados y luego confirmas todos los cambios que hayas preparado, y el ciclo se repite. Este proceso queda ilustrado en la Figura 2-1.
48
+
49
+ Insert 18333fig0201.png
50
+ Figura 2-1. El ciclo de vida del estado de tus archivos.
51
+
52
+ ### Comprobando el estado de tus archivos ###
53
+
54
+ Tu principal herramienta para determinar qué archivos están en qué estado es el comando `git status`. Si ejecutas este comando justo después de clonar un repositorio, deberías ver algo así:
55
+
56
+ $ git status
57
+ # On branch master
58
+ nothing to commit, working directory clean
59
+
60
+ Esto significa que tienes un directorio de trabajo limpio —en otras palabras, no tienes archivos bajo seguimiento y modificados—. Git tampoco ve ningún archivo que no esté bajo seguimiento, o estaría listado ahí. Por último, el comando te dice en qué rama estás. Por ahora, esa rama siempre es "master", que es la predeterminada. No te preocupes de eso por ahora, el siguiente capítulo tratará los temas de las ramas y las referencias en detalle.
61
+
62
+ Digamos que añades un nuevo archivo a tu proyecto, un sencillo archivo README. Si el archivo no existía y ejecutas `git status`, verás tus archivos sin seguimiento así:
63
+
64
+ $ vim README
65
+ $ git status
66
+ # On branch master
67
+ # Untracked files:
68
+ # (use "git add <file>..." to include in what will be committed)
69
+ #
70
+ # README
71
+ nothing added to commit but untracked files present (use "git add" to track)
72
+
73
+ Puedes ver que tu nuevo archivo README aparece bajo la cabecera “Archivos sin seguimiento” (“Untracked files”) de la salida del comando. Sin seguimiento significa básicamente que Git ve un archivo que no estaba en la instantánea anterior; Git no empezará a incluirlo en las confirmaciones de tus instantáneas hasta que se lo indiques explícitamente. Lo hace para que no incluyas accidentalmente archivos binarios generados u otros archivos que no tenías intención de incluir. Sí que quieres incluir el README, así que vamos a iniciar el seguimiento del archivo.
74
+
75
+ ### Seguimiento de nuevos archivos ###
76
+
77
+ Para empezar el seguimiento de un nuevo archivo se usa el comando `git add`. Iniciaremos el seguimiento del archivo README ejecutando esto:
78
+
79
+ $ git add README
80
+
81
+ Si vuelves a ejecutar el comando `git status`, verás que tu README está ahora bajo seguimiento y preparado:
82
+
83
+ $ git status
84
+ # On branch master
85
+ # Changes to be committed:
86
+ # (use "git reset HEAD <file>..." to unstage)
87
+ #
88
+ # new file: README
89
+ #
90
+
91
+ Puedes ver que está preparado porque aparece bajo la cabecera “Cambios a confirmar” (“Changes to be committed”). Si confirmas ahora, la versión del archivo en el momento de ejecutar `git add` será la que se incluya en la instantánea. Recordarás que cuando antes ejecutaste `git init`, seguidamente ejecutaste `git add (archivos)`. Esto era para iniciar el seguimiento de los archivos de tu directorio. El comando `git add` recibe la ruta de un archivo o de un directorio; si es un directorio, añade todos los archivos que contenga de manera recursiva.
92
+
93
+ ### Preparando archivos modificados ###
94
+
95
+ Vamos a modificar un archivo que estuviese bajo seguimiento. Si modificas el archivo `benchmarks.rb` que estaba bajo seguimiento, y ejecutas el comando `status` de nuevo, verás algo así:
96
+
97
+ $ git status
98
+ # On branch master
99
+ # Changes to be committed:
100
+ # (use "git reset HEAD <file>..." to unstage)
101
+ #
102
+ # new file: README
103
+ #
104
+ # Changes not staged for commit:
105
+ # (use "git add <file>..." to update what will be committed)
106
+ #
107
+ # modified: benchmarks.rb
108
+ #
109
+
110
+ El archivo benchmarks.rb aparece bajo la cabecera “Modificados pero no actualizados” (“Changes not staged for commit”) —esto significa que un archivo bajo seguimiento ha sido modificado en el directorio de trabajo, pero no ha sido preparado todavía—. Para prepararlo, ejecuta el comando `git add` (es un comando multiuso —puedes utilizarlo para empezar el seguimiento de archivos nuevos, para preparar archivos, y para otras cosas como marcar como resueltos archivos con conflictos de unión—). Ejecutamos `git add` para preparar el archivo benchmarks.rb, y volvemos a ejecutar `git status`:
111
+
112
+ $ git add benchmarks.rb
113
+ $ git status
114
+ # On branch master
115
+ # Changes to be committed:
116
+ # (use "git reset HEAD <file>..." to unstage)
117
+ #
118
+ # new file: README
119
+ # modified: benchmarks.rb
120
+ #
121
+
122
+ Ambos archivos están ahora preparados y se incluirán en tu próxima confirmación. Supón que en este momento recuerdas que tenías que hacer una pequeña modificación en benchmarks.rb antes de confirmarlo. Lo vuelves abrir, haces ese pequeño cambio, y ya estás listo para confirmar. Sin embargo, si vuelves a ejecutar `git status` verás lo siguiente:
123
+
124
+ $ vim benchmarks.rb
125
+ $ git status
126
+ # On branch master
127
+ # Changes to be committed:
128
+ # (use "git reset HEAD <file>..." to unstage)
129
+ #
130
+ # new file: README
131
+ # modified: benchmarks.rb
132
+ #
133
+ # Changes not staged for commit:
134
+ # (use "git add <file>..." to update what will be committed)
135
+ #
136
+ # modified: benchmarks.rb
137
+ #
138
+
139
+ ¿Pero qué...? Ahora benchmarks.rb aparece listado como preparado y como no preparado. ¿Cómo es posible? Resulta que Git prepara un archivo tal y como era en el momento de ejecutar el comando `git add`. Si haces `git commit` ahora, la versión de benchmarks.rb que se incluirá en la confirmación será la que fuese cuando ejecutaste el comando `git add`, no la versión que estás viendo ahora en tu directorio de trabajo. Si modificas un archivo después de haber ejecutado `git add`, tendrás que volver a ejecutar `git add` para preparar la última versión del archivo:
140
+
141
+ $ git add benchmarks.rb
142
+ $ git status
143
+ # On branch master
144
+ # Changes to be committed:
145
+ # (use "git reset HEAD <file>..." to unstage)
146
+ #
147
+ # new file: README
148
+ # modified: benchmarks.rb
149
+ #
150
+
151
+ ### Ignorando archivos ###
152
+
153
+ A menudo tendrás un tipo de archivos que no quieras que Git añada automáticamente o te muestre como no versionado. Suelen ser archivos generados automáticamente, como archivos de log, o archivos generados por tu compilador. Para estos casos puedes crear un archivo llamado .gitignore, en el que listas los patrones de nombres que deseas que sean ignorados. He aquí un archivo .gitignore de ejemplo:
154
+
155
+ $ cat .gitignore
156
+ *.[oa]
157
+ *~
158
+
159
+ La primera línea le dice a Git que ignore cualquier archivo cuyo nombre termine en .o o .a —archivos objeto que suelen ser producto de la compilación de código—. La segunda línea le dice a Git que ignore todos los archivos que terminan en tilde (`~`), usada por muchos editores de texto, como Emacs, para marcar archivos temporales. También puedes incluir directorios de log, temporales, documentación generada automáticamente, etc. Configurar un archivo .gitignore antes de empezar a trabajar suele ser una buena idea, para así no confirmar archivos que no quieres en tu repositorio Git.
160
+
161
+ Las reglas para los patrones que pueden ser incluidos en el archivo .gitignore son:
162
+
163
+ * Las líneas en blanco, o que comienzan por #, son ignoradas.
164
+ * Puedes usar patrones glob estándar.
165
+ * Puedes indicar un directorio añadiendo una barra hacia delante (`/`) al final.
166
+ * Puedes negar un patrón añadiendo una exclamación (`!`) al principio.
167
+
168
+ Los patrones glob son expresiones regulares simplificadas que pueden ser usadas por las shells. Un asterisco (`*`) reconoce cero o más caracteres; `[abc]` reconoce cualquier carácter de los especificados entre corchetes (en este caso, a, b o c); una interrogación (`?`) reconoce un único carácter; y caracteres entre corchetes separados por un guión (`[0-9]`) reconoce cualquier carácter entre ellos (en este caso, de 0 a 9).
169
+
170
+ He aquí otro ejemplo de archivo .gitignore:
171
+
172
+ # a comment – this is ignored
173
+ # no .a files
174
+ *.a
175
+ # but do track lib.a, even though you're ignoring .a files above
176
+ !lib.a
177
+ # only ignore the root TODO file, not subdir/TODO
178
+ /TODO
179
+ # ignore all files in the build/ directory
180
+ build/
181
+ # ignore doc/notes.txt, but not doc/server/arch.txt
182
+ doc/*.txt
183
+ # ignore all .txt files in the doc/ directory
184
+ doc/**/*.txt
185
+
186
+ El patrón `**/` está disponible en Git desde la versión 1.8.2.
187
+
188
+ ### Viendo tus cambios preparados y no preparados ###
189
+
190
+ Si el comando `git status` es demasiado impreciso para ti —quieres saber exactamente lo que ha cambiado, no sólo qué archivos fueron modificados— puedes usar el comando `git diff`. Veremos `git diff` en más detalle después; pero probablemente lo usarás para responder estas dos preguntas: ¿qué has cambiado pero aún no has preparado?, y ¿qué has preparado y estás a punto de confirmar? Aunque `git status` responde esas preguntas de manera general, `git diff` te muestra exactamente las líneas añadidas y eliminadas —el parche, como si dijésemos.
191
+
192
+ Supongamos que quieres editar y preparar el archivo README otra vez, y luego editar el archivo benchmarks.rb sin prepararlo. Si ejecutas el comando `status`, de nuevo verás algo así:
193
+
194
+ $ git status
195
+ # On branch master
196
+ # Changes to be committed:
197
+ # (use "git reset HEAD <file>..." to unstage)
198
+ #
199
+ # new file: README
200
+ #
201
+ # Changes not staged for commit:
202
+ # (use "git add <file>..." to update what will be committed)
203
+ #
204
+ # modified: benchmarks.rb
205
+ #
206
+
207
+ Para ver lo que has modificado pero aún no has preparado, escribe `git diff`:
208
+
209
+ $ git diff
210
+ diff --git a/benchmarks.rb b/benchmarks.rb
211
+ index 3cb747f..da65585 100644
212
+ --- a/benchmarks.rb
213
+ +++ b/benchmarks.rb
214
+ @@ -36,6 +36,10 @@ def main
215
+ @commit.parents[0].parents[0].parents[0]
216
+ end
217
+
218
+ + run_code(x, 'commits 1') do
219
+ + git.commits.size
220
+ + end
221
+ +
222
+ run_code(x, 'commits 2') do
223
+ log = git.commits('master', 15)
224
+ log.size
225
+
226
+ Ese comando compara lo que hay en tu directorio de trabajo con lo que hay en tu área de preparación. El resultado te indica los cambios que has hecho y que todavía no has preparado.
227
+
228
+ Si quieres ver los cambios que has preparado y que irán en tu próxima confirmación, puedes usar `git diff –-cached`. (A partir de la versión 1.6.1 de Git, también puedes usar `git diff –-staged`, que puede resultar más fácil de recordar.) Este comando compara tus cambios preparados con tu última confirmación:
229
+
230
+ $ git diff --cached
231
+ diff --git a/README b/README
232
+ new file mode 100644
233
+ index 0000000..03902a1
234
+ --- /dev/null
235
+ +++ b/README2
236
+ @@ -0,0 +1,5 @@
237
+ +grit
238
+ + by Tom Preston-Werner, Chris Wanstrath
239
+ + http://github.com/mojombo/grit
240
+ +
241
+ +Grit is a Ruby library for extracting information from a Git repository
242
+
243
+ Es importante indicar que `git diff` por sí solo no muestra todos los cambios hechos desde tu última confirmación —sólo los cambios que todavía no están preparados—. Esto puede resultar desconcertante, porque si has preparado todos tus cambios, `git diff` no mostrará nada.
244
+
245
+ Por poner otro ejemplo, si preparas el archivo benchmarks.rb y después lo editas, puedes usar `git diff` para ver las modificaciones del archivo que están preparadas, y las que no lo están:
246
+
247
+ $ git add benchmarks.rb
248
+ $ echo '# test line' >> benchmarks.rb
249
+ $ git status
250
+ # On branch master
251
+ #
252
+ # Changes to be committed:
253
+ #
254
+ # modified: benchmarks.rb
255
+ #
256
+ # Changes not staged for commit:
257
+ #
258
+ # modified: benchmarks.rb
259
+ #
260
+
261
+ Ahora puedes usar `git diff` para ver qué es lo que aún no está preparado:
262
+
263
+ $ git diff
264
+ diff --git a/benchmarks.rb b/benchmarks.rb
265
+ index e445e28..86b2f7c 100644
266
+ --- a/benchmarks.rb
267
+ +++ b/benchmarks.rb
268
+ @@ -127,3 +127,4 @@ end
269
+ main()
270
+
271
+ ##pp Grit::GitRuby.cache_client.stats
272
+ +# test line
273
+
274
+ Y `git diff --cached` para ver los cambios que llevas preparados hasta ahora:
275
+
276
+ $ git diff --cached
277
+ diff --git a/benchmarks.rb b/benchmarks.rb
278
+ index 3cb747f..e445e28 100644
279
+ --- a/benchmarks.rb
280
+ +++ b/benchmarks.rb
281
+ @@ -36,6 +36,10 @@ def main
282
+ @commit.parents[0].parents[0].parents[0]
283
+ end
284
+
285
+ + run_code(x, 'commits 1') do
286
+ + git.commits.size
287
+ + end
288
+ +
289
+ run_code(x, 'commits 2') do
290
+ log = git.commits('master', 15)
291
+ log.size
292
+
293
+ ### Confirmando tus cambios ###
294
+
295
+ Ahora que el área de preparación está como tú quieres, puedes confirmar los cambios. Recuerda que cualquier cosa que todavía esté sin preparar —cualquier archivo que hayas creado o modificado, y sobre el que no hayas ejecutado `git add` desde su última edición— no se incluirá en esta confirmación. Se mantendrán como modificados en tu disco.
296
+
297
+ En este caso, la última vez que ejecutaste `git status` viste que estaba todo preparado, por lo que estás listo para confirmar tus cambios. La forma más fácil de confirmar es escribiendo `git commit`:
298
+
299
+ $ git commit
300
+
301
+ Al hacerlo, se ejecutará tu editor de texto. (Esto se configura a través de la variable de entorno `$EDITOR` de tu shell —normalmente vim o emacs, aunque puedes configurarlo usando el comando `git config --global core.editor` como vimos en el Capítulo 1.—)
302
+
303
+ El editor mostrará el siguiente texto (este ejemplo usa Vim):
304
+
305
+ # Please enter the commit message for your changes. Lines starting
306
+ # with '#' will be ignored, and an empty message aborts the commit.
307
+ # On branch master
308
+ # Changes to be committed:
309
+ # (use "git reset HEAD <file>..." to unstage)
310
+ #
311
+ # new file: README
312
+ # modified: benchmarks.rb
313
+ ~
314
+ ~
315
+ ~
316
+ ".git/COMMIT_EDITMSG" 10L, 283C
317
+
318
+ Puedes ver que el mensaje de confirmación predeterminado contiene la salida del comando `git status` comentada, y una línea vacía arriba del todo. Puedes eliminar estos comentarios y escribir tu mensaje de confirmación, o puedes dejarlos para ayudarte a recordar las modificaciones que estás confirmando. (Para un recordatorio todavía más explícito de lo que has modificado, puedes pasar la opción `-v` a `git commit`. Esto provoca que se añadan también las diferencias de tus cambios, para que veas exactamente lo que hiciste.) Cuando sales del editor, Git crea tu confirmación con el mensaje que hayas especificado (omitiendo los comentarios y las diferencias).
319
+
320
+ Como alternativa, puedes escribir tu mensaje de confirmación desde la propia línea de comandos mediante la opción `-m`:
321
+
322
+ $ git commit -m "Story 182: Fix benchmarks for speed"
323
+ [master]: created 463dc4f: "Fix benchmarks for speed"
324
+ 2 files changed, 3 insertions(+), 0 deletions(-)
325
+ create mode 100644 README
326
+
327
+ ¡Acabas de crear tu primera confirmación! Puedes ver que el comando `commit` ha dado cierta información sobre la confirmación: a qué rama has confirmado (master), cuál es su suma de comprobación SHA-1 de la confirmación (`463dc4f`), cuántos archivos se modificaron, y estadísticas acerca de cuántas líneas se han añadido y cuántas se han eliminado.
328
+
329
+ Recuerda que la confirmación registra la instantánea de tu área de preparación. Cualquier cosa que no preparases sigue estando modificada; puedes hacer otra confirmación para añadirla a la historia del proyecto. Cada vez que confirmas, estás registrando una instantánea de tu proyecto, a la que puedes volver o con la que puedes comparar más adelante.
330
+
331
+ ### Saltándote el área de preparación ###
332
+
333
+ Aunque puede ser extremadamente útil para elaborar confirmaciones exactamente a tu gusto, el área de preparación es en ocasiones demasiado compleja para las necesidades de tu flujo de trabajo. Si quieres saltarte el área de preparación, Git proporciona un atajo. Pasar la opción `-a` al comando `git commit` hace que Git prepare todo archivo que estuviese en seguimiento antes de la confirmación, permitiéndote obviar toda la parte de `git add`:
334
+
335
+ $ git status
336
+ # On branch master
337
+ #
338
+ # Changes not staged for commit:
339
+ #
340
+ # modified: benchmarks.rb
341
+ #
342
+ $ git commit -a -m 'added new benchmarks'
343
+ [master 83e38c7] added new benchmarks
344
+ 1 files changed, 5 insertions(+), 0 deletions(-)
345
+
346
+ Fíjate que no has tenido que ejecutar `git add` sobre el archivo benchmarks.rb antes de hacer la confirmación.
347
+
348
+ ### Eliminando archivos ###
349
+
350
+ Para eliminar un archivo de Git, debes eliminarlo de tus archivos bajo seguimiento (más concretamente, debes eliminarlo de tu área de preparación), y después confirmar. El comando `git rm` se encarga de eso, y también elimina el archivo de tu directorio de trabajo, para que no lo veas entre los archivos sin seguimiento.
351
+
352
+ Si simplemente eliminas el archivo de tu directorio de trabajo, aparecerá bajo la cabecera “Modificados pero no actualizados” (“Changes not staged for commit”) (es decir, _sin preparar_) de la salida del comando `git status`:
353
+
354
+ $ rm grit.gemspec
355
+ $ git status
356
+ # On branch master
357
+ #
358
+ # Changes not staged for commit:
359
+ # (use "git add/rm <file>..." to update what will be committed)
360
+ #
361
+ # deleted: grit.gemspec
362
+ #
363
+
364
+ Si entonces ejecutas el comando `git rm`, preparas la eliminación del archivo en cuestión:
365
+
366
+ $ git rm grit.gemspec
367
+ rm 'grit.gemspec'
368
+ $ git status
369
+ # On branch master
370
+ #
371
+ # Changes to be committed:
372
+ # (use "git reset HEAD <file>..." to unstage)
373
+ #
374
+ # deleted: grit.gemspec
375
+ #
376
+
377
+ La próxima vez que confirmes, el archivo desaparecerá y dejará de estar bajo seguimiento. Si ya habías modificado el archivo y lo tenías en el área de preparación, deberás forzar su eliminación con la opción `-f`. Ésta es una medida de seguridad para evitar la eliminación accidental de información que no ha sido registrada en una instantánea, y que por tanto no podría ser recuperada.
378
+
379
+ Otra cosa que puede que quieras hacer es mantener el archivo en tu directorio de trabajo, pero eliminarlo de tu área de preparación. Dicho de otro modo, puede que quieras mantener el archivo en tu disco duro, pero interrumpir su seguimiento por parte de Git. Esto resulta particularmente útil cuando olvidaste añadir algo a tu archivo `.gitignore` y lo añadiste accidentalmente, como un archivo de log enorme, o un montón de archivos `.a`. Para hacer esto, usa la opción `--cached`:
380
+
381
+ $ git rm --cached readme.txt
382
+
383
+ El comando `git rm` acepta archivos, directorios, y patrones glob. Es decir, que podrías hacer algo así:
384
+
385
+ $ git rm log/\*.log
386
+
387
+ Fíjate en la barra hacia atrás (`\`) antes del `*`. Es necesaria debido a que Git hace su propia expansión de rutas, además de la expansión que hace tu shell. En la consola del sistema de Windows, esta barra debe de ser omitida. Este comando elimina todos los archivos con la extensión `.log` en el directorio `log/`. También puedes hacer algo así:
388
+
389
+ $ git rm \*~
390
+
391
+ Este comando elimina todos los archivos que terminan en `~`.
392
+
393
+ ### Moviendo archivos ###
394
+
395
+ A diferencia de muchos otros VCSs, Git no hace un seguimiento explicito del movimiento de archivos. Si renombras un archivo, en Git no se almacena ningún metadato que indique que lo has renombrado. Sin embargo, Git es suficientemente inteligente como para darse cuenta —trataremos el tema de la detección de movimiento de archivos un poco más adelante.
396
+
397
+ Por tanto, es un poco desconcertante que Git tenga un comando `mv`. Si quieres renombrar un archivo en Git, puedes ejecutar algo así:
398
+
399
+ $ git mv file_from file_to
400
+
401
+ Y funciona perfectamente. De hecho, cuando ejecutas algo así y miras la salida del comando `status`, verás que Git lo considera un archivo renombrado:
402
+
403
+ $ git mv README.txt README
404
+ $ git status
405
+ # On branch master
406
+ # Your branch is ahead of 'origin/master' by 1 commit.
407
+ #
408
+ # Changes to be committed:
409
+ # (use "git reset HEAD <file>..." to unstage)
410
+ #
411
+ # renamed: README.txt -> README
412
+ #
413
+
414
+ Sin embargo, esto es equivalente a ejecutar algo así:
415
+
416
+ $ mv README.txt README
417
+ $ git rm README.txt
418
+ $ git add README
419
+
420
+ Git se da cuenta de que es un renombrado de manera implícita, así que no importa si renombras un archivo de este modo, o usando el comando `mv`. La única diferencia real es que `mv` es un comando en vez de tres —es más cómodo—. Y lo que es más importante, puedes usar cualquier herramienta para renombrar un archivo, y preocuparte de los `add` y `rm` más tarde, antes de confirmar.
421
+
422
+ ## Viendo el histórico de confirmaciones ##
423
+
424
+ Después de haber hecho varias confirmaciones, o si has clonado un repositorio que ya tenía un histórico de confirmaciones, probablemente quieras mirar atrás para ver qué modificaciones se han llevado a cabo. La herramienta más básica y potente para hacer esto es el comando `git log`.
425
+
426
+ Estos ejemplos usan un proyecto muy sencillo llamado simplegit que suelo usar para hacer demostraciones. Para clonar el proyecto, ejecuta:
427
+
428
+ git clone git://github.com/schacon/simplegit-progit.git
429
+
430
+ Cuando ejecutes `git log` sobre este proyecto, deberías ver una salida similar a esta:
431
+
432
+ $ git log
433
+ commit ca82a6dff817ec66f44342007202690a93763949
434
+ Author: Scott Chacon <schacon@gee-mail.com>
435
+ Date: Mon Mar 17 21:52:11 2008 -0700
436
+
437
+ changed the version number
438
+
439
+ commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
440
+ Author: Scott Chacon <schacon@gee-mail.com>
441
+ Date: Sat Mar 15 16:40:33 2008 -0700
442
+
443
+ removed unnecessary test code
444
+
445
+ commit a11bef06a3f659402fe7563abf99ad00de2209e6
446
+ Author: Scott Chacon <schacon@gee-mail.com>
447
+ Date: Sat Mar 15 10:31:28 2008 -0700
448
+
449
+ first commit
450
+
451
+ Por defecto, si no pasas ningún argumento, `git log` lista las confirmaciones hechas sobre ese repositorio en orden cronológico inverso. Es decir, las confirmaciones más recientes se muestran al principio. Como puedes ver, este comando lista cada confirmación con su suma de comprobación SHA-1, el nombre y dirección de correo del autor, la fecha y el mensaje de confirmación.
452
+
453
+ El comando `git log` proporciona gran cantidad de opciones para mostrarte exactamente lo que buscas. Aquí veremos algunas de las más usadas.
454
+
455
+ Una de las opciones más útiles es `-p`, que muestra las diferencias introducidas en cada confirmación. También puedes usar la opción `-2`, que hace que se muestren únicamente las dos últimas entradas del histórico:
456
+
457
+ $ git log –p -2
458
+ commit ca82a6dff817ec66f44342007202690a93763949
459
+ Author: Scott Chacon <schacon@gee-mail.com>
460
+ Date: Mon Mar 17 21:52:11 2008 -0700
461
+
462
+ changed the version number
463
+
464
+ diff --git a/Rakefile b/Rakefile
465
+ index a874b73..8f94139 100644
466
+ --- a/Rakefile
467
+ +++ b/Rakefile
468
+ @@ -5,7 +5,7 @@ require 'rake/gempackagetask'
469
+ spec = Gem::Specification.new do |s|
470
+ - s.version = "0.1.0"
471
+ + s.version = "0.1.1"
472
+ s.author = "Scott Chacon"
473
+
474
+ commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
475
+ Author: Scott Chacon <schacon@gee-mail.com>
476
+ Date: Sat Mar 15 16:40:33 2008 -0700
477
+
478
+ removed unnecessary test code
479
+
480
+ diff --git a/lib/simplegit.rb b/lib/simplegit.rb
481
+ index a0a60ae..47c6340 100644
482
+ --- a/lib/simplegit.rb
483
+ +++ b/lib/simplegit.rb
484
+ @@ -18,8 +18,3 @@ class SimpleGit
485
+ end
486
+
487
+ end
488
+ -
489
+ -if $0 == __FILE__
490
+ - git = SimpleGit.new
491
+ - puts git.show
492
+ -end
493
+
494
+
495
+ Esta opción muestra la misma información, pero añadiendo tras cada entrada las diferencias que le corresponden. Esto resulta muy útil para revisiones de código, o para visualizar rápidamente lo que ha pasado en las confirmaciones enviadas por un colaborador.
496
+
497
+ A veces es más fácil revisar cambios a nivel de palabra que a nivel de línea. Git dispone de la opción `--word-diff`, que se puede añadir al comando `git log -p` para obtener las diferencias por palabras en lugar de las diferencias línea por línea. Formatear las diferencias a nivel de palabra es bastante inusual cuando se aplica a código fuente, pero resulta muy práctico cuando se aplica a grandes archivos de texto, como libros o tu propia tesis. He aquí un ejemplo:
498
+
499
+ $ git log -U1 --word-diff
500
+ commit ca82a6dff817ec66f44342007202690a93763949
501
+ Author: Scott Chacon <schacon@gee-mail.com>
502
+ Date: Mon Mar 17 21:52:11 2008 -0700
503
+
504
+ changed the version number
505
+
506
+ diff --git a/Rakefile b/Rakefile
507
+ index a874b73..8f94139 100644
508
+ --- a/Rakefile
509
+ +++ b/Rakefile
510
+ @@ -7,3 +7,3 @@ spec = Gem::Specification.new do |s|
511
+ s.name = "simplegit"
512
+ s.version = [-"0.1.0"-]{+"0.1.1"+}
513
+ s.author = "Scott Chacon"
514
+
515
+ Como se puede ver, no aparecen líneas añadidas o eliminadas en la salida como en las diferencias normales. Se puede ver la palabra añadida encerrada en `{+ +}` y la eliminada en `[- -]`. Puede que se quiera reducir las usuales tres líneas de contexto en las diferencias a sólo una línea puesto que el contexto es ahora de palabras, no de líneas. Se puede hacer esto con `-U1`, como hicimos en el ejemplo de arriba.
516
+
517
+ También puedes usar con `git log` una serie de opciones de resumen. Por ejemplo, si quieres ver algunas estadísticas de cada confirmación, puedes usar la opción `--stat`:
518
+
519
+ $ git log --stat
520
+ commit ca82a6dff817ec66f44342007202690a93763949
521
+ Author: Scott Chacon <schacon@gee-mail.com>
522
+ Date: Mon Mar 17 21:52:11 2008 -0700
523
+
524
+ changed the version number
525
+
526
+ Rakefile | 2 +-
527
+ 1 files changed, 1 insertions(+), 1 deletions(-)
528
+
529
+ commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
530
+ Author: Scott Chacon <schacon@gee-mail.com>
531
+ Date: Sat Mar 15 16:40:33 2008 -0700
532
+
533
+ removed unnecessary test code
534
+
535
+ lib/simplegit.rb | 5 -----
536
+ 1 files changed, 0 insertions(+), 5 deletions(-)
537
+
538
+ commit a11bef06a3f659402fe7563abf99ad00de2209e6
539
+ Author: Scott Chacon <schacon@gee-mail.com>
540
+ Date: Sat Mar 15 10:31:28 2008 -0700
541
+
542
+ first commit
543
+
544
+ README | 6 ++++++
545
+ Rakefile | 23 +++++++++++++++++++++++
546
+ lib/simplegit.rb | 25 +++++++++++++++++++++++++
547
+ 3 files changed, 54 insertions(+), 0 deletions(-)
548
+
549
+ Como puedes ver, la opción `--stat` imprime tras cada confirmación una lista de archivos modificados, indicando cuántos han sido modificados y cuántas líneas han sido añadidas y eliminadas para cada uno de ellos, y un resumen de toda esta información.
550
+
551
+ Otra opción realmente útil es `--pretty`, que modifica el formato de la salida. Tienes unos cuantos estilos disponibles. La opción `oneline` imprime cada confirmación en una única línea, lo que puede resultar útil si estás analizando gran cantidad de confirmaciones. Otras opciones son `short`, `full` y `fuller`, que muestran la salida en un formato parecido, pero añadiendo menos o más información, respectivamente:
552
+
553
+ $ git log --pretty=oneline
554
+ ca82a6dff817ec66f44342007202690a93763949 changed the version number
555
+ 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test code
556
+ a11bef06a3f659402fe7563abf99ad00de2209e6 first commit
557
+
558
+ La opción más interesante es `format`, que te permite especificar tu propio formato. Esto resulta especialmente útil si estás generando una salida para que sea analizada por otro programa —como especificas el formato explícitamente, sabes que no cambiará en futuras actualizaciones de Git—:
559
+
560
+ $ git log --pretty=format:"%h - %an, %ar : %s"
561
+ ca82a6d - Scott Chacon, 11 months ago : changed the version number
562
+ 085bb3b - Scott Chacon, 11 months ago : removed unnecessary test code
563
+ a11bef0 - Scott Chacon, 11 months ago : first commit
564
+
565
+ La Tabla 2-1 lista algunas de las opciones más útiles aceptadas por `format`.
566
+
567
+ Opción Descripción de la salida
568
+ %H Hash de la confirmación
569
+ %h Hash de la confirmación abreviado
570
+ %T Hash del árbol
571
+ %t Hash del árbol abreviado
572
+ %P Hashes de las confirmaciones padre
573
+ %p Hashes de las confirmaciones padre abreviados
574
+ %an Nombre del autor
575
+ %ae Dirección de correo del autor
576
+ %ad Fecha de autoría (el formato respeta la opción `-–date`)
577
+ %ar Fecha de autoría, relativa
578
+ %cn Nombre del confirmador
579
+ %ce Dirección de correo del confirmador
580
+ %cd Fecha de confirmación
581
+ %cr Fecha de confirmación, relativa
582
+ %s Asunto
583
+
584
+ Puede que te estés preguntando la diferencia entre _autor_ (_author_) y _confirmador_ (_committer_). El autor es la persona que escribió originalmente el trabajo, mientras que el confirmador es quien lo aplicó. Por tanto, si mandas un parche a un proyecto, y uno de sus miembros lo aplica, ambos recibiréis reconocimiento —tú como autor, y el miembro del proyecto como confirmador—. Veremos esta distinción en mayor profundidad en el Capítulo 5.
585
+
586
+ Las opciones `oneline` y `format` son especialmente útiles combinadas con otra opción llamada `--graph`. Ésta añade un pequeño gráfico ASCII mostrando tu histórico de ramificaciones y uniones, como podemos ver en nuestra copia del repositorio del proyecto Grit:
587
+
588
+ $ git log --pretty=format:"%h %s" --graph
589
+ * 2d3acf9 ignore errors from SIGCHLD on trap
590
+ * 5e3ee11 Merge branch 'master' of git://github.com/dustin/grit
591
+ |\
592
+ | * 420eac9 Added a method for getting the current branch.
593
+ * | 30e367c timeout code and tests
594
+ * | 5a09431 add timeout protection to grit
595
+ * | e1193f8 support for heads with slashes in them
596
+ |/
597
+ * d6016bc require time for xmlschema
598
+ * 11d191e Merge branch 'defunkt' into local
599
+
600
+ Éstas son sólo algunas de las opciones para formatear la salida de `git log` —existen muchas más. La Tabla 2-2 lista las opciones vistas hasta ahora, y algunas otras opciones de formateo que pueden resultarte útiles, así como su efecto sobre la salida.
601
+
602
+ Opción Descripción
603
+ -p Muestra el parche introducido en cada confirmación.
604
+ --word-diff Muestra el parche en formato de una palabra.
605
+ --stat Muestra estadísticas sobre los archivos modificados en cada confirmación.
606
+ --shortstat Muestra solamente la línea de resumen de la opción `--stat`.
607
+ --name-only Muestra la lista de archivos afectados.
608
+ --name-status Muestra la lista de archivos afectados, indicando además si fueron añadidos, modificados o eliminados.
609
+ --abbrev-commit Muestra solamente los primeros caracteres de la suma SHA-1, en vez de los 40 caracteres de que se compone.
610
+ --relative-date Muestra la fecha en formato relativo (por ejemplo, “2 weeks ago” (“hace 2 semanas”)) en lugar del formato completo.
611
+ --graph Muestra un gráfico ASCII con la historia de ramificaciones y uniones.
612
+ --pretty Muestra las confirmaciones usando un formato alternativo. Posibles opciones son oneline, short, full, fuller y format (mediante el cual puedes especificar tu propio formato).
613
+ --oneline Un cómodo acortamiento de la opción `--pretty=oneline --abbrev-commit`.
614
+
615
+ ### Limitando la salida del histórico ###
616
+
617
+ Además de las opciones de formateo, `git log` acepta una serie de opciones para limitar su salida —es decir, opciones que te permiten mostrar únicamente parte de las confirmaciones—. Ya has visto una de ellas, la opción `-2`, que muestra sólo las dos últimas confirmaciones. De hecho, puedes hacer `-<n>`, siendo `n` cualquier entero, para mostrar las últimas `n` confirmaciones. En realidad es poco probable que uses esto con frecuencia, ya que Git por defecto pagina su salida para que veas cada página del histórico por separado.
618
+
619
+ Sin embargo, las opciones temporales como `--since` (desde) y `--until` (hasta) sí que resultan muy útiles. Por ejemplo, este comando lista todas las confirmaciones hechas durante las dos últimas semanas:
620
+
621
+ $ git log --since=2.weeks
622
+
623
+ Este comando acepta muchos formatos. Puedes indicar una fecha concreta (“2008-01-15”), o relativa, como “2 years 1 day 3 minutes ago” (“hace 2 años, 1 día y 3 minutos”).
624
+
625
+ También puedes filtrar la lista para que muestre sólo aquellas confirmaciones que cumplen ciertos criterios. La opción `--author` te permite filtrar por autor, y `--grep` te permite buscar palabras clave entre los mensajes de confirmación. (Ten en cuenta que si quieres aplicar ambas opciones simultáneamente, tienes que añadir `--all-match`, o el comando mostrará las confirmaciones que cumplan cualquiera de las dos, no necesariamente las dos a la vez.)
626
+
627
+ <!-- The prior paragraph was changed in English version for the following two in commit 60e261895a77951a6541470c9438f32a1e5b7fd0. It has not been trasnlated yet:
628
+
629
+ You can also filter the list to commits that match some search criteria. The `--author` option allows you to filter on a specific author, and the `--grep` option lets you search for keywords in the commit messages. (Note that if you specify both author and grep options, the command will match commits with both.)
630
+
631
+ If you want to specify multiple grep options, you have to add `--all-match` or the command will match commits with either.
632
+ -->
633
+
634
+ La última opción verdaderamente útil para filtrar la salida de `git log` es especificar una ruta. Si especificas la ruta de un directorio o archivo, puedes limitar la salida a aquellas confirmaciones que introdujeron un cambio en dichos archivos. Ésta debe ser siempre la última opción, y suele ir precedida de dos guiones (`--`) para separar la ruta del resto de opciones.
635
+
636
+ En la Tabla 2-3 se listan estas opciones, y algunas otras bastante comunes, a modo de referencia.
637
+
638
+ Opción Descripción
639
+ -(n) Muestra solamente las últimas n confirmaciones
640
+ --since, --after Muestra aquellas confirmaciones hechas después de la fecha especificada.
641
+ --until, --before Muestra aquellas confirmaciones hechas antes de la fecha especificada.
642
+ --author Muestra sólo aquellas confirmaciones cuyo autor coincide con la cadena especificada.
643
+ --committer Muestra sólo aquellas confirmaciones cuyo confirmador coincide con la cadena especificada.
644
+
645
+ Por ejemplo, si quieres ver cuáles de las confirmaciones hechas sobre archivos de prueba del código fuente de Git fueron enviadas por Junio Hamano, y no fueron uniones, en el mes de octubre de 2008, ejecutarías algo así:
646
+
647
+ $ git log --pretty="%h - %s" --author=gitster --since="2008-10-01" \
648
+ --before="2008-11-01" --no-merges -- t/
649
+ 5610e3b - Fix testcase failure when extended attribute
650
+ acd3b9e - Enhance hold_lock_file_for_{update,append}()
651
+ f563754 - demonstrate breakage of detached checkout wi
652
+ d1a43f2 - reset --hard/read-tree --reset -u: remove un
653
+ 51a94af - Fix "checkout --track -b newbranch" on detac
654
+ b0ad11e - pull: allow "git pull origin $something:$cur
655
+
656
+ De las casi 20.000 confirmaciones en la historia del código fuente de Git, este comando muestra las 6 que cumplen estas condiciones.
657
+
658
+ ### Usando un interfaz gráfico para visualizar el histórico ###
659
+
660
+ Si deseas utilizar una herramienta más gráfica para visualizar el histórico de confirmaciones, puede que quieras echarle un ojo a un programa Tcl/Tk llamado gitk que se distribuye junto con Git. Gitk es básicamente un `git log` visual, y acepta casi todas las opciones de filtrado que acepta `git log`. Si tecleas `gitk` en la línea de comandos dentro de tu proyecto, deberías ver algo como lo de la Figura 2-2.
661
+
662
+ Insert 18333fig0202.png
663
+ Figura 2-2. El visualizador de histórico gitk.
664
+
665
+ Puedes ver el histórico de confirmaciones en la mitad superior de la ventana, junto con un gráfico de ascendencia. El visor de diferencias de la mitad inferior muestra las modificaciones introducidas en cada confirmación que selecciones.
666
+
667
+ ## Deshaciendo cosas ##
668
+
669
+ En cualquier momento puedes querer deshacer algo. En esta sección veremos algunas herramientas básicas para deshacer cambios. Ten cuidado, porque no siempre puedes volver atrás después de algunas de estas operaciones. Ésta es una de las pocas áreas de Git que pueden provocar que pierdas datos si haces las cosas incorrectamente.
670
+
671
+ ### Modificando tu última confirmación ###
672
+
673
+ Uno de los casos más comunes en el que quieres deshacer cambios es cuando confirmas demasiado pronto y te olvidas de añadir algún archivo, o te confundes al introducir el mensaje de confirmación. Si quieres volver a hacer la confirmación, puedes ejecutar un `commit` con la opción `--amend`:
674
+
675
+ $ git commit --amend
676
+
677
+ Este comando utiliza lo que haya en tu área de preparación para la confirmación. Si no has hecho ningún cambio desde la última confirmación (por ejemplo, si ejecutas este comando justo después de tu confirmación anterior), esta instantánea será exactamente igual, y lo único que cambiarás será el mensaje de confirmación.
678
+
679
+ Se lanzará el editor de texto para que introduzcas tu mensaje, pero ya contendrá el mensaje de la confirmación anterior. Puedes editar el mensaje, igual que siempre, pero se sobreescribirá tu confirmación anterior.
680
+
681
+
682
+ Por ejemplo, si confirmas y luego te das cuenta de que se te olvidó preparar los cambios en uno de los archivos que querías añadir, puedes hacer algo así:
683
+
684
+ $ git commit -m 'initial commit'
685
+ $ git add forgotten_file
686
+ $ git commit --amend
687
+
688
+ Estos tres comandos acabarán convirtiéndose en una única confirmación —la segunda confirmación reemplazará los resultados de la primera.
689
+
690
+ ### Deshaciendo la preparación de un archivo ###
691
+
692
+ Las dos secciones siguientes muestran cómo trabajar con las modificaciones del área de preparación y del directorio de trabajo. Lo bueno es que el comando que usas para determinar el estado de ambas áreas te recuerda como deshacer sus modificaciones. Por ejemplo, digamos que has modificado dos archivos, y quieres confirmarlos como cambios separados, pero tecleas accidentalmente `git add *` y preparas ambos. ¿Cómo puedes sacar uno de ellos del área de preparación? El comando `git status` te lo recuerda:
693
+
694
+ $ git add .
695
+ $ git status
696
+ # On branch master
697
+ # Changes to be committed:
698
+ # (use "git reset HEAD <file>..." to unstage)
699
+ #
700
+ # modified: README.txt
701
+ # modified: benchmarks.rb
702
+ #
703
+
704
+ Justo debajo de la cabecera “Cambios a confirmar” (“Changes to be committed”), dice que uses `git reset HEAD <archivo>...` para sacar un archivo del área de preparación. Vamos a aplicar ese consejo sobre benchmarks.rb:
705
+
706
+ $ git reset HEAD benchmarks.rb
707
+ benchmarks.rb: locally modified
708
+ $ git status
709
+ # On branch master
710
+ # Changes to be committed:
711
+ # (use "git reset HEAD <file>..." to unstage)
712
+ #
713
+ # modified: README.txt
714
+ #
715
+ # Changes not staged for commit:
716
+ # (use "git add <file>..." to update what will be committed)
717
+ # (use "git checkout -- <file>..." to discard changes in working directory)
718
+ #
719
+ # modified: benchmarks.rb
720
+ #
721
+
722
+ El comando es un poco extraño, pero funciona. El archivo benchmarks.rb ahora está modificado, no preparado.
723
+
724
+ ### Deshaciendo la modificación de un archivo ###
725
+
726
+ ¿Qué pasa si te das cuenta de que no quieres mantener las modificaciones que has hecho sobre el archivo benchmarks.rb? ¿Cómo puedes deshacerlas fácilmente —revertir el archivo al mismo estado en el que estaba cuando hiciste tu última confirmación (o cuando clonaste el repositorio, o como quiera que metieses el archivo en tu directorio de trabajo)? Afortunadamente, `git status` también te dice como hacer esto. En la salida del último ejemplo, la cosa estaba así:
727
+
728
+ # Changes not staged for commit:
729
+ # (use "git add <file>..." to update what will be committed)
730
+ # (use "git checkout -- <file>..." to discard changes in working directory)
731
+ #
732
+ # modified: benchmarks.rb
733
+ #
734
+
735
+ Te dice de forma bastante explícita cómo descartar las modificaciones que hayas hecho (al menos las versiones de Git a partir de la 1.6.1 lo hacen —si tienes una versión más antigua, te recomendamos encarecidamente que la actualices para obtener algunas de estas mejoras de usabilidad). Vamos a hacer lo que dice:
736
+
737
+ $ git checkout -- benchmarks.rb
738
+ $ git status
739
+ # On branch master
740
+ # Changes to be committed:
741
+ # (use "git reset HEAD <file>..." to unstage)
742
+ #
743
+ # modified: README.txt
744
+ #
745
+
746
+ Puedes ver que se han revertido los cambios. También deberías ser consciente del peligro de este comando: cualquier modificación hecha sobre este archivo ha desaparecido —acabas de sobreescribirlo con otro archivo—. Nunca uses este comando a no ser que estés absolutamente seguro de que no quieres el archivo. Si lo único que necesitas es olvidarte de él momentáneamente, veremos los conceptos de apilamiento (stashing) y ramificación (branching) en el próximo capítulo; en general son formas más adecuadas de trabajar.
747
+
748
+ Recuerda, cualquier cosa que esté confirmada en Git casi siempre puede ser recuperada. Incluso confirmaciones sobre ramas que han sido eliminadas, o confirmaciones sobreescritas con la opción `--amend`, pueden recuperarse (véase el Capítulo 9 para conocer más sobre recuperación de datos). Sin embargo, cualquier cosa que pierdas y que no estuviese confirmada, probablemente no vuelvas a verla nunca más.
749
+
750
+ ## Trabajando con repositorios remotos ##
751
+
752
+ Para poder colaborar en cualquier proyecto Git, necesitas saber cómo gestionar tus repositorios remotos. Los repositorios remotos son versiones de tu proyecto que se encuentran alojados en Internet o en algún punto de la red. Puedes tener varios, cada uno de los cuales puede ser de sólo lectura, o de lectura/escritura, según los permisos que tengas. Colaborar con otros implica gestionar estos repositorios remotos, y mandar (push) y recibir (pull) datos de ellos cuando necesites compartir cosas.
753
+
754
+ Gestionar repositorios remotos implica conocer cómo añadir repositorios nuevos, eliminar aquellos que ya no son válidos, gestionar ramas remotas e indicar si están bajo seguimiento o no, y más cosas. En esta sección veremos todos estos conceptos.
755
+
756
+ ### Mostrando tus repositorios remotos ###
757
+
758
+ Para ver qué repositorios remotos tienes configurados, puedes ejecutar el comando `git remote`. Mostrará una lista con los nombres de los remotos que hayas especificado. Si has clonado tu repositorio, deberías ver por lo menos "origin" —es el nombre predeterminado que le da Git al servidor del que clonaste—:
759
+
760
+ $ git clone git://github.com/schacon/ticgit.git
761
+ Initialized empty Git repository in /private/tmp/ticgit/.git/
762
+ remote: Counting objects: 595, done.
763
+ remote: Compressing objects: 100% (269/269), done.
764
+ remote: Total 595 (delta 255), reused 589 (delta 253)
765
+ Receiving objects: 100% (595/595), 73.31 KiB | 1 KiB/s, done.
766
+ Resolving deltas: 100% (255/255), done.
767
+ $ cd ticgit
768
+ $ git remote
769
+ origin
770
+
771
+ También puedes añadir la opción `-v`, que muestra la URL asociada a cada repositorio remoto:
772
+
773
+ $ git remote -v
774
+ origin git://github.com/schacon/ticgit.git (fetch)
775
+ origin git://github.com/schacon/ticgit.git (push)
776
+
777
+ Si tienes más de un remoto, este comando los lista todos. Por ejemplo, mi repositorio Grit tiene esta pinta:
778
+
779
+ $ cd grit
780
+ $ git remote -v
781
+ bakkdoor git://github.com/bakkdoor/grit.git
782
+ cho45 git://github.com/cho45/grit.git
783
+ defunkt git://github.com/defunkt/grit.git
784
+ koke git://github.com/koke/grit.git
785
+ origin git@github.com:mojombo/grit.git
786
+
787
+ Esto significa que podemos recibir contribuciones de cualquiera de estos usuarios de manera bastante fácil. Pero fíjate en que sólo el remoto origen tiene una URL SSH, por lo que es el único al que podemos enviar (veremos el por qué en el Capítulo 4).
788
+
789
+ ### Añadiendo repositorios remotos ###
790
+
791
+ Ya he mencionado y he dado ejemplos de repositorios remotos en secciones anteriores, pero a continuación veremos cómo añadirlos explícitamente. Para añadir un nuevo repositorio Git remoto, asignándole un nombre con el que referenciarlo fácilmente, ejecuta `git remote add [nombre] [url]`:
792
+
793
+ $ git remote
794
+ origin
795
+ $ git remote add pb git://github.com/paulboone/ticgit.git
796
+ $ git remote -v
797
+ origin git://github.com/schacon/ticgit.git
798
+ pb git://github.com/paulboone/ticgit.git
799
+
800
+ Ahora puedes usar la cadena "pb" en la línea de comandos, en lugar de toda la URL. Por ejemplo, si quieres recuperar toda la información de Paul que todavía no tienes en tu repositorio, puedes ejecutar `git fetch pb`:
801
+
802
+ $ git fetch pb
803
+ remote: Counting objects: 58, done.
804
+ remote: Compressing objects: 100% (41/41), done.
805
+ remote: Total 44 (delta 24), reused 1 (delta 0)
806
+ Unpacking objects: 100% (44/44), done.
807
+ From git://github.com/paulboone/ticgit
808
+ * [new branch] master -> pb/master
809
+ * [new branch] ticgit -> pb/ticgit
810
+
811
+ La rama maestra de Paul es accesible localmente como `pb/master` —puedes unirla a una de tus ramas, o copiarla localmente para inspeccionarla.
812
+
813
+ ### Recibiendo de tus repositorios remotos ###
814
+
815
+ Como acabas de ver, para recuperar datos de tus repositorios remotos puedes ejecutar:
816
+
817
+ $ git fetch [remote-name]
818
+
819
+ Este comando recupera todos los datos del proyecto remoto que no tengas todavía. Después de hacer esto, deberías tener referencias a todas las ramas del repositorio remoto, que puedes unir o inspeccionar en cualquier momento. (Veremos qué son las ramas y cómo utilizarlas en más detalle en el Capítulo 3.)
820
+
821
+ Si clonas un repositorio, el comando añade automáticamente ese repositorio remoto con el nombre de "origin". Por tanto, `git fetch origin` recupera toda la información enviada a ese servidor desde que lo clonaste (o desde la última vez que ejecutaste `fetch`). Es importante tener en cuenta que el comando `fetch` sólo recupera la información y la pone en tu repositorio local —no la une automáticamente con tu trabajo ni modifica aquello en lo que estás trabajando. Tendrás que unir ambos manualmente a posteriori.
822
+
823
+ Si has configurado una rama para seguir otra rama remota (véase la siguiente sección y el Capítulo 3 para más información), puedes usar el comando `git pull` para recuperar y unir automáticamente la rama remota con tu rama actual. Éste puede resultarte un flujo de trabajo más sencillo y más cómodo; y por defecto, el comando `git clone` automáticamente configura tu rama local maestra para que siga la rama remota maestra del servidor del cual clonaste (asumiendo que el repositorio remoto tiene una rama maestra). Al ejecutar `git pull`, por lo general se recupera la información del servidor del que clonaste, y automáticamente se intenta unir con el código con el que estás trabajando actualmente.
824
+
825
+ ### Enviando a tus repositorios remotos ###
826
+
827
+ Cuando tu proyecto se encuentra en un estado que quieres compartir, tienes que enviarlo a un repositorio remoto. El comando que te permite hacer esto es sencillo: `git push [nombre-remoto][nombre-rama]`. Si quieres enviar tu rama maestra (`master`) a tu servidor origen (`origin`), ejecutarías esto para enviar tu trabajo al servidor:
828
+
829
+ $ git push origin master
830
+
831
+ Este comando funciona únicamente si has clonado de un servidor en el que tienes permiso de escritura, y nadie ha enviado información mientras tanto. Si tú y otra persona clonais a la vez, y él envía su información y luego envías tú la tuya, tu envío será rechazado. Tendrás que bajarte primero su trabajo e incorporarlo en el tuyo para que se te permita hacer un envío. Véase el Capítulo 3 para ver en detalle cómo enviar a servidores remotos.
832
+
833
+ ### Inspeccionando un repositorio remoto ###
834
+
835
+ Si quieres ver más información acerca de un repositorio remoto en particular, puedes usar el comando `git remote show [nombre]`. Si ejecutas este comando pasándole el nombre de un repositorio, como `origin`, obtienes algo así:
836
+
837
+ $ git remote show origin
838
+ * remote origin
839
+ URL: git://github.com/schacon/ticgit.git
840
+ Remote branch merged with 'git pull' while on branch master
841
+ master
842
+ Tracked remote branches
843
+ master
844
+ ticgit
845
+
846
+ Esto lista la URL del repositorio remoto, así como información sobre las ramas bajo seguimiento. Este comando te recuerda que si estás en la rama maestra y ejecutas `git pull`, automáticamente unirá los cambios a la rama maestra del remoto después de haber recuperado todas las referencias remotas. También lista todas las referencias remotas que ha recibido.
847
+
848
+ El anterior es un sencillo ejemplo que te encontrarás con frecuencia. Sin embargo, cuando uses Git de forma más avanzada, puede que `git remote show` muestre mucha más información:
849
+
850
+ $ git remote show origin
851
+ * remote origin
852
+ URL: git@github.com:defunkt/github.git
853
+ Remote branch merged with 'git pull' while on branch issues
854
+ issues
855
+ Remote branch merged with 'git pull' while on branch master
856
+ master
857
+ New remote branches (next fetch will store in remotes/origin)
858
+ caching
859
+ Stale tracking branches (use 'git remote prune')
860
+ libwalker
861
+ walker2
862
+ Tracked remote branches
863
+ acl
864
+ apiv2
865
+ dashboard2
866
+ issues
867
+ master
868
+ postgres
869
+ Local branch pushed with 'git push'
870
+ master:master
871
+
872
+ Este comando muestra qué rama se envía automáticamente cuando ejecutas `git push` en determinadas ramas. También te muestra qué ramas remotas no tienes todavía, qué ramas remotas tienes y han sido eliminadas del servidor, y múltiples ramas que serán unidas automáticamente cuando ejecutes `git pull`.
873
+
874
+ ### Eliminando y renombrando repositorios remotos ###
875
+
876
+ Si quieres renombrar una referencia a un repositorio remoto, en versiones recientes de Git puedes ejecutar `git remote rename`. Por ejemplo, si quieres renombrar `pb` a `paul`, puedes hacerlo de la siguiente manera:
877
+
878
+ $ git remote rename pb paul
879
+ $ git remote
880
+ origin
881
+ paul
882
+
883
+ Conviene mencionar que esto también cambia el nombre de tus ramas remotas. Lo que antes era referenciado en `pb/master` ahora está en `paul/master`.
884
+
885
+ Si por algún motivo quieres eliminar una referencia —has movido el servidor o ya no estás usando un determinado mirror, o quizás un contribuidor ha dejado de contribuir— puedes usar el comando `git remote rm`:
886
+
887
+ $ git remote rm paul
888
+ $ git remote
889
+ origin
890
+
891
+ ## Creando etiquetas ##
892
+
893
+ Como muchos VCSs, Git tiene la habilidad de etiquetar (tag) puntos específicos en la historia como importantes. Generalmente la gente usa esta funcionalidad para marcar puntos donde se ha lanzado alguna versión (v1.0, y así sucesivamente). En esta sección aprenderás cómo listar las etiquetas disponibles, crear nuevas etiquetas y qué tipos diferentes de etiquetas hay.
894
+
895
+ ### Listando tus etiquetas ###
896
+
897
+ Listar las etiquetas disponibles en Git es sencillo, Simplemente escribe `git tag`:
898
+
899
+ $ git tag
900
+ v0.1
901
+ v1.3
902
+
903
+ Este comando lista las etiquetas en orden alfabético; el orden en el que aparecen no es realmente importante.
904
+
905
+ También puedes buscar etiquetas de acuerdo a un patrón en particular. El repositorio fuente de Git, por ejemplo, contiene mas de 240 etiquetas. Si solo estás interesado en la serie 1.4.2, puedes ejecutar esto:
906
+
907
+ $ git tag -l 'v1.4.2.*'
908
+ v1.4.2.1
909
+ v1.4.2.2
910
+ v1.4.2.3
911
+ v1.4.2.4
912
+
913
+ ### Creando etiquetas ###
914
+
915
+ Git usa dos tipos principales de etiquetas: ligeras y anotadas. Una etiqueta ligera es muy parecida a una rama que no cambia —un puntero a una confirmación específica—. Sin embargo, las etiquetas anotadas son almacenadas como objetos completos en la base de datos de Git. Tienen suma de comprobación; contienen el nombre del etiquetador, correo electrónico y fecha; tienen mensaje de etiquetado; y pueden estar firmadas y verificadas con GNU Privacy Guard (GPG). Generalmente se recomienda crear etiquetas anotadas para disponer de toda esta información; pero si por alguna razón quieres una etiqueta temporal y no quieres almacenar el resto de información, también tiene disponibles las etiquetas ligeras.
916
+
917
+ ### Etiquetas anotadas ###
918
+
919
+ Crear una etiqueta anotada en Git es simple. La forma más fácil es especificar `-a` al ejecutar el comando `tag`:
920
+
921
+ $ git tag -a v1.4 -m 'my version 1.4'
922
+ $ git tag
923
+ v0.1
924
+ v1.3
925
+ v1.4
926
+
927
+ El parámetro `-m` especifica el mensaje, el cual se almacena con la etiqueta. Si no se especifica un mensaje para la etiqueta anotada, Git lanza tu editor para poder escribirlo.
928
+
929
+ Puedes ver los datos de la etiqueta junto con la confirmación que fue etiquetada usando el comando `git show`:
930
+
931
+ $ git show v1.4
932
+ tag v1.4
933
+ Tagger: Scott Chacon <schacon@gee-mail.com>
934
+ Date: Mon Feb 9 14:45:11 2009 -0800
935
+
936
+ my version 1.4
937
+ commit 15027957951b64cf874c3557a0f3547bd83b3ff6
938
+ Merge: 4a447f7... a6b4c97...
939
+ Author: Scott Chacon <schacon@gee-mail.com>
940
+ Date: Sun Feb 8 19:02:46 2009 -0800
941
+
942
+ Merge branch 'experiment'
943
+
944
+ Esto muestra la información del autor de la etiqueta, la fecha en la que la confirmación fue etiquetada, y el mensaje de anotación antes de mostrar la información de la confirmación.
945
+
946
+ ### Etiquetas firmadas ###
947
+
948
+ También puedes firmar tus etiquetas con GPG, siempre que tengas una clave privada. Lo único que debes hacer es usar `-s` en vez de `-a`:
949
+
950
+ $ git tag -s v1.5 -m 'my signed 1.5 tag'
951
+ You need a passphrase to unlock the secret key for
952
+ user: "Scott Chacon <schacon@gee-mail.com>"
953
+ 1024-bit DSA key, ID F721C45A, created 2009-02-09
954
+
955
+ Si ejecutas `git show` en esa etiqueta, puedes ver la firma GPG adjunta a ella:
956
+
957
+ $ git show v1.5
958
+ tag v1.5
959
+ Tagger: Scott Chacon <schacon@gee-mail.com>
960
+ Date: Mon Feb 9 15:22:20 2009 -0800
961
+
962
+ my signed 1.5 tag
963
+ -----BEGIN PGP SIGNATURE-----
964
+ Version: GnuPG v1.4.8 (Darwin)
965
+
966
+ iEYEABECAAYFAkmQurIACgkQON3DxfchxFr5cACeIMN+ZxLKggJQf0QYiQBwgySN
967
+ Ki0An2JeAVUCAiJ7Ox6ZEtK+NvZAj82/
968
+ =WryJ
969
+ -----END PGP SIGNATURE-----
970
+ commit 15027957951b64cf874c3557a0f3547bd83b3ff6
971
+ Merge: 4a447f7... a6b4c97...
972
+ Author: Scott Chacon <schacon@gee-mail.com>
973
+ Date: Sun Feb 8 19:02:46 2009 -0800
974
+
975
+ Merge branch 'experiment'
976
+
977
+ Más tarde, aprenderás cómo verificar etiquetas firmadas.
978
+
979
+ ### Etiquetas ligeras ###
980
+
981
+ Otra forma de etiquetar confirmaciones es con una etiqueta ligera. Esto es básicamente la suma de comprobación de la confirmación almacenada en un archivo —ninguna otra información es guardada—. Para crear una etiqueta ligera no añadas las opciones `-a`, `-s` o `-m`:
982
+
983
+ $ git tag v1.4-lw
984
+ $ git tag
985
+ v0.1
986
+ v1.3
987
+ v1.4
988
+ v1.4-lw
989
+ v1.5
990
+
991
+ Esta vez, si ejecutas el comando `git show` en la etiqueta, no verás ninguna información extra. El comando simplemente muestra la confirmación.
992
+
993
+ $ git show v1.4-lw
994
+ commit 15027957951b64cf874c3557a0f3547bd83b3ff6
995
+ Merge: 4a447f7... a6b4c97...
996
+ Author: Scott Chacon <schacon@gee-mail.com>
997
+ Date: Sun Feb 8 19:02:46 2009 -0800
998
+
999
+ Merge branch 'experiment'
1000
+
1001
+ ### Verificando etiquetas ###
1002
+
1003
+ Para verificar una etiqueta firmada, debes usar `git tag -v [tag-name]`. Este comando utiliza GPG para verificar la firma. Necesitas la clave pública del autor de la firma en tu llavero para que funcione correctamente.
1004
+
1005
+ $ git tag -v v1.4.2.1
1006
+ object 883653babd8ee7ea23e6a5c392bb739348b1eb61
1007
+ type commit
1008
+ tag v1.4.2.1
1009
+ tagger Junio C Hamano <junkio@cox.net> 1158138501 -0700
1010
+
1011
+ GIT 1.4.2.1
1012
+
1013
+ Minor fixes since 1.4.2, including git-mv and git-http with alternates.
1014
+ gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
1015
+ gpg: Good signature from "Junio C Hamano <junkio@cox.net>"
1016
+ gpg: aka "[jpeg image of size 1513]"
1017
+ Primary key fingerprint: 3565 2A26 2040 E066 C9A7 4A7D C0C6 D9A4 F311 9B9A
1018
+
1019
+ Si no tienes la clave pública del autor de la firma, se obtiene algo parecido a:
1020
+
1021
+ gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
1022
+ gpg: Can't check signature: public key not found
1023
+ error: could not verify the tag 'v1.4.2.1'
1024
+
1025
+ ### Etiquetando más tarde ###
1026
+
1027
+ Puedes incluso etiquetar confirmaciones después de avanzar sobre ellas. Supón que tu historico de confirmaciones se parece a esto:
1028
+
1029
+ $ git log --pretty=oneline
1030
+ 15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
1031
+ a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support
1032
+ 0d52aaab4479697da7686c15f77a3d64d9165190 one more thing
1033
+ 6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'experiment'
1034
+ 0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc added a commit function
1035
+ 4682c3261057305bdd616e23b64b0857d832627b added a todo file
1036
+ 166ae0c4d3f420721acbb115cc33848dfcc2121a started write support
1037
+ 9fceb02d0ae598e95dc970b74767f19372d61af8 updated rakefile
1038
+ 964f16d36dfccde844893cac5b347e7b3d44abbc commit the todo
1039
+ 8a5cbc430f1a9c3d00faaeffd07798508422908a updated readme
1040
+
1041
+ Ahora, supón que olvidaste etiquetar el proyecto en v1.2, que estaba en la confirmación "updated rakefile". Puedes hacerlo ahora. Para etiquetar esa confirmación especifica la suma de comprobación de la confirmación (o una parte de la misma) al final del comando:
1042
+
1043
+ $ git tag -a v1.2 -m 'version 1.2' 9fceb02
1044
+
1045
+ Puedes ver que has etiquetado la confirmación:
1046
+
1047
+ $ git tag
1048
+ v0.1
1049
+ v1.2
1050
+ v1.3
1051
+ v1.4
1052
+ v1.4-lw
1053
+ v1.5
1054
+
1055
+ $ git show v1.2
1056
+ tag v1.2
1057
+ Tagger: Scott Chacon <schacon@gee-mail.com>
1058
+ Date: Mon Feb 9 15:32:16 2009 -0800
1059
+
1060
+ version 1.2
1061
+ commit 9fceb02d0ae598e95dc970b74767f19372d61af8
1062
+ Author: Magnus Chacon <mchacon@gee-mail.com>
1063
+ Date: Sun Apr 27 20:43:35 2008 -0700
1064
+
1065
+ updated rakefile
1066
+ ...
1067
+
1068
+ ### Compartiendo etiquetas ###
1069
+
1070
+ Por defecto, el comando `git push` no transfiere etiquetas a servidores remotos. Tienes que enviarlas explicitamente a un servidor compartido después de haberlas creado. Este proceso es igual a compartir ramas remotas —puedes ejecutar `git push origin [tagname]`.
1071
+
1072
+ $ git push origin v1.5
1073
+ Counting objects: 50, done.
1074
+ Compressing objects: 100% (38/38), done.
1075
+ Writing objects: 100% (44/44), 4.56 KiB, done.
1076
+ Total 44 (delta 18), reused 8 (delta 1)
1077
+ To git@github.com:schacon/simplegit.git
1078
+ * [new tag] v1.5 -> v1.5
1079
+
1080
+ Si tienes un montón de etiquetas que quieres enviar a la vez, también puedes usar la opción `--tags` en el comando `git push`. Esto transfiere todas tus etiquetas que no estén ya en el servidor remoto.
1081
+
1082
+ $ git push origin --tags
1083
+ Counting objects: 50, done.
1084
+ Compressing objects: 100% (38/38), done.
1085
+ Writing objects: 100% (44/44), 4.56 KiB, done.
1086
+ Total 44 (delta 18), reused 8 (delta 1)
1087
+ To git@github.com:schacon/simplegit.git
1088
+ * [new tag] v0.1 -> v0.1
1089
+ * [new tag] v1.2 -> v1.2
1090
+ * [new tag] v1.4 -> v1.4
1091
+ * [new tag] v1.4-lw -> v1.4-lw
1092
+ * [new tag] v1.5 -> v1.5
1093
+
1094
+ Ahora, cuando alguien clone o reciba de tu repositorio, obtendrá también todas tus etiquetas.
1095
+
1096
+ ## Consejos y trucos ##
1097
+
1098
+ Antes de que terminemos este capitulo de Git básico, unos pocos trucos y consejos que harán de tu experiencia con Git más sencilla, fácil, o más familiar. Mucha gente usa Git sin usar ninguno de estos consejos, y no nos referiremos a ellos o asumiremos que los has usado más tarde en el libro, pero probablemente debas saber cómo hacerlos.
1099
+
1100
+ ### Autocompletado ###
1101
+
1102
+ Si usas el shell Bash, Git viene con un buen script de autocompletado que puedes activar. Descárgalo directamente desde el código fuente de Git en `https://github.com/git/git/blob/master/contrib/completion/git-completion.bash`, copia este fichero en tu directorio `home` y añade esto a tu archivo `.bashrc`:
1103
+
1104
+ source ~/git-completion.bash
1105
+
1106
+ Si quieres que Git tenga automáticamente autocompletado para todos los usuarios, copia este script en el directorio `/opt/local/etc/bash_completion.d` en sistemas Mac, o en el directorio `/etc/bash_completion.d/` en sistemas Linux. Este es un directorio de scripts que Bash cargará automáticamente para proveer de autocompletado.
1107
+
1108
+ Si estás usando Windows con el Bash de Git, el cual es el predeterminado cuando instalas Git en Windows con msysGit, el autocompletado debería estar preconfigurado.
1109
+
1110
+ Presiona el tabulador cuando estés escribiendo un comando de Git, y deberían aparecer un conjunto de sugerencias para que escojas:
1111
+
1112
+ $ git co<tab><tab>
1113
+ commit config
1114
+
1115
+ En este caso, escribiendo `git co` y presionando el tabulador dos veces sugiere `commit` y `config`. Añadiendo `m` y pulsando el tabulador completa `git commit` automáticamente.
1116
+
1117
+ Esto también funciona con opciones, que probablemente es más útil. Por ejemplo, si quieres ejecutar `git log` y no recuerdas una de las opciones, puedes empezar a escribirla y presionar el tabulador para ver qué coincide:
1118
+
1119
+ $ git log --s<tab>
1120
+ --shortstat --since= --src-prefix= --stat --summary
1121
+
1122
+ Es un pequeño truco que puede guardarte algún tiempo y lectura de documentación.
1123
+
1124
+ ### Alias de Git ###
1125
+
1126
+ Git no infiere tu comando si lo escribes parcialmente. Si no quieres escribir el texto entero de cada uno de los comandos de Git, puedes establecer fácilmente un alias para cada comando usando `git config`. Aquí hay un par de ejemplos que tal vez quieras establecer:
1127
+
1128
+ $ git config --global alias.co checkout
1129
+ $ git config --global alias.br branch
1130
+ $ git config --global alias.ci commit
1131
+ $ git config --global alias.st status
1132
+
1133
+ Esto significa que, por ejemplo, en vez de escribir `git commit`, simplemente necesitas escribir `git ci`. A medida que uses Git, probablemente uses otros comandos de forma frecuente. En este caso no dudes en crear nuevos alias.
1134
+
1135
+ Esta técnica también puede ser muy útil para crear comandos que creas que deben existir. Por ejemplo, para corregir el problema de usabilidad que encontramos al quitar del área de preparación un archivo, puedes añadir tu propio alias:
1136
+
1137
+ $ git config --global alias.unstage 'reset HEAD --'
1138
+
1139
+ Esto hace los siguientes dos comandos equivalentes:
1140
+
1141
+ $ git unstage fileA
1142
+ $ git reset HEAD fileA
1143
+
1144
+ Esto parece un poco mas claro. También es común añadir un comando `last`, tal que así:
1145
+
1146
+ $ git config --global alias.last 'log -1 HEAD'
1147
+
1148
+ De esta forma puedes ver la última confirmación fácilmente:
1149
+
1150
+ $ git last
1151
+ commit 66938dae3329c7aebe598c2246a8e6af90d04646
1152
+ Author: Josh Goebel <dreamer3@example.com>
1153
+ Date: Tue Aug 26 19:48:51 2008 +0800
1154
+
1155
+ test for current head
1156
+
1157
+ Signed-off-by: Scott Chacon <schacon@example.com>
1158
+
1159
+ Como puedes ver, Git simplemente reemplaza el nuevo comando con lo que le pongas como alias. Sin embargo, tal vez quieres ejecutar un comando externo en lugar de un subcomando de Git. En este caso, empieza el comando con el caracter `!`. Esto es útil si escribes tus propias herramientas que trabajan con un repositorio de Git. Podemos demostrarlo creando el alias `git visual` para ejecutar `gitk`:
1160
+
1161
+ $ git config --global alias.visual '!gitk'
1162
+
1163
+ ## Resumen ##
1164
+
1165
+ En este punto puedes hacer todas las operaciones básicas de Git a nivel local —crear o clonar un repositorio, hacer cambios, preparar y confirmar esos cambios y ver la historia de los cambios en el repositorio—. A continuación cubriremos la mejor característica de Git: su modelo de ramas.