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.
- checksums.yaml +4 -4
- data/Gemfile +3 -2
- data/README.md +67 -42
- data/Rakefile +22 -2
- data/commonmarker.gemspec +13 -9
- data/ext/commonmarker/cmark/api_test/main.c +35 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/CMakeError.log +12 -12
- data/ext/commonmarker/cmark/build/CMakeFiles/CMakeOutput.log +141 -141
- data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/main.c.o +0 -0
- data/ext/commonmarker/cmark/build/api_test/api_test +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/houdini_html_u.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/iterator.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/houdini_html_u.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/iterator.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/houdini_html_u.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/iterator.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/cmark +0 -0
- data/ext/commonmarker/cmark/build/src/libcmark.0.19.0.dylib +0 -0
- data/ext/commonmarker/cmark/build/src/libcmark.a +0 -0
- data/ext/commonmarker/cmark/build/src/libcmark.dylib +0 -0
- data/ext/commonmarker/cmark/src/houdini_html_u.c +26 -13
- data/ext/commonmarker/cmark/src/iterator.c +2 -2
- data/ext/commonmarker/cmark/test/__pycache__/cmark.cpython-34.pyc +0 -0
- data/ext/commonmarker/cmark/test/__pycache__/normalize.cpython-34.pyc +0 -0
- data/ext/commonmarker/cmark/test/cmark.pyc +0 -0
- data/ext/commonmarker/cmark/test/normalize.pyc +0 -0
- data/ext/commonmarker/commonmarker.c +276 -3
- data/ext/commonmarker/extconf.rb +3 -1
- data/lib/commonmarker.rb +70 -360
- data/lib/commonmarker/config.rb +1 -1
- data/lib/commonmarker/renderer.rb +91 -0
- data/lib/commonmarker/renderer/html_renderer.rb +149 -0
- data/lib/commonmarker/version.rb +1 -1
- data/test/benchinput.md +148414 -0
- data/test/benchmark.rb +13 -9
- data/test/progit/Gemfile +5 -0
- data/test/progit/README.md +9 -0
- data/test/progit/README.original.md +70 -0
- data/test/progit/Rakefile +285 -0
- data/test/progit/ar/01-introduction/01-chapter1.markdown +264 -0
- data/test/progit/ar/02-git-basics/01-chapter2.markdown +1124 -0
- data/test/progit/ar/NOTES +18 -0
- data/test/progit/ar/README +14 -0
- data/test/progit/az/01-introduction/01-chapter1.markdown +257 -0
- data/test/progit/az/02-git-basics/01-chapter2.markdown +1127 -0
- data/test/progit/az/03-git-branching/01-chapter3.markdown +598 -0
- data/test/progit/az/04-git-server/01-chapter4.markdown +861 -0
- data/test/progit/az/05-distributed-git/01-chapter5.markdown +897 -0
- data/test/progit/az/06-git-tools/01-chapter6.markdown +1126 -0
- data/test/progit/az/07-customizing-git/01-chapter7.markdown +937 -0
- data/test/progit/az/08-git-and-other-scms/01-chapter8.markdown +690 -0
- data/test/progit/az/09-git-internals/01-chapter9.markdown +977 -0
- data/test/progit/be/01-introduction/01-chapter1.markdown +257 -0
- data/test/progit/be/02-git-basics/01-chapter2.markdown +1126 -0
- data/test/progit/ca/01-introduction/01-chapter1.markdown +257 -0
- data/test/progit/ca/README.txt +1 -0
- data/test/progit/couchapp/Makefile +41 -0
- data/test/progit/couchapp/Readme.md +17 -0
- data/test/progit/couchapp/_id +1 -0
- data/test/progit/couchapp/shows/chapter.js +14 -0
- data/test/progit/couchapp/templates/foot.html +7 -0
- data/test/progit/couchapp/templates/head.html +51 -0
- data/test/progit/couchapp/vendor/markdown/showdown.js +420 -0
- data/test/progit/couchapp/vendor/mustache.js/mustache.js +302 -0
- data/test/progit/cs/01-introduction/01-chapter1.markdown +259 -0
- data/test/progit/cs/02-git-basics/01-chapter2.markdown +1225 -0
- data/test/progit/cs/03-git-branching/01-chapter3.markdown +606 -0
- data/test/progit/cs/04-git-server/01-chapter4.markdown +871 -0
- data/test/progit/cs/05-distributed-git/01-chapter5.markdown +914 -0
- data/test/progit/cs/06-git-tools/01-chapter6.markdown +1167 -0
- data/test/progit/cs/07-customizing-git/01-chapter7.markdown +940 -0
- data/test/progit/cs/08-git-and-other-scms/01-chapter8.markdown +700 -0
- data/test/progit/cs/09-git-internals/01-chapter9.markdown +1014 -0
- data/test/progit/de/01-introduction/01-chapter1.markdown +445 -0
- data/test/progit/de/02-git-basics/01-chapter2.markdown +1589 -0
- data/test/progit/de/03-git-branching/01-chapter3.markdown +964 -0
- data/test/progit/de/04-git-server/01-chapter4.markdown +1337 -0
- data/test/progit/de/05-distributed-git/01-chapter5.markdown +1329 -0
- data/test/progit/de/06-git-tools/01-chapter6.markdown +1502 -0
- data/test/progit/de/07-customizing-git/01-chapter7.markdown +1361 -0
- data/test/progit/de/08-git-and-other-scms/01-chapter8.markdown +919 -0
- data/test/progit/de/09-git-internals/01-chapter9.markdown +1361 -0
- data/test/progit/de/README.md +626 -0
- data/test/progit/ebooks/cover.png +0 -0
- data/test/progit/en/01-introduction/01-chapter1.markdown +263 -0
- data/test/progit/en/02-git-basics/01-chapter2.markdown +1228 -0
- data/test/progit/en/03-git-branching/01-chapter3.markdown +606 -0
- data/test/progit/en/04-git-server/01-chapter4.markdown +871 -0
- data/test/progit/en/05-distributed-git/01-chapter5.markdown +914 -0
- data/test/progit/en/06-git-tools/01-chapter6.markdown +1150 -0
- data/test/progit/en/07-customizing-git/01-chapter7.markdown +940 -0
- data/test/progit/en/08-git-and-other-scms/01-chapter8.markdown +700 -0
- data/test/progit/en/09-git-internals/01-chapter9.markdown +983 -0
- data/test/progit/eo/01-introduction/01-chapter1.markdown +257 -0
- data/test/progit/eo/02-git-basics/01-chapter2.markdown +1171 -0
- data/test/progit/epub/ProGit.css +28 -0
- data/test/progit/epub/title.png +0 -0
- data/test/progit/es-ni/01-introduction/01-chapter1.markdown +257 -0
- data/test/progit/es-ni/02-git-basics/01-chapter2.markdown +1127 -0
- data/test/progit/es/01-introduction/01-chapter1.markdown +262 -0
- data/test/progit/es/02-git-basics/01-chapter2.markdown +1165 -0
- data/test/progit/es/03-git-branching/01-chapter3.markdown +598 -0
- data/test/progit/es/04-git-server/01-chapter4.markdown +707 -0
- data/test/progit/es/05-distributed-git/01-chapter5.markdown +890 -0
- data/test/progit/es/06-git-tools/01-chapter6.markdown +1113 -0
- data/test/progit/es/07-customizing-git/01-chapter7.markdown +875 -0
- data/test/progit/es/08-git-and-other-scms/01-chapter8.markdown +686 -0
- data/test/progit/es/09-git-internals/01-chapter9.markdown +976 -0
- data/test/progit/es/NOTES +29 -0
- data/test/progit/es/README +3 -0
- data/test/progit/es/glosario-Benzirpi.txt +27 -0
- data/test/progit/es/omegat-Benzirpi.tmx +29075 -0
- data/test/progit/fa/01-introduction/01-chapter1.markdown +262 -0
- data/test/progit/fa/03-git-branching/01-chapter3.markdown +608 -0
- data/test/progit/fa/04-git-server/01-chapter4.markdown +872 -0
- data/test/progit/fa/NOTES.en-fa.md +143 -0
- data/test/progit/fa/README.md +7 -0
- data/test/progit/fi/01-introduction/01-chapter1.markdown +259 -0
- data/test/progit/fi/02-git-basics/01-chapter2.markdown +1171 -0
- data/test/progit/fi/NOTES +5 -0
- data/test/progit/figures-dia/fig0101.dia +617 -0
- data/test/progit/figures-dia/fig0102.dia +921 -0
- data/test/progit/figures-dia/fig0103.dia +1468 -0
- data/test/progit/figures-dia/fig0104.dia +1432 -0
- data/test/progit/figures-dia/fig0105.dia +1924 -0
- data/test/progit/figures-dia/fig0106.dia +562 -0
- data/test/progit/figures-dia/fig0201.dia +774 -0
- data/test/progit/figures-dia/fig0301.dia +2006 -0
- data/test/progit/figures-dia/fig0302.dia +2148 -0
- data/test/progit/figures-dia/fig0303.dia +719 -0
- data/test/progit/figures-dia/fig0304.dia +525 -0
- data/test/progit/figures-dia/fig0305.dia +622 -0
- data/test/progit/figures-dia/fig0306.dia +622 -0
- data/test/progit/figures-dia/fig0307.dia +719 -0
- data/test/progit/figures-dia/fig0308.dia +734 -0
- data/test/progit/figures-dia/fig0309.dia +831 -0
- data/test/progit/figures-dia/fig0310.dia +412 -0
- data/test/progit/figures-dia/fig0311.dia +493 -0
- data/test/progit/figures-dia/fig0312.dia +596 -0
- data/test/progit/figures-dia/fig0313.dia +774 -0
- data/test/progit/figures-dia/fig0314.dia +846 -0
- data/test/progit/figures-dia/fig0315.dia +787 -0
- data/test/progit/figures-dia/fig0316.dia +1078 -0
- data/test/progit/figures-dia/fig0317.dia +881 -0
- data/test/progit/figures-dia/fig0318.dia +968 -0
- data/test/progit/figures-dia/fig0319.dia +957 -0
- data/test/progit/figures-dia/fig0320.dia +1637 -0
- data/test/progit/figures-dia/fig0321.dia +1494 -0
- data/test/progit/figures-dia/fig0322.dia +1142 -0
- data/test/progit/figures-dia/fig0323.dia +1377 -0
- data/test/progit/figures-dia/fig0324.dia +1603 -0
- data/test/progit/figures-dia/fig0325.dia +2003 -0
- data/test/progit/figures-dia/fig0326.dia +2013 -0
- data/test/progit/figures-dia/fig0327.dia +687 -0
- data/test/progit/figures-dia/fig0328.dia +814 -0
- data/test/progit/figures-dia/fig0329.dia +793 -0
- data/test/progit/figures-dia/fig0330.dia +693 -0
- data/test/progit/figures-dia/fig0331.dia +1159 -0
- data/test/progit/figures-dia/fig0332.dia +1362 -0
- data/test/progit/figures-dia/fig0333.dia +1165 -0
- data/test/progit/figures-dia/fig0334.dia +1450 -0
- data/test/progit/figures-dia/fig0335.dia +994 -0
- data/test/progit/figures-dia/fig0336.dia +786 -0
- data/test/progit/figures-dia/fig0337.dia +1546 -0
- data/test/progit/figures-dia/fig0338.dia +1755 -0
- data/test/progit/figures-dia/fig0339.dia +1882 -0
- data/test/progit/figures-dia/fig0501.dia +456 -0
- data/test/progit/figures-dia/fig0502.dia +956 -0
- data/test/progit/figures-dia/fig0503.dia +915 -0
- data/test/progit/figures-dia/fig0504.dia +620 -0
- data/test/progit/figures-dia/fig0505.dia +744 -0
- data/test/progit/figures-dia/fig0506.dia +747 -0
- data/test/progit/figures-dia/fig0507.dia +895 -0
- data/test/progit/figures-dia/fig0508.dia +1122 -0
- data/test/progit/figures-dia/fig0509.dia +1243 -0
- data/test/progit/figures-dia/fig0510.dia +1240 -0
- data/test/progit/figures-dia/fig0511.dia +1201 -0
- data/test/progit/figures-dia/fig0512.dia +801 -0
- data/test/progit/figures-dia/fig0513.dia +1387 -0
- data/test/progit/figures-dia/fig0514.dia +1568 -0
- data/test/progit/figures-dia/fig0515.dia +1721 -0
- data/test/progit/figures-dia/fig0516.dia +997 -0
- data/test/progit/figures-dia/fig0517.dia +994 -0
- data/test/progit/figures-dia/fig0518.dia +1145 -0
- data/test/progit/figures-dia/fig0519.dia +992 -0
- data/test/progit/figures-dia/fig0520.dia +1240 -0
- data/test/progit/figures-dia/fig0521.dia +801 -0
- data/test/progit/figures-dia/fig0522.dia +922 -0
- data/test/progit/figures-dia/fig0523.dia +922 -0
- data/test/progit/figures-dia/fig0524.dia +1828 -0
- data/test/progit/figures-dia/fig0525.dia +2685 -0
- data/test/progit/figures-dia/fig0526.dia +717 -0
- data/test/progit/figures-dia/fig0527.dia +856 -0
- data/test/progit/figures-dia/fig0601.dia +790 -0
- data/test/progit/figures-dia/fig0702.dia +795 -0
- data/test/progit/figures-dia/fig0703.dia +795 -0
- data/test/progit/figures-dia/fig0901.dia +669 -0
- data/test/progit/figures-dia/fig0902.dia +834 -0
- data/test/progit/figures-dia/fig0903.dia +1483 -0
- data/test/progit/figures-dia/fig0904.dia +1728 -0
- data/test/progit/figures-dia/makeimages +25 -0
- data/test/progit/figures-source/progit.graffle +123108 -0
- data/test/progit/figures/18333fig0101-tn.png +0 -0
- data/test/progit/figures/18333fig0102-tn.png +0 -0
- data/test/progit/figures/18333fig0103-tn.png +0 -0
- data/test/progit/figures/18333fig0104-tn.png +0 -0
- data/test/progit/figures/18333fig0105-tn.png +0 -0
- data/test/progit/figures/18333fig0106-tn.png +0 -0
- data/test/progit/figures/18333fig0107-tn.png +0 -0
- data/test/progit/figures/18333fig0201-tn.png +0 -0
- data/test/progit/figures/18333fig0202-tn.png +0 -0
- data/test/progit/figures/18333fig0301-tn.png +0 -0
- data/test/progit/figures/18333fig0302-tn.png +0 -0
- data/test/progit/figures/18333fig0303-tn.png +0 -0
- data/test/progit/figures/18333fig0304-tn.png +0 -0
- data/test/progit/figures/18333fig0305-tn.png +0 -0
- data/test/progit/figures/18333fig0306-tn.png +0 -0
- data/test/progit/figures/18333fig0307-tn.png +0 -0
- data/test/progit/figures/18333fig0308-tn.png +0 -0
- data/test/progit/figures/18333fig0309-tn.png +0 -0
- data/test/progit/figures/18333fig0310-tn.png +0 -0
- data/test/progit/figures/18333fig0311-tn.png +0 -0
- data/test/progit/figures/18333fig0312-tn.png +0 -0
- data/test/progit/figures/18333fig0313-tn.png +0 -0
- data/test/progit/figures/18333fig0314-tn.png +0 -0
- data/test/progit/figures/18333fig0315-tn.png +0 -0
- data/test/progit/figures/18333fig0316-tn.png +0 -0
- data/test/progit/figures/18333fig0317-tn.png +0 -0
- data/test/progit/figures/18333fig0318-tn.png +0 -0
- data/test/progit/figures/18333fig0319-tn.png +0 -0
- data/test/progit/figures/18333fig0320-tn.png +0 -0
- data/test/progit/figures/18333fig0321-tn.png +0 -0
- data/test/progit/figures/18333fig0322-tn.png +0 -0
- data/test/progit/figures/18333fig0323-tn.png +0 -0
- data/test/progit/figures/18333fig0324-tn.png +0 -0
- data/test/progit/figures/18333fig0325-tn.png +0 -0
- data/test/progit/figures/18333fig0326-tn.png +0 -0
- data/test/progit/figures/18333fig0327-tn.png +0 -0
- data/test/progit/figures/18333fig0328-tn.png +0 -0
- data/test/progit/figures/18333fig0329-tn.png +0 -0
- data/test/progit/figures/18333fig0330-tn.png +0 -0
- data/test/progit/figures/18333fig0331-tn.png +0 -0
- data/test/progit/figures/18333fig0332-tn.png +0 -0
- data/test/progit/figures/18333fig0333-tn.png +0 -0
- data/test/progit/figures/18333fig0334-tn.png +0 -0
- data/test/progit/figures/18333fig0335-tn.png +0 -0
- data/test/progit/figures/18333fig0336-tn.png +0 -0
- data/test/progit/figures/18333fig0337-tn.png +0 -0
- data/test/progit/figures/18333fig0338-tn.png +0 -0
- data/test/progit/figures/18333fig0339-tn.png +0 -0
- data/test/progit/figures/18333fig0401-tn.png +0 -0
- data/test/progit/figures/18333fig0402-tn.png +0 -0
- data/test/progit/figures/18333fig0403-tn.png +0 -0
- data/test/progit/figures/18333fig0404-tn.png +0 -0
- data/test/progit/figures/18333fig0405-tn.png +0 -0
- data/test/progit/figures/18333fig0406-tn.png +0 -0
- data/test/progit/figures/18333fig0407-tn.png +0 -0
- data/test/progit/figures/18333fig0408-tn.png +0 -0
- data/test/progit/figures/18333fig0409-tn.png +0 -0
- data/test/progit/figures/18333fig0410-tn.png +0 -0
- data/test/progit/figures/18333fig0411-tn.png +0 -0
- data/test/progit/figures/18333fig0412-tn.png +0 -0
- data/test/progit/figures/18333fig0413-tn.png +0 -0
- data/test/progit/figures/18333fig0414-tn.png +0 -0
- data/test/progit/figures/18333fig0415-tn.png +0 -0
- data/test/progit/figures/18333fig0501-tn.png +0 -0
- data/test/progit/figures/18333fig0502-tn.png +0 -0
- data/test/progit/figures/18333fig0503-tn.png +0 -0
- data/test/progit/figures/18333fig0504-tn.png +0 -0
- data/test/progit/figures/18333fig0505-tn.png +0 -0
- data/test/progit/figures/18333fig0506-tn.png +0 -0
- data/test/progit/figures/18333fig0507-tn.png +0 -0
- data/test/progit/figures/18333fig0508-tn.png +0 -0
- data/test/progit/figures/18333fig0509-tn.png +0 -0
- data/test/progit/figures/18333fig0510-tn.png +0 -0
- data/test/progit/figures/18333fig0511-tn.png +0 -0
- data/test/progit/figures/18333fig0512-tn.png +0 -0
- data/test/progit/figures/18333fig0513-tn.png +0 -0
- data/test/progit/figures/18333fig0514-tn.png +0 -0
- data/test/progit/figures/18333fig0515-tn.png +0 -0
- data/test/progit/figures/18333fig0516-tn.png +0 -0
- data/test/progit/figures/18333fig0517-tn.png +0 -0
- data/test/progit/figures/18333fig0518-tn.png +0 -0
- data/test/progit/figures/18333fig0519-tn.png +0 -0
- data/test/progit/figures/18333fig0520-tn.png +0 -0
- data/test/progit/figures/18333fig0521-tn.png +0 -0
- data/test/progit/figures/18333fig0522-tn.png +0 -0
- data/test/progit/figures/18333fig0523-tn.png +0 -0
- data/test/progit/figures/18333fig0524-tn.png +0 -0
- data/test/progit/figures/18333fig0525-tn.png +0 -0
- data/test/progit/figures/18333fig0526-tn.png +0 -0
- data/test/progit/figures/18333fig0527-tn.png +0 -0
- data/test/progit/figures/18333fig0601-tn.png +0 -0
- data/test/progit/figures/18333fig0701-tn.png +0 -0
- data/test/progit/figures/18333fig0702-tn.png +0 -0
- data/test/progit/figures/18333fig0703-tn.png +0 -0
- data/test/progit/figures/18333fig0901-tn.png +0 -0
- data/test/progit/figures/18333fig0902-tn.png +0 -0
- data/test/progit/figures/18333fig0903-tn.png +0 -0
- data/test/progit/figures/18333fig0904-tn.png +0 -0
- data/test/progit/fr/01-introduction/01-chapter1.markdown +371 -0
- data/test/progit/fr/02-git-basics/01-chapter2.markdown +1378 -0
- data/test/progit/fr/03-git-branching/01-chapter3.markdown +781 -0
- data/test/progit/fr/04-git-server/01-chapter4.markdown +1141 -0
- data/test/progit/fr/05-distributed-git/01-chapter5.markdown +1163 -0
- data/test/progit/fr/06-git-tools/01-chapter6.markdown +1356 -0
- data/test/progit/fr/07-customizing-git/01-chapter7.markdown +1200 -0
- data/test/progit/fr/08-git-and-other-scms/01-chapter8.markdown +832 -0
- data/test/progit/fr/09-git-internals/01-chapter9.markdown +1228 -0
- data/test/progit/fr/NOTES.fr-fr.markdown +1 -0
- data/test/progit/fr/NOTES.fr-fr.md +127 -0
- data/test/progit/fr/README.md +43 -0
- data/test/progit/fr/glossaire-git.adoc +108 -0
- data/test/progit/hi/01-introduction/01-chapter1.markdown +7 -0
- data/test/progit/hu/01-introduction/01-chapter1.markdown +257 -0
- data/test/progit/id/01-introduction/01-chapter1.markdown +257 -0
- data/test/progit/id/02-git-basics/01-chapter2.markdown +1127 -0
- data/test/progit/id/03-git-branching/01-chapter3.markdown +598 -0
- data/test/progit/it/01-introduction/01-chapter1.markdown +263 -0
- data/test/progit/it/02-git-basics/01-chapter2.markdown +1227 -0
- data/test/progit/it/03-git-branching/01-chapter3.markdown +598 -0
- data/test/progit/it/04-git-server/01-chapter4.markdown +864 -0
- data/test/progit/it/05-distributed-git/01-chapter5.markdown +897 -0
- data/test/progit/it/06-git-tools/01-chapter6.markdown +1144 -0
- data/test/progit/it/07-customizing-git/01-chapter7.markdown +606 -0
- data/test/progit/it/08-git-and-other-scms/01-chapter8.markdown +707 -0
- data/test/progit/it/09-git-internals/01-chapter9.markdown +1000 -0
- data/test/progit/ja/01-introduction/01-chapter1.markdown +260 -0
- data/test/progit/ja/02-git-basics/01-chapter2.markdown +1221 -0
- data/test/progit/ja/03-git-branching/01-chapter3.markdown +604 -0
- data/test/progit/ja/04-git-server/01-chapter4.markdown +863 -0
- data/test/progit/ja/05-distributed-git/01-chapter5.markdown +908 -0
- data/test/progit/ja/06-git-tools/01-chapter6.markdown +1133 -0
- data/test/progit/ja/07-customizing-git/01-chapter7.markdown +936 -0
- data/test/progit/ja/08-git-and-other-scms/01-chapter8.markdown +690 -0
- data/test/progit/ja/09-git-internals/01-chapter9.markdown +984 -0
- data/test/progit/ja/README.md +58 -0
- data/test/progit/ja/translation glossaries.txt +33 -0
- data/test/progit/ko/01-introduction/01-chapter1.markdown +258 -0
- data/test/progit/ko/02-git-basics/01-chapter2.markdown +1181 -0
- data/test/progit/ko/03-git-branching/01-chapter3.markdown +612 -0
- data/test/progit/ko/04-git-server/01-chapter4.markdown +867 -0
- data/test/progit/ko/05-distributed-git/01-chapter5.markdown +913 -0
- data/test/progit/ko/06-git-tools/01-chapter6.markdown +1142 -0
- data/test/progit/ko/07-customizing-git/01-chapter7.markdown +935 -0
- data/test/progit/ko/08-git-and-other-scms/01-chapter8.markdown +688 -0
- data/test/progit/ko/09-git-internals/01-chapter9.markdown +976 -0
- data/test/progit/ko/README.md +75 -0
- data/test/progit/ko/translation_guide.txt +65 -0
- data/test/progit/latex/README +27 -0
- data/test/progit/latex/config.yml +144 -0
- data/test/progit/latex/makepdf +207 -0
- data/test/progit/latex/template.tex +155 -0
- data/test/progit/makeebooks +125 -0
- data/test/progit/makepdfs +47 -0
- data/test/progit/mk/01-introduction/01-chapter1.markdown +258 -0
- data/test/progit/mk/02-git-basics/01-chapter2.markdown +1125 -0
- data/test/progit/mk/03-git-branching/01-chapter3.markdown +598 -0
- data/test/progit/mk/05-distributed-git/01-chapter5.markdown +897 -0
- data/test/progit/nl/01-introduction/01-chapter1.markdown +296 -0
- data/test/progit/nl/02-git-basics/01-chapter2.markdown +1253 -0
- data/test/progit/nl/03-git-branching/01-chapter3.markdown +642 -0
- data/test/progit/nl/04-git-server/01-chapter4.markdown +902 -0
- data/test/progit/nl/05-distributed-git/01-chapter5.markdown +953 -0
- data/test/progit/nl/06-git-tools/01-chapter6.markdown +1177 -0
- data/test/progit/nl/07-customizing-git/01-chapter7.markdown +974 -0
- data/test/progit/nl/08-git-and-other-scms/01-chapter8.markdown +725 -0
- data/test/progit/nl/09-git-internals/01-chapter9.markdown +1013 -0
- data/test/progit/no-nb/01-introduction/01-chapter1.markdown +261 -0
- data/test/progit/no-nb/02-git-basics/01-chapter2.markdown +1225 -0
- data/test/progit/no-nb/03-git-branching/01-chapter3.markdown +606 -0
- data/test/progit/no-nb/04-git-server/01-chapter4.markdown +867 -0
- data/test/progit/no-nb/05-distributed-git/01-chapter5.markdown +914 -0
- data/test/progit/no-nb/06-git-tools/01-chapter6.markdown +1144 -0
- data/test/progit/no-nb/07-customizing-git/01-chapter7.markdown +936 -0
- data/test/progit/no-nb/08-git-and-other-scms/01-chapter8.markdown +689 -0
- data/test/progit/no-nb/09-git-internals/01-chapter9.markdown +977 -0
- data/test/progit/no-nb/README +2 -0
- data/test/progit/pl/01-introduction/01-chapter1.markdown +257 -0
- data/test/progit/pl/02-git-basics/02-chapter2.markdown +1128 -0
- data/test/progit/pl/03-git-branching/01-chapter3.markdown +598 -0
- data/test/progit/pl/04-git-server/01-chapter4.markdown +897 -0
- data/test/progit/pl/05-distributed-git/01-chapter5.markdown +1278 -0
- data/test/progit/pl/06-git-tools/01-chapter6.markdown +1550 -0
- data/test/progit/pl/07-customizing-git/01-chapter7.markdown +1058 -0
- data/test/progit/pl/08-git-and-other-scms/01-chapter8.markdown +948 -0
- data/test/progit/pl/09-git-internals/01-chapter9.markdown +1382 -0
- data/test/progit/pl/translation-guidelines.txt +70 -0
- data/test/progit/pt-br/01-introduction/01-chapter1.markdown +256 -0
- data/test/progit/pt-br/02-git-basics/01-chapter2.markdown +1127 -0
- data/test/progit/pt-br/03-git-branching/01-chapter3.markdown +596 -0
- data/test/progit/pt-br/04-git-server/01-chapter4.markdown +888 -0
- data/test/progit/pt-br/05-distributed-git/01-chapter5.markdown +896 -0
- data/test/progit/pt-br/06-git-tools/01-chapter6.markdown +1122 -0
- data/test/progit/pt-br/07-customizing-git/01-chapter7.markdown +932 -0
- data/test/progit/pt-br/08-git-and-other-scms/01-chapter8.markdown +691 -0
- data/test/progit/pt-br/09-git-internals/01-chapter9.markdown +978 -0
- data/test/progit/pt-br/figures-dia/fig0101.dia +617 -0
- data/test/progit/pt-br/figures-dia/fig0102.dia +921 -0
- data/test/progit/pt-br/figures-dia/fig0103.dia +1468 -0
- data/test/progit/pt-br/figures-dia/fig0104.dia +1432 -0
- data/test/progit/pt-br/figures-dia/fig0105.dia +1924 -0
- data/test/progit/pt-br/figures-dia/fig0106.dia +562 -0
- data/test/progit/pt-br/figures-dia/fig0201.dia +776 -0
- data/test/progit/pt-br/figures-dia/fig0301.dia +2006 -0
- data/test/progit/pt-br/figures-dia/fig0302.dia +2148 -0
- data/test/progit/pt-br/figures-dia/fig0316.dia +1079 -0
- data/test/progit/pt-br/figures-dia/fig0322.dia +1142 -0
- data/test/progit/pt-br/figures-dia/fig0323.dia +1407 -0
- data/test/progit/pt-br/figures-dia/fig0324.dia +1603 -0
- data/test/progit/pt-br/figures-dia/fig0325.dia +2003 -0
- data/test/progit/pt-br/figures-dia/fig0326.dia +2013 -0
- data/test/progit/pt-br/figures-dia/fig0336.dia +786 -0
- data/test/progit/pt-br/figures-dia/fig0337.dia +1546 -0
- data/test/progit/pt-br/figures-dia/fig0338.dia +1755 -0
- data/test/progit/pt-br/figures-dia/fig0339.dia +1882 -0
- data/test/progit/pt-br/figures-dia/fig0501.dia +456 -0
- data/test/progit/pt-br/figures-dia/fig0502.dia +965 -0
- data/test/progit/pt-br/figures-dia/fig0503.dia +914 -0
- data/test/progit/pt-br/figures-dia/fig0511.dia +1201 -0
- data/test/progit/pt-br/figures-dia/fig0515.dia +1721 -0
- data/test/progit/pt-br/figures-dia/fig0702.dia +795 -0
- data/test/progit/pt-br/figures-dia/fig0703.dia +795 -0
- data/test/progit/pt-br/figures-dia/fig0901.dia +669 -0
- data/test/progit/pt-br/figures-dia/fig0902.dia +834 -0
- data/test/progit/pt-br/figures-dia/fig0903.dia +1483 -0
- data/test/progit/pt-br/figures-dia/fig0904.dia +1728 -0
- data/test/progit/ro/01-introduction/01-chapter1.markdown +257 -0
- data/test/progit/ru/01-introduction/01-chapter1.markdown +259 -0
- data/test/progit/ru/02-git-basics/01-chapter2.markdown +1155 -0
- data/test/progit/ru/03-git-branching/01-chapter3.markdown +598 -0
- data/test/progit/ru/04-git-server/01-chapter4.markdown +854 -0
- data/test/progit/ru/05-distributed-git/01-chapter5.markdown +897 -0
- data/test/progit/ru/06-git-tools/01-chapter6.markdown +1126 -0
- data/test/progit/ru/07-customizing-git/01-chapter7.markdown +938 -0
- data/test/progit/ru/08-git-and-other-scms/01-chapter8.markdown +691 -0
- data/test/progit/ru/09-git-internals/01-chapter9.markdown +977 -0
- data/test/progit/ru/Glossary +38 -0
- data/test/progit/ru/README +12 -0
- data/test/progit/ru/figures-dia/fig0101.dia +647 -0
- data/test/progit/ru/figures-dia/fig0102.dia +1009 -0
- data/test/progit/ru/figures-dia/fig0103.dia +1468 -0
- data/test/progit/ru/figures-dia/fig0104.dia +1432 -0
- data/test/progit/ru/figures-dia/fig0105.dia +1924 -0
- data/test/progit/ru/figures-dia/fig0106.dia +561 -0
- data/test/progit/ru/figures-dia/fig0201.dia +774 -0
- data/test/progit/ru/figures-dia/fig0322.dia +1182 -0
- data/test/progit/ru/figures-dia/fig0323.dia +1457 -0
- data/test/progit/ru/figures-dia/fig0324.dia +1698 -0
- data/test/progit/ru/figures-dia/fig0325.dia +2101 -0
- data/test/progit/ru/figures-dia/fig0326.dia +2111 -0
- data/test/progit/ru/figures-dia/fig0336.dia +786 -0
- data/test/progit/ru/figures-dia/fig0337.dia +1546 -0
- data/test/progit/ru/figures-dia/fig0338.dia +1755 -0
- data/test/progit/ru/figures-dia/fig0339.dia +1882 -0
- data/test/progit/ru/figures-dia/fig0501.dia +477 -0
- data/test/progit/ru/figures-dia/fig0502.dia +1063 -0
- data/test/progit/ru/figures-dia/fig0503.dia +915 -0
- data/test/progit/ru/figures-dia/fig0511.dia +1201 -0
- data/test/progit/ru/figures-dia/fig0515.dia +1741 -0
- data/test/progit/ru/figures-dia/fig0702.dia +851 -0
- data/test/progit/ru/figures-dia/fig0703.dia +851 -0
- data/test/progit/sr/01-introduction/01-chapter1.markdown +257 -0
- data/test/progit/summary.rb +29 -0
- data/test/progit/th/01-introduction/01-chapter1.markdown +257 -0
- data/test/progit/th/02-git-basics/01-chapter2.markdown +1126 -0
- data/test/progit/th/README.md +47 -0
- data/test/progit/tr/01-introduction/01-chapter1.markdown +258 -0
- data/test/progit/tr/02-git-basics/01-chapter2.markdown +1129 -0
- data/test/progit/tr/03-git-branching/01-chapter3.markdown +598 -0
- data/test/progit/tr/04-git-server/01-chapter4.markdown +73 -0
- data/test/progit/tr/05-distributed-git/01-chapter5.markdown +215 -0
- data/test/progit/uk/01-introduction/01-chapter1.markdown +522 -0
- data/test/progit/vi/01-introduction/01-chapter1.markdown +259 -0
- data/test/progit/vi/02-git-basics/01-chapter2.markdown +1172 -0
- data/test/progit/vi/03-git-branching/01-chapter3.markdown +598 -0
- data/test/progit/zh-tw/01-introduction/01-chapter1.markdown +259 -0
- data/test/progit/zh-tw/02-git-basics/01-chapter2.markdown +1183 -0
- data/test/progit/zh-tw/03-git-branching/01-chapter3.markdown +604 -0
- data/test/progit/zh-tw/04-git-server/01-chapter4.markdown +866 -0
- data/test/progit/zh-tw/05-distributed-git/01-chapter5.markdown +912 -0
- data/test/progit/zh-tw/06-git-tools/01-chapter6.markdown +1139 -0
- data/test/progit/zh-tw/07-customizing-git/01-chapter7.markdown +932 -0
- data/test/progit/zh-tw/08-git-and-other-scms/01-chapter8.markdown +689 -0
- data/test/progit/zh-tw/09-git-internals/01-chapter9.markdown +977 -0
- data/test/progit/zh/01-introduction/01-chapter1.markdown +259 -0
- data/test/progit/zh/02-git-basics/01-chapter2.markdown +1177 -0
- data/test/progit/zh/03-git-branching/01-chapter3.markdown +604 -0
- data/test/progit/zh/04-git-server/01-chapter4.markdown +866 -0
- data/test/progit/zh/05-distributed-git/01-chapter5.markdown +912 -0
- data/test/progit/zh/06-git-tools/01-chapter6.markdown +1125 -0
- data/test/progit/zh/07-customizing-git/01-chapter7.markdown +935 -0
- data/test/progit/zh/08-git-and-other-scms/01-chapter8.markdown +689 -0
- data/test/progit/zh/09-git-internals/01-chapter9.markdown +976 -0
- data/test/spec_tests.json +4382 -4070
- data/test/test_basics.rb +1 -1
- data/test/test_helper.rb +1 -0
- data/test/test_maliciousness.rb +4 -2
- data/test/test_pathological_inputs.rb +31 -30
- data/test/test_spec.rb +5 -4
- 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.
|