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,257 @@
|
|
1
|
+
# Pierwsze kroki #
|
2
|
+
|
3
|
+
Ten rozdział poświęcony jest pierwszym krokom z Git. Rozpoczyna się krótkim wprowadzeniem do narzędzi kontroli wersji, następnie przechodzi do instalacji i początkowej konfiguracji Git. Po przeczytaniu tego rozdziału powinieneś rozumieć w jakim celu Git został stworzony, dlaczego warto z niego korzystać oraz być przygotowany do używania go.
|
4
|
+
|
5
|
+
## Wprowadzenie do kontroli wersji ##
|
6
|
+
|
7
|
+
Czym jest kontrola wersji i dlaczego powinieneś się nią przejmować? System kontroli wersji śledzi wszystkie zmiany dokonywane na pliku (lub plikach) i umożliwia przywołanie dowolnej wcześniejszej wersji. Przykłady w tej książce będą śledziły zmiany w kodzie źródłowym, niemniej w ten sam sposób można kontrolować praktycznie dowolny typ plików.
|
8
|
+
|
9
|
+
Jeśli jesteś grafikiem lub projektantem WWW i chcesz zachować każdą wersję pliku graficznego lub układu witryny WWW (co jest wysoce prawdopodobne), to używanie systemu kontroli wersji (VCS-Version Control System) jest bardzo rozsądnym rozwiązaniem. Pozwala on przywrócić plik(i) do wcześniejszej wersji, odtworzyć stan całego projektu, porównać wprowadzone zmiany, dowiedzieć się kto jako ostatnio zmodyfikował część projektu powodującą problemy, kto i kiedy wprowadził daną modyfikację. Oprócz tego używanie VCS oznacza, że nawet jeśli popełnisz błąd lub stracisz część danych, naprawa i odzyskanie ich powinno być łatwe. Co więcej, wszystko to można uzyskać całkiem niewielkim kosztem.
|
10
|
+
|
11
|
+
### Lokalne systemy kontroli wersji ###
|
12
|
+
|
13
|
+
Dla wielu ludzi preferowaną metodą kontroli wersji jest kopiowanie plików do innego katalogu (może nawet oznaczonego datą, jeśli są sprytni). Takie podejście jest bardzo częste ponieważ jest wyjątkowo proste, niemniej jest także bardzo podatne na błędy. Zbyt łatwo zapomnieć w jakim jest się katalogu i przypadkowo zmodyfikować błędny plik lub skopiować nie te dane.
|
14
|
+
|
15
|
+
Aby poradzić sobie z takimi problemami, programiści już dość dawno temu stworzyli lokalne systemy kontroli wersji, które składały się z prostej bazy danych w której przechowywane były wszystkie zmiany dokonane na śledzonych plikach (por. Rysunek 1-1).
|
16
|
+
|
17
|
+
Insert 18333fig0101.png
|
18
|
+
Rysunek 1-1. Diagram lokalnego systemu kontroli wersji.
|
19
|
+
|
20
|
+
Jednym z najbardziej popularnych narzędzi VCS był system rcs, który wciąż jest obecny na wielu dzisiejszych komputerach. Nawet w popularnym systemie operacyjnym Mac OS X rcs jest dostępny po zainstalowaniu Narzędzi Programistycznych (Developer Tools). Program ten działa zapisując, w specjalnym formacie na dysku, dane różnicowe (to jest zawierające jedynie różnice pomiędzy plikami) z każdej dokonanej modyfikacji. Używając tych danych jest w stanie przywołać stan pliku z dowolnego momentu.
|
21
|
+
|
22
|
+
### Scentralizowane systemy kontroli wersji ###
|
23
|
+
|
24
|
+
Kolejnym poważnym problemem z którym można się spotkać jest potrzeba współpracy w rozwoju projektu z odrębnych systemów. Aby poradzić sobie z tym problemem stworzono scentralizowane systemy kontroli wersji (CVCS - Centralized Version Control System). Systemy takie jak CVS, Subversion czy Perforce składają się z jednego serwera, który zawiera wszystkie pliki poddane kontroli wersji, oraz klientów którzy mogą się z nim łączyć i uzyskać dostęp do najnowszych wersji plików. Przez wiele lat był to standardowy model kontroli wersji (por. Rysunek 1-2).
|
25
|
+
|
26
|
+
Insert 18333fig0102.png
|
27
|
+
Rysunek 1-2. Diagram scentralizowanego systemu kontroli wersji.
|
28
|
+
|
29
|
+
Taki schemat posiada wiele zalet, szczególnie w porównaniu z VCS. Dla przykładu każdy może się zorientować co robią inni uczestnicy projektu. Administratorzy mają dokładną kontrolę nad uprawnieniami poszczególnych użytkowników. Co więcej systemy CVCS są także dużo łatwiejsze w zarządzaniu niż lokalne bazy danych u każdego z klientów.
|
30
|
+
|
31
|
+
Niemniej systemy te mają także poważne wady. Najbardziej oczywistą jest problem awarii centralnego serwera. Jeśli serwer przestanie działać na przykład na godzinę, to przez tę godzinę nikt nie będzie miał możliwości współpracy nad projektem, ani nawet zapisania zmian nad którymi pracował. Jeśli dysk twardy na którym przechowywana jest centralna baza danych zostanie uszkodzony a nie tworzono żadnych kopii zapasowych, to można stracić absolutnie wszystko - całą historię projektu, może oprócz pojedynczych jego części zapisanych na osobistych komputerach niektórych użytkowników. Lokalne VCS mają ten sam problem - zawsze gdy cała historia projektu jest przechowywana tylko w jednym miejscu, istnieje ryzyko utraty większości danych.
|
32
|
+
|
33
|
+
### Rozproszone systemy kontroli wersji ###
|
34
|
+
|
35
|
+
W ten sposób dochodzimy do rozproszonych systemów kontroli wersji (DVCS - Distributed Version Control System). W systemach DVCS (takich jak Git, Mercurial, Bazaar lub Darcs) klienci nie dostają dostępu jedynie do najnowszych wersji plików ale w pełni kopiują całe repozytorium. Gdy jeden z serwerów, używanych przez te systemy do współpracy, ulegnie awarii, repozytorium każdego klienta może zostać po prostu skopiowane na ten serwer w celu przywrócenia go do pracy (por. Rysunek 1-3).
|
36
|
+
|
37
|
+
Insert 18333fig0103.png
|
38
|
+
Rysunek 1-3. Diagram rozproszonego systemu kontroli wersji.
|
39
|
+
|
40
|
+
Co więcej, wiele z tych systemów dość dobrze radzi sobie z kilkoma zdalnymi repozytoriami, więc możliwa jest jednoczesna współpraca z różnymi grupami ludzi nad tym samym projektem. Daje to swobodę wykorzystania różnych schematów pracy, nawet takich które nie są możliwe w scentralizowanych systemach, na przykład modeli hierarchicznych.
|
41
|
+
|
42
|
+
## Krótka historia Git ##
|
43
|
+
|
44
|
+
Jak z wieloma dobrymi rzeczami w życiu Git zaczął od odrobiny twórczej destrukcji oraz zażartych kontrowersji. Jądro Linuksa jest dość dużym projektem otwartego oprogramowania (ang. open source). Przez większą część życia tego projektu (1991-2002), zmiany w źródle były przekazywane jako łaty (ang. patches) i zarchiwizowane pliki. W roku 2002 projekt jądra Linuksa zaczął używać systemu DVCS BitKeeper.
|
45
|
+
|
46
|
+
W 2005 roku relacje pomiędzy wspólnotą rozwijającą jądro Linuksa a firmą która stworzyła BitKeepera znacznie się pogorszyły, a pozwolenie na nieodpłatne używanie systemu zostało cofnięte. To skłoniło programistów pracujących nad jądrem (a w szczególności Linusa Torvaldsa, twórcę Linuksa) do stworzenia własnego systemu na podstawie wiedzy wyniesionej z używania BitKeepera. Do celów tego nowego systemu należały:
|
47
|
+
|
48
|
+
* Szybkość
|
49
|
+
* Prosta konstrukcja
|
50
|
+
* Silne wsparcie dla nieliniowego rozwoju (tysięcy równoległych gałęzi)
|
51
|
+
* Pełne rozproszenie
|
52
|
+
* Wydajna obsługa dużych projektów, takich jak jądro Linuksa (szybkość i rozmiar danych)
|
53
|
+
|
54
|
+
Od swoich narodzin w 2005 roku, Git ewoluował i ustabilizował się jako narzędzie łatwe w użyciu, jednocześnie zachowując wyżej wymienione cechy. Jest niewiarygodnie szybki, bardzo wydajny przy pracy z dużymi projektami i posiada niezwykły system gałęzi do nieliniowego rozwoju (patrz Rozdział 3).
|
55
|
+
|
56
|
+
## Podstawy Git ##
|
57
|
+
|
58
|
+
Czym jest w skrócie Git? To jest bardzo istotna sekcja tej książki, ponieważ jeśli zrozumiesz czym jest Git i podstawy jego działania to efektywne używanie go powinno być dużo prostsze. Podczas uczenia się Git staraj się nie myśleć o tym co wiesz o innych systemach VCS, takich jak Subversion czy Perforce; pozwoli Ci to uniknąć subtelnych błędów przy używaniu tego narzędzia. Git przechowuje i traktuje informacje kompletnie inaczej niż te pozostałe systemy, mimo że interfejs użytkownika jest dość zbliżony. Rozumienie tych różnic powinno pomóc Ci w unikaniu błędów przy korzystaniu z Git.
|
59
|
+
|
60
|
+
### Migawki, nie różnice ###
|
61
|
+
|
62
|
+
Podstawową różnicą pomiędzy Git a każdym innym systemem VCS (włączając w to Subversion) jest podejście Git do przechowywanych danych. Większość pozostałych systemów przechowuje informacje jako listę zmian na plikach. Systemy te (CVS, Subversion, Perforce, Bazaar i inne) traktują przechowywane informacje jako zbiór plików i zmian dokonanych na każdym z nich w okresie czasu. Obrazuje to Rysunek 1-4.
|
63
|
+
|
64
|
+
Insert 18333fig0104.png
|
65
|
+
Rysunek 1-4. Inne system przechowują dane w postaci zmian do podstawowej wersji każdego z plików.
|
66
|
+
|
67
|
+
Git podchodzi do przechowywania danych w odmienny sposób. Traktuje on dane podobnie jak zestaw migawek (ang. snapshots) małego systemu plików. Za każdym razem jak tworzysz commit lub zapisujesz stan projektu, Git tworzy obraz przedstawiający to jak wyglądają wszystkie pliki w danym momencie i przechowuje referencję do tej migawki. W celu uzyskania dobrej wydajności, jeśli dany plik nie został zmieniony, Git nie zapisuje ponownie tego pliku, a tylko referencję do jego poprzedniej, identycznej wersji, która jest już zapisana. Git myśli o danych w sposób podobny do przedstawionego na Rysunku 1-5.
|
68
|
+
|
69
|
+
Insert 18333fig0105.png
|
70
|
+
Rysunek 1-5. Git przechowuje dane jako migawki projektu w okresie czasu.
|
71
|
+
|
72
|
+
To jest istotna różnica pomiędzy Git i prawie wszystkimi innymi systemami VCS. Jej konsekwencją jest to, że Git rewiduje prawie wszystkie aspekty kontroli wersji, które pozostałe systemy po prostu kopiowały z poprzednich generacji. Powoduje także, że Git jest bardziej podobny do mini systemu plików ze zbudowanymi na nim potężnymi narzędziami, niż do zwykłego systemu VCS. Odkryjemy niektóre z zalet które zyskuje się poprzez myślenie o danych w ten sposób, gdy w trzecim rozdziale będziemy omawiać tworzenie gałęzi w Git.
|
73
|
+
|
74
|
+
### Niemal każda operacja jest lokalna ###
|
75
|
+
|
76
|
+
Większość operacji w Git do działania wymaga jedynie dostępu do lokalnych plików i zasobów, lub inaczej – nie są potrzebne żadne dane przechowywane na innym komputerze w sieci. Jeśli jesteś przyzwyczajony do systemów CVCS, w których większość operacji posiada narzut związany z dostępem sieciowym, ten aspekt Git sprawi, że uwierzysz w bogów szybkości, którzy musieli obdarzyć Git nieziemskimi mocami. Ponieważ kompletna historia projektu znajduje się w całości na Twoim dysku, odnosi się wrażenie, że większość operacji działa niemal natychmiast.
|
77
|
+
|
78
|
+
Przykładowo, w celu przeglądu historii projektu, Git nie musi łączyć się z serwerem, aby pobrać historyczne dane - zwyczajnie odczytuje je wprost z lokalnej bazy danych. Oznacza to, że dostęp do historii jest niemal natychmiastowy. Jeśli chcesz przejrzeć zmiany wprowadzone pomiędzy bieżącą wersją pliku, a jego stanem sprzed miesiąca, Git może odnaleźć wersję pliku sprzed miesiąca i dokonać lokalnego porównania. Nie musi w tym celu prosić serwera o wygenerowanie różnicy, czy też o udostępnienie wcześniejszej wersji pliku.
|
79
|
+
|
80
|
+
Oznacza to również, że można zrobić prawie wszystko będąc poza zasięgiem sieci lub firmowego VPNa. Jeśli masz ochotę popracować w samolocie lub pociągu, możesz bez problemu zatwierdzać kolejne zmiany, by w momencie połączenia z siecią przesłać komplet zmian na serwer. Jeśli pracujesz w domu, a klient VPN odmawia współpracy, nie musisz czekać z pilnymi zmianami. W wielu innych systemach taki sposób pracy jest albo niemożliwy, albo co najmniej uciążliwy. Przykładowo w Perforce, nie możesz wiele zdziałać bez połączenia z serwerem; w Subversion, albo CVS możesz edytować pliki, ale nie masz możliwości zatwierdzania zmian w repozytorium (ponieważ nie masz do niego dostępu). Może nie wydaje się to wielkim problemem, ale zdziwisz się pewnie jak wielką stanowi to różnicę w sposobie pracy.
|
81
|
+
|
82
|
+
### Git ma wbudowane mechanizmy spójności danych ###
|
83
|
+
|
84
|
+
Dla każdego obiektu Git wyliczana jest suma kontrolna przed jego zapisem i na podstawie tej sumy można od tej pory odwoływać się do danego obiektu. Oznacza to, że nie ma możliwości zmiany zawartości żadnego pliku, czy katalogu bez reakcji ze strony Git. Ta cecha wynika z wbudowanych, niskopoziomowych mechanizmów Git i stanowi integralną część jego filozofii. Nie ma szansy na utratę informacji, czy uszkodzenie zawartości pliku podczas przesyłania lub pobierania danych, bez możliwości wykrycia takiej sytuacji przez Git.
|
85
|
+
|
86
|
+
Mechanizmem, który wykorzystuje Git do wyznaczenia sumy kontrolnej jest tzw. skrót SHA-1. Jest to 40-znakowy łańcuch składający się z liczb szesnastkowych (0–9 oraz a–f), wyliczany na podstawie zawartości pliku lub struktury katalogu. Skrót SHA-1 wygląda mniej więcej tak:
|
87
|
+
|
88
|
+
24b9da6552252987aa493b52f8696cd6d3b00373
|
89
|
+
|
90
|
+
Pracując z Git będziesz miał styczność z takimi skrótami w wielu miejscach, ponieważ są one wykorzystywane cały czas. W rzeczywistości Git przechowuje wszystko nie pod postacią plików i ich nazw, ale we własnej bazie danych, w której kluczami są skróty SHA-1, a wartościami - zawartości plików, czy struktur katalogów.
|
91
|
+
|
92
|
+
### Standardowo Git wyłącznie dodaje nowe dane ###
|
93
|
+
|
94
|
+
Wykonując pracę z Git, niemal zawsze jedynie dodajemy dane do bazy danych Git. Bardzo trudno jest zmusić system do zrobienia czegoś, z czego nie można się następnie wycofać, albo sprawić, by niejawnie skasował jakieś dane. Podobnie jak w innych systemach VCS, można stracić lub nadpisać zmiany, które nie zostały jeszcze zatwierdzone; ale po zatwierdzeniu migawki do Git, bardzo trudno jest stracić te zmiany, zwłaszcza jeśli regularnie pchasz własną bazę danych Git do innego repozytorium.
|
95
|
+
|
96
|
+
Ta cecha sprawia, że praca z Git jest czystą przyjemnością, ponieważ wiemy, że możemy eksperymentować bez ryzyka zepsucia czegokolwiek. Więcej szczegółów na temat sposobu przechowywania danych przez Git oraz na temat mechanizmów odzyskiwania danych, które wydają się być utracone, znajduje się w rozdziale 9, "Mechanizmy wewnętrzne".
|
97
|
+
|
98
|
+
### Trzy stany ###
|
99
|
+
|
100
|
+
Teraz uwaga. To jedna z najważniejszych spraw do zapamiętania jeśli chodzi o pracę z Git, jeśli dalszy proces nauki ma przebiegać sprawnie. Git posiada trzy stany, w których mogą znajdować się pliki: zatwierdzony, zmodyfikowany i śledzony. Zatwierdzony oznacza, że dane zostały bezpiecznie zachowane w Twojej lokalnej bazie danych. Zmodyfikowany oznacza, że plik został zmieniony, ale zmiany nie zostały wprowadzone do bazy danych. Śledzony - oznacza, że zmodyfikowany plik został przeznaczony do zatwierdzenia w bieżącej postaci w następnej operacji commit.
|
101
|
+
|
102
|
+
Z powyższego wynikają trzy główne sekcje projektu Git: katalog Git, katalog roboczy i przechowalnia (ang. staging area).
|
103
|
+
|
104
|
+
Insert 18333fig0106.png
|
105
|
+
Rysunek 1-6. Katalog roboczy, przechowalnia, katalog git.
|
106
|
+
|
107
|
+
Katalog Git jest miejscem, w którym Git przechowuje własne metadane oraz obiektową bazę danych Twojego projektu. To najważniejsza część Git i to właśnie ten katalog jest kopiowany podczas klonowania repozytorium z innego komputera.
|
108
|
+
|
109
|
+
Katalog roboczy stanowi obraz jednej wersji projektu. Zawartość tego katalogu pobierana jest ze skompresowanej bazy danych zawartej w katalogu Git i umieszczana na dysku w miejscu, w którym można ją odczytać lub zmodyfikować.
|
110
|
+
|
111
|
+
Przechowalnia to prosty plik, zwykle przechowywany w katalogu Git, który zawiera informacje o tym, czego dotyczyć będzie następna operacja `commit`. Czasami można spotkać się z określeniem indeks, ale ostatnio przyjęło się odwoływać do niego właśnie jako przechowalnia.
|
112
|
+
|
113
|
+
Podstawowy sposób pracy z Git wygląda mniej więcej tak:
|
114
|
+
|
115
|
+
1. Dokonujesz modyfikacji plików w katalogu roboczym.
|
116
|
+
2. Oznaczasz zmodyfikowane pliki jako śledzone, dodając ich bieżący stan (migawkę) do przechowalni.
|
117
|
+
3. Dokonujesz zatwierdzenia (`commit`), podczas którego zawartość plików z przechowalni zapisywana jest jako migawka projektu w katalogu Git.
|
118
|
+
|
119
|
+
Jeśli jakaś wersja pliku znajduje się w katalogu git, uznaje się ją jako zatwierdzoną. Jeśli plik jest zmodyfikowany, ale został dodany do przechowalni, plik jest śledzony. Jeśli zaś plik jest zmodyfikowany od czasu ostatniego pobrania, ale nie został dodany do przechowalni, plik jest w stanie zmodyfikowanym. W rozdziale 2 dowiesz się więcej o wszystkich tych stanach oraz o tym jak wykorzystać je do ułatwienia sobie pracy lub jak zupełnie pominąć przechowalnię.
|
120
|
+
|
121
|
+
## Instalacja Git ##
|
122
|
+
|
123
|
+
Czas rozpocząć pracę z Git. Pierwszym krokiem jest instalacja. Można ją przeprowadzić na różne sposoby; po pierwsze można zainstalować Git ze źródeł, po drugie - można skorzystać z pakietu binarnego dla konkretnej platformy.
|
124
|
+
|
125
|
+
### Instalacja ze źródeł ###
|
126
|
+
|
127
|
+
Jeśli masz taką możliwość, korzystne jest zainstalowanie Git ze źródeł, ponieważ w ten sposób dostajesz najnowszą wersję. Każda wersja Git zawiera zwykle użyteczne zmiany w interfejsie, zatem chęć skorzystania z najnowszych funkcji stanowi zwykle najlepszy powód by skompilować samodzielnie własną wersję Git. Jest to istotne także z tego powodu, że wiele dystrybucji Linuksa posiada stare wersje pakietów; zatem jeśli nie korzystasz z najświeższej dystrybucji, albo nie aktualizujesz jej nowszymi pakietami, instalacja ze źródeł to najlepsza metoda.
|
128
|
+
|
129
|
+
Aby zainstalować Git, potrzebne są następujące biblioteki: curl, zlib, openssl, expat oraz libiconv. Przykładowo, jeśli korzystasz z systemu, który posiada narzędzie yum (np. Fedora) lub apt-get (np. system oparty na Debianie), możesz skorzystać z następujących poleceń w celu instalacji zależności:
|
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
|
+
Gdy wszystkie wymagane zależności zostaną zainstalowane, możesz pobrać najnowszą wersję Git ze strony:
|
138
|
+
|
139
|
+
http://git-scm.com/download
|
140
|
+
|
141
|
+
A następnie skompilować i zainstalować Git:
|
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
|
+
Po instalacji masz również możliwość pobrania Git za pomocą samego Git:
|
149
|
+
|
150
|
+
$ git clone git://git.kernel.org/pub/scm/git/git.git
|
151
|
+
|
152
|
+
### Instalacja w systemie Linux ###
|
153
|
+
|
154
|
+
Jeśli chcesz zainstalować Git w systemie Linux z wykorzystaniem pakietów binarnych, możesz to zrobić w standardowy sposób przy użyciu narzędzi zarządzania pakietami, specyficznych dla danej dystrybucji. Jeśli korzystasz z Fedory, możesz użyć narzędzia yum:
|
155
|
+
|
156
|
+
$ yum install git-core
|
157
|
+
|
158
|
+
Jeśli korzystasz z dystrybucji opartej na Debianie (np. Ubuntu), użyj apt-get:
|
159
|
+
|
160
|
+
$ apt-get install git
|
161
|
+
|
162
|
+
### Instalacja na komputerze Mac ###
|
163
|
+
|
164
|
+
Istnieją dwa proste sposoby instalacji Git na komputerze Mac. Najprostszym z nich jest użycie graficznego instalatora, którego można pobrać z witryny SourceForge (patrz Ekran 1-7):
|
165
|
+
|
166
|
+
http://sourceforge.net/projects/git-osx-installer/
|
167
|
+
|
168
|
+
Insert 18333fig0107.png
|
169
|
+
Rysunek 1-7. Instalator Git dla OS X.
|
170
|
+
|
171
|
+
Innym prostym sposobem jest instalacja Git z wykorzystaniem MacPorts (`http://www.macports.org`). Jeśli masz zainstalowane MacPorts, zainstaluj Git za pomocą
|
172
|
+
|
173
|
+
$ sudo port install git-core +svn +doc +bash_completion +gitweb
|
174
|
+
|
175
|
+
Nie musisz instalować wszystkich dodatków, ale dobrym pomysłem jest dołączenie +svn w razie konieczności skorzystania z Git podczas pracy z repozytoriami Subversion (patrz Rozdział 8).
|
176
|
+
|
177
|
+
### Instalacja w systemie Windows ###
|
178
|
+
|
179
|
+
Instalacja Git w systemie Windows jest bardzo prosta. Projekt msysGit posiada jedną z najprostszych procedur instalacji. Po prostu pobierz program instalatora z witryny GitHub i uruchom go:
|
180
|
+
|
181
|
+
http://msysgit.github.com/
|
182
|
+
|
183
|
+
Po instalacji masz dostęp zarówno do wersji konsolowej, uruchamianej z linii poleceń (w tym do klienta SSH, który przyda się jeszcze później) oraz do standardowego GUI.
|
184
|
+
|
185
|
+
## Wstępna konfiguracja Git ##
|
186
|
+
|
187
|
+
Teraz, gdy Git jest już zainstalowany w Twoim systemie, istotne jest wykonanie pewnych czynności konfiguracyjnych. Wystarczy to zrobić raz; konfiguracja będzie obowiązywać także po aktualizacji Git. Ustawienia można zmienić w dowolnym momencie jeszcze raz wykonując odpowiednie polecenia.
|
188
|
+
|
189
|
+
Git posiada narzędzie zwane `git config`, które pozwala odczytać, bądź zmodyfikować zmienne, które kontrolują wszystkie aspekty działania i zachowania Git. Zmienne te mogą być przechowywane w trzech różnych miejscach:
|
190
|
+
|
191
|
+
* plik `/etc/gitconfig`: Zawiera wartości zmiennych widoczne dla każdego użytkownika w systemie oraz dla każdego z ich repozytoriów. Jeśli dodasz opcję ` --system` do polecenia `git config`, odczytane bądź zapisane zostaną zmienne z tej właśnie lokalizacji.
|
192
|
+
* plik `~/.gitconfig`: Lokalizacja specyficzna dla danego użytkownika. Za pomocą opcji `--global` można uzyskać dostęp do tych właśnie zmiennych.
|
193
|
+
* plik konfiguracyjny w katalogu git (tzn. `.git/config`) bieżącego repozytorium: zawiera konfigurację charakterystyczną dla tego konkretnego repozytorium. Każdy poziom ma priorytet wyższy niż poziom poprzedni, zatem wartości zmiennych z pliku `.git/config` przesłaniają wartości zmiennych z pliku `/etc/gitconfig`.
|
194
|
+
|
195
|
+
W systemie Windows, Git poszukuje pliku `.gitconfig` w katalogu `%HOME%` (`C:\Documents and Settings\%USERNAME%` w większości przypadków). Sprawdza również istnienie pliku `/etc/gitconfig`, choć w tym wypadku katalog ten jest katalogiem względnym do katalogu instalacji MSysGit.
|
196
|
+
|
197
|
+
### Twoja tożsamość ###
|
198
|
+
|
199
|
+
Pierwszą rzeczą, którą warto wykonać po instalacji Git jest konfiguracja własnej nazwy użytkownika oraz adresu e-mail. Jest to ważne, ponieważ każda operacja zatwierdzenia w Git korzysta z tych informacji, które stają się integralną częścią zatwierdzeń przesyłanych i pobieranych później do i z serwera:
|
200
|
+
|
201
|
+
$ git config --global user.name "Jan Nowak"
|
202
|
+
$ git config --global user.email jannowak@example.com
|
203
|
+
|
204
|
+
Jeśli skorzystasz z opcji `--global` wystarczy, że taka konfiguracja zostanie dokonana jednorazowo. Git skorzysta z niej podczas każdej operacji wykonywanej przez Ciebie w danym systemie. Jeśli zaistnieje potrzeba zmiany tych informacji dla konkretnego projektu, można skorzystać z `git config` bez opcji `--global`.
|
205
|
+
|
206
|
+
### Edytor ###
|
207
|
+
|
208
|
+
Teraz, gdy ustaliłeś swą tożsamość, możesz skonfigurować domyślny edytor tekstu, który zostanie uruchomiony, gdy Git będzie wymagał wprowadzenia jakiejś informacji tekstowej. Domyślnie Git skorzysta z domyślnego edytora systemowego, którym zazwyczaj jest Vi lub Vim. Jeśli wolisz korzystać z innego edytora, np. z Emacsa, uruchom następujące polecenie:
|
209
|
+
|
210
|
+
$ git config --global core.editor emacs
|
211
|
+
|
212
|
+
### Narzędzie obsługi różnic ###
|
213
|
+
|
214
|
+
Warto również skonfigurować domyślne narzędzie do rozstrzygania różnic i problemów podczas edycji konfliktów powstałych w czasie operacji łączenia (ang. merge). Jeśli chcesz wykorzystywać w tym celu narzędzie vimdiff, użyj polecenia:
|
215
|
+
|
216
|
+
$ git config --global merge.tool vimdiff
|
217
|
+
|
218
|
+
Git zna narzędzia kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge, oraz opendiff. Możesz również użyć własnego narzędzia; rozdział 7 zawiera więcej informacji na ten temat.
|
219
|
+
|
220
|
+
### Sprawdzanie ustawień ###
|
221
|
+
|
222
|
+
Jeśli chcesz sprawdzić bieżące ustawienia, wykonaj polecenie `git config --list`. Git wyświetli pełną konfigurację:
|
223
|
+
|
224
|
+
$ git config --list
|
225
|
+
user.name=Scott Chacon
|
226
|
+
user.email=schacon@gmail.com
|
227
|
+
color.status=auto
|
228
|
+
color.branch=auto
|
229
|
+
color.interactive=auto
|
230
|
+
color.diff=auto
|
231
|
+
...
|
232
|
+
|
233
|
+
Niektóre zmienne mogą pojawić się wiele razy, ponieważ Git odczytuje konfigurację z różnych plików (choćby z `/etc/gitconfig` oraz `~/.gitconfig`). W takim wypadku Git korzysta z ostatniej wartości dla każdej unikalnej zmiennej, którą znajdzie.
|
234
|
+
|
235
|
+
Można również sprawdzić jaka jest rzeczywista wartość zmiennej o konkretnej nazwie za pomocą polecenia `git config {zmienna}`:
|
236
|
+
|
237
|
+
$ git config user.name
|
238
|
+
Scott Chacon
|
239
|
+
|
240
|
+
## Uzyskiwanie pomocy ##
|
241
|
+
|
242
|
+
Jeśli kiedykolwiek będziesz potrzebować pomocy podczas pracy z Git, istnieją trzy sposoby wyświetlenia strony podręcznika dla każdego z poleceń Git:
|
243
|
+
|
244
|
+
$ git help <polecenie>
|
245
|
+
$ git <polecenie> --help
|
246
|
+
$ man git-<polecenie>
|
247
|
+
|
248
|
+
Przykładowo, pomoc dotyczącą konfiguracji można uzyskać wpisując:
|
249
|
+
|
250
|
+
$ git help config
|
251
|
+
|
252
|
+
Polecenia te mają tę przyjemną cechę, że można z nich korzystać w każdej chwili, nawet bez połączenia z Internetem.
|
253
|
+
Jeśli standardowy podręcznik oraz niniejsza książka to za mało i potrzebna jest pomoc osobista, zawsze możesz sprawdzić kanał `#git` lub `#github` na serwerze IRC Freenode (irc.freenode.net). Kanały te są nieustannie oblegane przez setki osób, które mają duże doświadczenie z pracą z Git i często chętnie udzielają pomocy.
|
254
|
+
|
255
|
+
## Podsumowanie ##
|
256
|
+
|
257
|
+
W tym momencie powinieneś posiadać podstawowy pogląd na to czym jest Git i czym różni się od scentralizowanych systemów kontroli wersji, do których być może jesteś przyzwyczajony. Powinieneś również mieć dostęp do działającej wersji Git na własnym komputerze, której konfiguracja została zainicjowana Twoimi danymi personalnymi. Nadszedł czas by poznać podstawy pracy z Git.
|
@@ -0,0 +1,1128 @@
|
|
1
|
+
# Podstawy Gita #
|
2
|
+
|
3
|
+
Jeśli chcesz ograniczyć się do czytania jednego rozdziału, dobrze trafiłeś. Niniejszy rozdział obejmuje wszystkie podstawowe polecenia, które musisz znać, aby wykonać przeważającą część zadań, z którymi przyjdzie ci spędzić czas podczas pracy z Gitem. Po zapoznaniu się z rozdziałem powinieneś umieć samodzielnie tworzyć i konfigurować repozytoria, rozpoczynać i kończyć śledzenie plików, umieszczać zmiany w poczekalni oraz je zatwierdzać. Pokażemy ci także, jak skonfigurować Gita tak, aby ignorował pewne pliki oraz całe ich grupy według zadanego wzorca, szybko i łatwo cofać błędne zmiany, przeglądać historię swojego projektu, podglądać zmiany pomiędzy rewizjami, oraz jak wypychać je na serwer i stamtąd pobierać.
|
4
|
+
|
5
|
+
## Pierwsze repozytorium Gita ##
|
6
|
+
|
7
|
+
Projekt Gita możesz rozpocząć w dwojaki sposób. Pierwsza metoda używa istniejącego projektu lub katalogu i importuje go do Gita. Druga polega na sklonowaniu istniejącego repozytorium z innego serwera.
|
8
|
+
|
9
|
+
### Inicjalizacja Gita w istniejącym katalogu ###
|
10
|
+
|
11
|
+
Jeśli chcesz rozpocząć śledzenie zmian w plikach istniejącego projektu, musisz przejść do katalogu projektu i wykonać polecenie
|
12
|
+
|
13
|
+
$ git init
|
14
|
+
|
15
|
+
To polecenie stworzy nowy podkatalog o nazwie .git, zawierający wszystkie niezbędne pliki — szkielet repozytorium Gita. W tym momencie żadna część twojego projektu nie jest jeszcze śledzona. (Zajrzyj do Rozdziału 9. aby dowiedzieć się, jakie dokładnie pliki są przechowywane w podkatalogu `.git`, który właśnie utworzyłeś).
|
16
|
+
|
17
|
+
Aby rozpocząć kontrolę wersji istniejących plików (w przeciwieństwie do pustego katalogu), najprawdopodobniej powinieneś rozpocząć ich śledzenie i utworzyć początkową rewizję. Możesz tego dokonać kilkoma poleceniami add (dodaj) wybierając pojedyncze pliki, które chcesz śledzić, a następnie zatwierdzając zmiany poleceniem `commit`:
|
18
|
+
|
19
|
+
$ git add *.c
|
20
|
+
$ git add README
|
21
|
+
$ git commit -m 'initial project version'
|
22
|
+
|
23
|
+
Za chwilę zobaczymy dokładnie, co wymienione polecenia robią. W tym jednak momencie masz już własne repozytorium Gita, śledzące wybrane pliki i zawierające pierwsze zatwierdzone zmiany (początkową rewizję).
|
24
|
+
|
25
|
+
### Klonowanie istniejącego repozytorium ###
|
26
|
+
|
27
|
+
Jeżeli chcesz uzyskać kopię istniejącego już repozytorium Gita — na przykład projektu, w którym chciałbyś zacząć się udzielać i wprowadzać własne zmiany — polecenie, którego potrzebujesz to `clone`. Jeżeli znasz już inne systemy kontroli wersji, jak np. Subversion, zauważysz z pewnością, że w przypadku Gita używane polecenie to `clone` a nie `checkout`. Jest to istotne rozróżnienie — Git pobiera kopię niemalże wszystkich danych posiadanych przez serwer. Po wykonaniu polecenia `git clone` zostanie pobrana każda rewizja, każdego pliku w historii projektu. W praktyce nawet jeśli dysk serwera zostanie uszkodzony, możesz użyć któregokolwiek z dostępnych klonów aby przywrócić serwer do stanu w jakim był w momencie klonowania (możesz utracić pewne hooki skonfigurowane na serwerze i tym podobne, ale wszystkie poddane kontroli wersji pliki będą spójne — zajrzyj do Rozdziału 4. aby poznać więcej szczegółów).
|
28
|
+
|
29
|
+
Repozytorium klonujesz używając polecenia `git clone [URL]`. Na przykład jeśli chcesz sklonować bibliotekę Rubiego do Gita o nazwie Grit, możesz to zrobić wywołując:
|
30
|
+
|
31
|
+
$ git clone git://github.com/schacon/grit.git
|
32
|
+
|
33
|
+
Tworzony jest katalog o nazwie „grit”, następnie wewnątrz niego inicjowany jest podkatalog `.git`, pobierane są wszystkie dane z repozytorium, a kopia robocza przełączona zostaje na ostatnią wersję. Jeśli wejdziesz do świeżo utworzonego katalogu `grit`, zobaczysz wewnątrz pliki projektu, gotowe do użycia i pracy z nimi. Jeśli chcesz sklonować repozytorium do katalogu o nazwie innej niż `grit`, możesz to zrobić podając w wierszu poleceń kolejną opcję:
|
34
|
+
|
35
|
+
$ git clone git://github.com/schacon/grit.git mygrit
|
36
|
+
|
37
|
+
Powyższe polecenie robi dokładnie to samo, co poprzednia, ale wszystkie pliki umieszcza w katalogu `mygrit`.
|
38
|
+
|
39
|
+
Git oferuje do wyboru zestaw różnych protokołów transmisji. Poprzedni przykład używa protokołu `git://`, ale możesz także spotkać `http(s)://` lub `uzytkownik@serwer:/sciezka.git`, używające protokołu SSH. W Rozdziale 4. omówimy wszystkie dostępne możliwości konfiguracji dostępu do repozytorium Gita na serwerze oraz zalety i wady każdej z nich.
|
40
|
+
|
41
|
+
## Rejestrowanie zmian w repozytorium ##
|
42
|
+
|
43
|
+
Posiadasz już repozytorium Gita i ostatnią wersję lub kopię roboczą wybranego projektu. Za każdym razem, kiedy po naniesieniu zmian projekt osiągnie stan, który chcesz zapamiętać, musisz nowe wersje plików zatwierdzić w swoim repozytorium.
|
44
|
+
|
45
|
+
Pamiętaj, że każdy plik w twoim katalogu roboczym może być w jednym z dwóch stanów: śledzony lub nieśledzony. Śledzone pliki to te, które znalazły się w ostatniej migawce; mogą być niezmodyfikowane, zmodyfikowane lub oczekiwać w poczekalni. Nieśledzone pliki to cała reszta — są to jakiekolwiek pliki w twoim katalogu roboczym, które nie znalazły się w ostatniej migawce i nie znajdują się w poczekalni, gotowe do zatwierdzenia. Początkowo, kiedy klonujesz repozytorium, wszystkie twoje pliki będą śledzone i niezmodyfikowane, ponieważ dopiero co zostały wybrane i nie zmieniałeś jeszcze niczego.
|
46
|
+
|
47
|
+
Kiedy zmieniasz pliki, Git rozpoznaje je jako zmodyfikowane, ponieważ różnią się od ostatniej zatwierdzonej zmiany. Zmodyfikowane pliki umieszczasz w poczekalni, a następnie zatwierdzasz oczekujące tam zmiany i tak powtarza się cały cykl. Przedstawia go Diagram 2-1.
|
48
|
+
|
49
|
+
Insert 18333fig0201.png
|
50
|
+
Rysunek 2-1. Cykl życia stanu twoich plików.
|
51
|
+
|
52
|
+
### Sprawdzanie stanu twoich plików ###
|
53
|
+
|
54
|
+
Podstawowe narzędzie używane do sprawdzenia stanu plików to polecenie `git status`. Jeśli uruchomisz je bezpośrednio po sklonowaniu repozytorium, zobaczysz wynik podobny do poniższego:
|
55
|
+
|
56
|
+
$ git status
|
57
|
+
# On branch master
|
58
|
+
nothing to commit, working directory clean
|
59
|
+
|
60
|
+
Oznacza to, że posiadasz czysty katalog roboczy — innymi słowy nie zawiera on śledzonych i zmodyfikowanych plików. Git nie widzi także żadnych plików nieśledzonych, w przeciwnym wypadku wyświetliłby ich listę. W końcu polecenie pokazuje również gałąź, na której aktualnie pracujesz. Póki co, jest to zawsze master, wartość domyślna; nie martw się tym jednak teraz. Następny rozdział w szczegółach omawia gałęzie oraz odniesienia.
|
61
|
+
|
62
|
+
Powiedzmy, że dodajesz do repozytorium nowy, prosty plik README. Jeżeli nie istniał on wcześniej, po uruchomieniu `git status` zobaczysz go jako plik nieśledzony, jak poniżej:
|
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
|
+
Widać, że twój nowy plik README nie jest jeszcze śledzony, ponieważ znajduje się pod nagłówkiem „Untracked files” (Nieśledzone pliki) w informacji o stanie. Nieśledzony oznacza, że Git widzi plik, którego nie miałeś w poprzedniej migawce (zatwierdzonej kopii); Git nie zacznie umieszczać go w przyszłych migawkach, dopóki sam mu tego nie polecisz. Zachowuje się tak, by uchronić cię od przypadkowego umieszczenia w migawkach wyników działania programu lub innych plików, których nie miałeś zamiaru tam dodawać. W tym przypadku chcesz, aby README został uwzględniony, więc zacznijmy go śledzić.
|
74
|
+
|
75
|
+
### Śledzenie nowych plików ###
|
76
|
+
|
77
|
+
Aby rozpocząć śledzenie nowego pliku, użyj polecenia `git add`. Aby zacząć śledzić plik README, możesz wykonać:
|
78
|
+
|
79
|
+
$ git add README
|
80
|
+
|
81
|
+
Jeśli uruchomisz teraz ponownie polecenie `status`, zobaczysz, że twój plik README jest już śledzony i znalazł się w poczekalni:
|
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
|
+
Widać, że jest w poczekalni, ponieważ znajduje się pod nagłówkiem „Changes to be commited“ (Zmiany do zatwierdzenia). Jeśli zatwierdzisz zmiany w tym momencie, jako migawka w historii zostanie zapisana wersja pliku z momentu wydania polecenia `git add`. Być może pamiętasz, że po uruchomieniu `git init` wydałeś polecenie `git add (pliki)` — miało to na celu rozpoczęcie ich śledzenia. Polecenie `git add` bierze jako parametr ścieżkę do pliku lub katalogu; jeśli jest to katalog, polecenie dodaje wszystkie pliki z tego katalogu i podkatalogów.
|
92
|
+
|
93
|
+
### Dodawanie zmodyfikowanych plików do poczekalni ###
|
94
|
+
|
95
|
+
Zmodyfikujmy teraz plik, który był już śledzony. Jeśli zmienisz śledzony wcześniej plik o nazwie `benchmarks.rb`, a następnie uruchomisz polecenie `status`, zobaczysz coś podobnego:
|
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
|
+
Plik `benchmarks.rb` pojawia się w sekcji „Changes not staged for commit“ (Zmienione ale nie zaktualizowane), co oznacza, że śledzony plik został zmodyfikowany, ale zmiany nie trafiły jeszcze do poczekalni. Aby je tam wysłać, uruchom polecenie `git add` (jest to wielozadaniowe polecenie — używa się go do rozpoczynania śledzenia nowych plików, umieszczania ich w poczekalni, oraz innych zadań, takich jak oznaczanie rozwiązanych konfliktów scalania). Uruchom zatem `git add` by umieścić `benchmarks.rb` w poczekalni, a następnie ponownie wykonaj `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
|
+
Oba pliki znajdują się już w poczekalni i zostaną uwzględnione podczas kolejnego zatwierdzenia zmian. Załóżmy, że w tym momencie przypomniałeś sobie o dodatkowej małej zmianie, którą koniecznie chcesz wprowadzić do pliku `benchmarks.rb` jeszcze przed zatwierdzeniem. Otwierasz go zatem, wprowadzasz zmianę i jesteś gotowy do zatwierdzenia. Uruchom jednak `git status` raz jeszcze:
|
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
|
+
Co do licha? Plik `benchmarks.rb` widnieje teraz jednocześnie w poczekalni i poza nią. Jak to możliwe? Okazuje się, że Git umieszcza plik w poczekalni dokładnie z taką zawartością, jak w momencie uruchomienia polecenia `git add`. Jeśli w tej chwili zatwierdzisz zmiany, zostanie użyta wersja `benchmarks.rb` dokładnie z momentu uruchomienia polecenia `git add`, nie zaś ta, którą widzisz w katalogu roboczym w momencie wydania polecenia `git commit`. Jeśli modyfikujesz plik po uruchomieniu `git add`, musisz ponownie użyć `git add`, aby najnowsze zmiany zostały umieszczone w poczekalni:
|
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
|
+
### Ignorowanie plików ###
|
152
|
+
|
153
|
+
Często spotkasz się z klasą plików, w przypadku których nie chcesz, by Git automatycznie dodawał je do repozytorium, czy nawet pokazywał je jako nieśledzone. Są to ogólnie pliki generowane automatycznie, takie jak dzienniki zdarzeń, czy pliki tworzone w czasie budowania projektu. W takich wypadkach tworzysz plik zawierający listę wzorców do nich pasujących i nazywasz go `.gitignore`. Poniżej znajdziesz przykładowy plik `.gitignore`:
|
154
|
+
|
155
|
+
$ cat .gitignore
|
156
|
+
*.[oa]
|
157
|
+
*~
|
158
|
+
|
159
|
+
Pierwsza linia mówi Gitowi, by ignorował pliki kończące się na .o lub .a — pliki obiektów i archiwa, które mogą być produktem kompilacji kodu. Druga linia mówi Gitowi, żeby pomijał również wszystkie pliki, które nazwy kończą się tyldą (`~`), której to używa wiele edytorów tekstu, takich jak Emacs, do oznaczania plików tymczasowych. Możesz też dołączyć katalog log, tmp lub pid, automatycznie wygenerowaną dokumentację itp. Zajęcie się plikiem `.gitignore` jeszcze przed przystąpieniem do pracy jest zwykle dobrym pomysłem i pozwoli ci uniknąć przypadkowego dodania do repozytorium Git niechcianych plików.
|
160
|
+
|
161
|
+
Zasady przetwarzania wyrażeń, które możesz umieścić w pliku `.gitignore` są następujące:
|
162
|
+
|
163
|
+
* Puste linie lub linie rozpoczynające się od # są ignorowane.
|
164
|
+
* Działają standardowe wyrażenia glob.
|
165
|
+
* Możesz zakończyć wyrażenie znakiem ukośnika (`/`) aby sprecyzować, że chodzi o katalog.
|
166
|
+
* Możesz negować wyrażenia rozpoczynając je wykrzyknikiem (`!`).
|
167
|
+
|
168
|
+
Wyrażenia glob są jak uproszczone wyrażenia regularne, używane przez powłokę. Gwiazdka (`*`) dopasowuje zero lub więcej znaków; `[abc]` dopasowuje dowolny znak znajdujący się wewnątrz nawiasu kwadratowego (w tym przypadku a, b lub c); znak zapytania (`?`) dopasowuje pojedynczy znak; nawias kwadratowy zawierający znaki rozdzielone myślnikiem (`[0-9]`) dopasowuje dowolny znajdujący się pomiędzy nimi znak (w tym przypadku od 0 do 9).
|
169
|
+
|
170
|
+
Poniżej znajdziesz kolejny przykład pliku `.gitignore`:
|
171
|
+
|
172
|
+
# komentarz — ta linia jest ignorowana
|
173
|
+
# żadnych plików .a
|
174
|
+
*.a
|
175
|
+
# ale uwzględniaj lib.a, pomimo ignorowania .a w linijce powyżej
|
176
|
+
!lib.a
|
177
|
+
# ignoruj plik TODO w katalogu głównym, ale nie podkatalog/TODO
|
178
|
+
/TODO
|
179
|
+
# ignoruj wszystkie pliki znajdujące się w katalogu build/
|
180
|
+
build/
|
181
|
+
# ignoruj doc/notatki.txt, ale nie doc/server/arch.txt
|
182
|
+
doc/*.txt
|
183
|
+
|
184
|
+
### Podgląd zmian w poczekalni i poza nią ###
|
185
|
+
|
186
|
+
Jeśli polecenie `git status` jest dla ciebie zbyt nieprecyzyjne — chcesz wiedzieć, co dokładnie zmieniłeś, nie zaś, które pliki zostały zmienione — możesz użyć polecenia `git diff`. W szczegółach zajmiemy się nim później; prawdopodobnie najczęściej będziesz używał go aby uzyskać odpowiedź na dwa pytania: Co zmieniłeś, ale jeszcze nie trafiło do poczekalni? Oraz, co znajduje się już w poczekalni, a co za chwilę zostanie zatwierdzone? Choć `git status` bardzo ogólnie odpowiada na oba te pytania, `git diff` pokazuje, które dokładnie linie zostały dodane, a które usunięte — w postaci łatki.
|
187
|
+
|
188
|
+
Powiedzmy, że zmieniłeś i ponownie dodałeś do poczekalni plik README, a następnie zmodyfikowałeś plik `benchmarks.rb`, jednak bez umieszczania go wśród oczekujących. Jeśli uruchomisz teraz polecenie `status`, zobaczysz coś podobnego:
|
189
|
+
|
190
|
+
$ git status
|
191
|
+
# On branch master
|
192
|
+
# Changes to be committed:
|
193
|
+
# (use "git reset HEAD <file>..." to unstage)
|
194
|
+
#
|
195
|
+
# new file: README
|
196
|
+
#
|
197
|
+
# Changes not staged for commit:
|
198
|
+
# (use "git add <file>..." to update what will be committed)
|
199
|
+
#
|
200
|
+
# modified: benchmarks.rb
|
201
|
+
#
|
202
|
+
|
203
|
+
Aby zobaczyć, co zmieniłeś ale nie wysłałeś do poczekalni, wpisz `git diff` bez żadnych argumentów:
|
204
|
+
|
205
|
+
$ git diff
|
206
|
+
diff --git a/benchmarks.rb b/benchmarks.rb
|
207
|
+
index 3cb747f..da65585 100644
|
208
|
+
--- a/benchmarks.rb
|
209
|
+
+++ b/benchmarks.rb
|
210
|
+
@@ -36,6 +36,10 @@ def main
|
211
|
+
@commit.parents[0].parents[0].parents[0]
|
212
|
+
end
|
213
|
+
|
214
|
+
+ run_code(x, 'commits 1') do
|
215
|
+
+ git.commits.size
|
216
|
+
+ end
|
217
|
+
+
|
218
|
+
run_code(x, 'commits 2') do
|
219
|
+
log = git.commits('master', 15)
|
220
|
+
log.size
|
221
|
+
|
222
|
+
Powyższe polecenie porównuje zawartość katalogu roboczego z tym, co znajduje się w poczekalni. Wynik pokaże ci te zmiany, które nie trafiły jeszcze do poczekalni.
|
223
|
+
|
224
|
+
Jeśli chcesz zobaczyć zawartość poczekalni, która trafi do repozytorium z najbliższym zatwierdzeniem, możesz użyć polecenia `git diff --cached`. (Git w wersji 1.6.1 i późniejszych pozawala użyć polecenia `git diff --staged`, które może być łatwiejsze do zapamiętania). To polecenie porówna zmiany z poczekalni z ostatnią migawką:
|
225
|
+
|
226
|
+
$ git diff --cached
|
227
|
+
diff --git a/README b/README
|
228
|
+
new file mode 100644
|
229
|
+
index 0000000..03902a1
|
230
|
+
--- /dev/null
|
231
|
+
+++ b/README2
|
232
|
+
@@ -0,0 +1,5 @@
|
233
|
+
+grit
|
234
|
+
+ by Tom Preston-Werner, Chris Wanstrath
|
235
|
+
+ http://github.com/mojombo/grit
|
236
|
+
+
|
237
|
+
+Grit is a Ruby library for extracting information from a Git repository
|
238
|
+
|
239
|
+
Istotnym jest, że samo polecenie `git diff` nie pokazuje wszystkich zmian dokonanych od ostatniego zatwierdzenia — jedynie te, które nie trafiły do poczekalni. Może być to nieco mylące, ponieważ jeżeli wszystkie twoje zmiany są już w poczekalni, wynik `git diff` będzie pusty.
|
240
|
+
|
241
|
+
Jeszcze jeden przykład — jeżeli wyślesz do poczekalni plik `benchmarks.rb`, a następnie zmodyfikujesz go ponownie, możesz użyć `git status`, by obejrzeć zmiany znajdujące się w poczekalni, jak i te poza nią:
|
242
|
+
|
243
|
+
$ git add benchmarks.rb
|
244
|
+
$ echo '# test line' >> benchmarks.rb
|
245
|
+
$ git status
|
246
|
+
# On branch master
|
247
|
+
#
|
248
|
+
# Changes to be committed:
|
249
|
+
#
|
250
|
+
# modified: benchmarks.rb
|
251
|
+
#
|
252
|
+
# Changes not staged for commit:
|
253
|
+
#
|
254
|
+
# modified: benchmarks.rb
|
255
|
+
#
|
256
|
+
|
257
|
+
Teraz możesz użyć `git diff`, by zobaczyć zmiany spoza poczekalni
|
258
|
+
|
259
|
+
$ git diff
|
260
|
+
diff --git a/benchmarks.rb b/benchmarks.rb
|
261
|
+
index e445e28..86b2f7c 100644
|
262
|
+
--- a/benchmarks.rb
|
263
|
+
+++ b/benchmarks.rb
|
264
|
+
@@ -127,3 +127,4 @@ end
|
265
|
+
main()
|
266
|
+
|
267
|
+
##pp Grit::GitRuby.cache_client.stats
|
268
|
+
+# test line
|
269
|
+
|
270
|
+
oraz `git diff --cached`, aby zobaczyć zmiany wysłane dotąd do poczekalni:
|
271
|
+
|
272
|
+
$ git diff --cached
|
273
|
+
diff --git a/benchmarks.rb b/benchmarks.rb
|
274
|
+
index 3cb747f..e445e28 100644
|
275
|
+
--- a/benchmarks.rb
|
276
|
+
+++ b/benchmarks.rb
|
277
|
+
@@ -36,6 +36,10 @@ def main
|
278
|
+
@commit.parents[0].parents[0].parents[0]
|
279
|
+
end
|
280
|
+
|
281
|
+
+ run_code(x, 'commits 1') do
|
282
|
+
+ git.commits.size
|
283
|
+
+ end
|
284
|
+
+
|
285
|
+
run_code(x, 'commits 2') do
|
286
|
+
log = git.commits('master', 15)
|
287
|
+
log.size
|
288
|
+
|
289
|
+
### Zatwierdzanie zmian ###
|
290
|
+
|
291
|
+
Teraz, kiedy twoja poczekalnia zawiera dokładnie to, co powinna, możesz zatwierdzić swoje zmiany. Pamiętaj, że wszystko czego nie ma jeszcze w poczekalni — każdy plik, który utworzyłeś lub zmodyfikowałeś, a na którym później nie uruchomiłeś polecenia `git add` — nie zostanie uwzględnione wśród zatwierdzanych zmian. Pozostanie wyłącznie w postaci zmodyfikowanych plików na twoim dysku.
|
292
|
+
|
293
|
+
W tym wypadku, kiedy ostatnio uruchamiałeś `git status`, zobaczyłeś, że wszystkie twoje zmiany są już w poczekalni, więc jesteś gotowy do ich zatwierdzenia. Najprostszy sposób zatwierdzenia zmian to wpisanie `git commit`:
|
294
|
+
|
295
|
+
$ git commit
|
296
|
+
|
297
|
+
Zostanie uruchomiony wybrany przez ciebie edytor tekstu. (Wybiera się go za pośrednictwem zmiennej środowiskową `$EDITOR` — zazwyczaj jest to vim lub emacs, możesz jednak wybrać własną aplikację używając polecenia `git config --global core.editor`, które poznałeś w Rozdziale 1.).
|
298
|
+
|
299
|
+
Edytor zostanie otwarty z następującym tekstem (poniższy przykład pokazuje ekran Vima):
|
300
|
+
|
301
|
+
# Please enter the commit message for your changes. Lines starting
|
302
|
+
# with '#' will be ignored, and an empty message aborts the commit.
|
303
|
+
# On branch master
|
304
|
+
# Changes to be committed:
|
305
|
+
# (use "git reset HEAD <file>..." to unstage)
|
306
|
+
#
|
307
|
+
# new file: README
|
308
|
+
# modified: benchmarks.rb
|
309
|
+
~
|
310
|
+
~
|
311
|
+
~
|
312
|
+
".git/COMMIT_EDITMSG" 10L, 283C
|
313
|
+
|
314
|
+
Jak widzisz, domyślny opis zmian zawiera aktualny wynik polecenia `git status` w postaci komentarza oraz jedną pustą linię na samej górze. Możesz usunąć komentarze i wpisać własny opis, lub pozostawić je, co pomoże zapamiętać zakres zatwierdzonych zmian. (Aby uzyskać jeszcze precyzyjniejsze przypomnienie, możesz przekazać do `git commit` parametr `-v`. Jeśli to zrobisz, do komentarza trafią również poszczególne zmodyfikowane wiersze, pokazując, co dokładnie zrobiłeś.). Po opuszczeniu edytora, Git stworzy nową migawkę opatrzoną twoim opisem zmian (uprzednio usuwając z niego komentarze i podsumowanie zmian).
|
315
|
+
|
316
|
+
Alternatywnie opis rewizji możesz podać już wydając polecenie `commit`, poprzedzając go flagą `-m`, jak poniżej:
|
317
|
+
|
318
|
+
$ git commit -m "Story 182: Fix benchmarks for speed"
|
319
|
+
[master]: created 463dc4f: "Fix benchmarks for speed"
|
320
|
+
2 files changed, 3 insertions(+), 0 deletions(-)
|
321
|
+
create mode 100644 README
|
322
|
+
|
323
|
+
Właśnie zatwierdziłeś swoje pierwsze zmiany! Sama operacja rewizji zwróciła dodatkowo garść informacji, między innymi, gałąź do której dorzuciłeś zmiany (master), ich sumę kontrolną SHA-1 (`463dc4f`), ilość zmienionych plików oraz statystyki dodanych i usuniętych linii kodu.
|
324
|
+
|
325
|
+
Pamiętaj, że operacja commit zapamiętała migawkę zmian z poczekalni. Wszystko czego nie dodałeś do poczekalni, ciągle czeka zmienione w swoim miejscu - możesz to uwzględnić przy następnym zatwierdzaniu zmian. Każdorazowe wywołanie polecenia `git commit` powoduje zapamiętanie migawki projektu, którą możesz następnie odtworzyć albo porównać do innej migawki.
|
326
|
+
|
327
|
+
### Pomijanie poczekalni ###
|
328
|
+
|
329
|
+
Chociaż poczekalnia może być niesamowicie przydatna przy ustalaniu rewizji dokładnie takich, jakimi chcesz je mieć później w historii, czasami możesz uznać ją za odrobinę zbyt skomplikowaną aniżeli wymaga tego twoja praca. Jeśli chcesz pominąć poczekalnię, Git udostępnia prosty skrót. Po dodaniu do składni polecenia `git commit` opcji `-a` każdy zmieniony plik, który jest już śledzony, automatycznie trafi do poczekalni, dzięki czemu pominiesz część `git add`:
|
330
|
+
|
331
|
+
$ git status
|
332
|
+
# On branch master
|
333
|
+
#
|
334
|
+
# Changes not staged for commit:
|
335
|
+
#
|
336
|
+
# modified: benchmarks.rb
|
337
|
+
#
|
338
|
+
$ git commit -a -m 'added new benchmarks'
|
339
|
+
[master 83e38c7] added new benchmarks
|
340
|
+
1 files changed, 5 insertions(+), 0 deletions(-)
|
341
|
+
|
342
|
+
Zauważ, że w tym wypadku przed zatwierdzeniem zmian i wykonaniem rewizji nie musiałeś uruchamiać `git add` na pliku banchmark.rb.
|
343
|
+
|
344
|
+
### Usuwanie plików ###
|
345
|
+
|
346
|
+
Aby usunąć plik z Gita, należy go najpierw wyrzucić ze zbioru plików śledzonych, a następnie zatwierdzić zmiany. Służy do tego polecenie `git rm`, które dodatkowo usuwa plik z katalogu roboczego. Nie zobaczysz go już zatem w sekcji plików nieśledzonych przy następnej okazji.
|
347
|
+
|
348
|
+
Jeżeli po prostu usuniesz plik z katalogu roboczego i wykonasz polecenie `git status` zobaczysz go w sekcji "Zmienione ale nie zaktualizowane" (Changes not staged for commit) (czyli, poza poczekalnią):
|
349
|
+
|
350
|
+
$ rm grit.gemspec
|
351
|
+
$ git status
|
352
|
+
# On branch master
|
353
|
+
#
|
354
|
+
# Changes not staged for commit:
|
355
|
+
# (use "git add/rm <file>..." to update what will be committed)
|
356
|
+
#
|
357
|
+
# deleted: grit.gemspec
|
358
|
+
#
|
359
|
+
|
360
|
+
W dalszej kolejności, uruchomienie `git rm` doda do poczekalni operację usunięcia pliku:
|
361
|
+
|
362
|
+
$ git rm grit.gemspec
|
363
|
+
rm 'grit.gemspec'
|
364
|
+
$ git status
|
365
|
+
# On branch master
|
366
|
+
#
|
367
|
+
# Changes to be committed:
|
368
|
+
# (use "git reset HEAD <file>..." to unstage)
|
369
|
+
#
|
370
|
+
# deleted: grit.gemspec
|
371
|
+
#
|
372
|
+
|
373
|
+
Przy kolejnej rewizji, plik zniknie i nie będzie dłużej śledzony. Jeśli zmodyfikowałeś go wcześniej i dodałeś już do indeksu oczekujących zmian, musisz wymusić usunięcie opcją `-f`. Spowodowane jest to wymogami bezpieczeństwa, aby uchronić cię przed usunięciem danych, które nie zostały jeszcze zapamiętane w żadnej migawce i które później nie będą mogły być odtworzone z repozytorium Gita.
|
374
|
+
|
375
|
+
Kolejną przydatną funkcją jest możliwość zachowywania plików w drzewie roboczym ale usuwania ich z poczekalni. Innymi słowy, możesz chcieć trzymać plik na dysku ale nie chcieć, żeby Git go dalej śledził. Jest to szczególnie przydatne w sytuacji kiedy zapomniałeś dodać czegoś do `.gitignore` i przez przypadek umieściłeś w poczekalni np. duży plik dziennika lub garść plików `.a`. Wystarczy wówczas wywołać polecenie rm wraz opcją `--cached`:
|
376
|
+
|
377
|
+
$ git rm --cached readme.txt
|
378
|
+
|
379
|
+
Do polecenia `git -rm` możesz przekazywać pliki, katalogi lub wyrażenia glob - możesz na przykład napisać coś takiego:
|
380
|
+
|
381
|
+
$ git rm log/\*.log
|
382
|
+
|
383
|
+
Zwróć uwagę na odwrotny ukośnik (`\`) na początku `*`. Jest on niezbędny gdyż Git dodatkowo do tego co robi powłoka, sam ewaluuje sobie nazwy plików. Przywołane polecenie usuwa wszystkie pliki z rozszerzeniem `.log`, znajdujące się w katalogu `log/`. Możesz także wywołać następujące polecenie:
|
384
|
+
|
385
|
+
$ git rm \*~
|
386
|
+
|
387
|
+
Usuwa ona wszystkie pliki, które kończą się tyldą `~`.
|
388
|
+
|
389
|
+
### Przenoszenie plików ###
|
390
|
+
|
391
|
+
W odróżnieniu do wielu innych systemów kontroli wersji, Git nie śledzi bezpośrednio przesunięć plików. Nie przechowuje on żadnych metadanych, które mogłyby mu pomóc w rozpoznawaniu operacji zmiany nazwy śledzonych plików. Jednakże, Git jest całkiem sprytny jeżeli chodzi o rozpoznawanie tego po fakcie - zajmiemy się tym tematem odrobinę dalej.
|
392
|
+
|
393
|
+
Nieco mylący jest fakt, że Git posiada polecenie `mv`. Służy ono do zmiany nazwy pliku w repozytorium, np.
|
394
|
+
|
395
|
+
$ git mv file_from file_to
|
396
|
+
|
397
|
+
W rzeczywistości, uruchomienie takiego polecenia spowoduje, że Git zapamięta w poczekalni operację zmiany nazwy - możesz to sprawdzić wyświetlając wynik operacji status:
|
398
|
+
|
399
|
+
$ git mv README.txt README
|
400
|
+
$ git status
|
401
|
+
# On branch master
|
402
|
+
# Your branch is ahead of 'origin/master' by 1 commit.
|
403
|
+
#
|
404
|
+
# Changes to be committed:
|
405
|
+
# (use "git reset HEAD <file>..." to unstage)
|
406
|
+
#
|
407
|
+
# renamed: README.txt -> README
|
408
|
+
#
|
409
|
+
|
410
|
+
Jest to równoważne z uruchomieniem poleceń:
|
411
|
+
|
412
|
+
$ mv README.txt README
|
413
|
+
$ git rm README.txt
|
414
|
+
$ git add README
|
415
|
+
|
416
|
+
Git rozpozna w tym przypadku, że jest to operacja zmiany nazwy - nie ma zatem znaczenia, czy zmienisz ją w ten czy opisany wcześniej (`mv`) sposób. Jedyna realna różnica polega na tym, że `mv` to jedno polecenie zamiast trzech - kwestia wygody. Co ważniejsze, samą nazwę możesz zmienić dowolnym narzędziem a resztą zajmą się już polecenia add i rm których musisz użyć przed zatwierdzeniem zmian.
|
417
|
+
|
418
|
+
## Podgląd historii rewizji ##
|
419
|
+
|
420
|
+
Po kilku rewizjach, lub w przypadku sklonowanego repozytorium zawierającego już własną historię, przyjdzie czas, że będziesz chciał spojrzeć w przeszłość i sprawdzić dokonane zmiany. Najprostszym, a zarazem najsilniejszym, służącym do tego narzędziem jest `git log`.
|
421
|
+
|
422
|
+
Poniższe przykłady operują na moim, bardzo prostym, demonstracyjnym projekcie o nazwie simplegit. Aby go pobrać uruchom:
|
423
|
+
|
424
|
+
git clone git://github.com/schacon/simplegit-progit.git
|
425
|
+
|
426
|
+
Jeśli teraz uruchomisz na sklonowanym repozytorium polecenie `git log`, uzyskasz mniej więcej coś takiego:
|
427
|
+
|
428
|
+
$ git log
|
429
|
+
commit ca82a6dff817ec66f44342007202690a93763949
|
430
|
+
Author: Scott Chacon <schacon@gee-mail.com>
|
431
|
+
Date: Mon Mar 17 21:52:11 2008 -0700
|
432
|
+
|
433
|
+
changed the version number
|
434
|
+
|
435
|
+
commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
|
436
|
+
Author: Scott Chacon <schacon@gee-mail.com>
|
437
|
+
Date: Sat Mar 15 16:40:33 2008 -0700
|
438
|
+
|
439
|
+
removed unnecessary test code
|
440
|
+
|
441
|
+
commit a11bef06a3f659402fe7563abf99ad00de2209e6
|
442
|
+
Author: Scott Chacon <schacon@gee-mail.com>
|
443
|
+
Date: Sat Mar 15 10:31:28 2008 -0700
|
444
|
+
|
445
|
+
first commit
|
446
|
+
|
447
|
+
|
448
|
+
Domyślnie, polecenie `git log` uruchomione bez argumentów, listuje zmiany zatwierdzone w tym repozytorium w odwrotnej kolejności chronologicznej, czyli pokazując najnowsze zmiany w pierwszej kolejności. Jak widzisz polecenie wyświetliło zmiany wraz z ich sumą kontrolną SHA-1, nazwiskiem oraz e-mailem autora, datą zapisu oraz notką zmiany.
|
449
|
+
|
450
|
+
Duża liczba opcji polecenia `git log` oraz ich różnorodność pozwalają na dokładne wybranie interesujących nas informacji. Za chwilę przedstawimy najważniejsze i najczęściej używane spośród nich.
|
451
|
+
|
452
|
+
Jedną z najprzydatniejszych opcji jest `-p`. Pokazuje ona różnice wprowadzone z każdą rewizją. Dodatkowo możesz użyć opcji `-2` aby ograniczyć zbiór do dwóch ostatnich wpisów:
|
453
|
+
|
454
|
+
$ git log -p -2
|
455
|
+
commit ca82a6dff817ec66f44342007202690a93763949
|
456
|
+
Author: Scott Chacon <schacon@gee-mail.com>
|
457
|
+
Date: Mon Mar 17 21:52:11 2008 -0700
|
458
|
+
|
459
|
+
changed the version number
|
460
|
+
|
461
|
+
diff --git a/Rakefile b/Rakefile
|
462
|
+
index a874b73..8f94139 100644
|
463
|
+
--- a/Rakefile
|
464
|
+
+++ b/Rakefile
|
465
|
+
@@ -5,7 +5,7 @@ require 'rake/gempackagetask'
|
466
|
+
spec = Gem::Specification.new do |s|
|
467
|
+
- s.version = "0.1.0"
|
468
|
+
+ s.version = "0.1.1"
|
469
|
+
s.author = "Scott Chacon"
|
470
|
+
|
471
|
+
commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
|
472
|
+
Author: Scott Chacon <schacon@gee-mail.com>
|
473
|
+
Date: Sat Mar 15 16:40:33 2008 -0700
|
474
|
+
|
475
|
+
removed unnecessary test code
|
476
|
+
|
477
|
+
diff --git a/lib/simplegit.rb b/lib/simplegit.rb
|
478
|
+
index a0a60ae..47c6340 100644
|
479
|
+
--- a/lib/simplegit.rb
|
480
|
+
+++ b/lib/simplegit.rb
|
481
|
+
@@ -18,8 +18,3 @@ class SimpleGit
|
482
|
+
end
|
483
|
+
|
484
|
+
end
|
485
|
+
-
|
486
|
+
-if $0 == __FILE__
|
487
|
+
- git = SimpleGit.new
|
488
|
+
- puts git.show
|
489
|
+
-end
|
490
|
+
|
491
|
+
|
492
|
+
Opcja spowodowała wyświetlenie tych samych informacji z tą różnicą, że bezpośrednio po każdym wpisie został pokazywany tzw. diff, czyli różnica. Jest to szczególnie przydatne podczas recenzowania kodu albo szybkiego przeglądania zmian dokonanych przez twojego współpracownika.
|
493
|
+
Dodatkowo możesz skorzystać z całej serii opcji podsumowujących wynik działania `git log`. Na przykład, aby zobaczyć skrócone statystyki każdej z zatwierdzonych zmian, użyj opcji `--stat`:
|
494
|
+
|
495
|
+
$ git log --stat
|
496
|
+
commit ca82a6dff817ec66f44342007202690a93763949
|
497
|
+
Author: Scott Chacon <schacon@gee-mail.com>
|
498
|
+
Date: Mon Mar 17 21:52:11 2008 -0700
|
499
|
+
|
500
|
+
changed the version number
|
501
|
+
|
502
|
+
Rakefile | 2 +-
|
503
|
+
1 files changed, 1 insertions(+), 1 deletions(-)
|
504
|
+
|
505
|
+
commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
|
506
|
+
Author: Scott Chacon <schacon@gee-mail.com>
|
507
|
+
Date: Sat Mar 15 16:40:33 2008 -0700
|
508
|
+
|
509
|
+
removed unnecessary test code
|
510
|
+
|
511
|
+
lib/simplegit.rb | 5 -----
|
512
|
+
1 files changed, 0 insertions(+), 5 deletions(-)
|
513
|
+
|
514
|
+
commit a11bef06a3f659402fe7563abf99ad00de2209e6
|
515
|
+
Author: Scott Chacon <schacon@gee-mail.com>
|
516
|
+
Date: Sat Mar 15 10:31:28 2008 -0700
|
517
|
+
|
518
|
+
first commit
|
519
|
+
|
520
|
+
README | 6 ++++++
|
521
|
+
Rakefile | 23 +++++++++++++++++++++++
|
522
|
+
lib/simplegit.rb | 25 +++++++++++++++++++++++++
|
523
|
+
3 files changed, 54 insertions(+), 0 deletions(-)
|
524
|
+
|
525
|
+
Jak widzisz, `--stat` wyświetlił pod każdym wpisem historii listę zmodyfikowanych plików, liczbę zmienionych plików oraz liczbę dodanych i usuniętych linii. Dodatkowo, opcja dołożyła podobne podsumowanie wszystkich informacji na samym końcu wyniku.
|
526
|
+
Kolejnym bardzo przydatnym parametrem jest `--pretty`. Pokazuje on wynik polecenia log w nowym, innym niż domyślny formacie. Możesz skorzystać z kilku pre-definiowanych wariantów. Opcja `oneline` wyświetla każdą zatwierdzoną zmianę w pojedynczej linii, co szczególnie przydaje się podczas wyszukiwania w całym gąszczu zmian. Dodatkowo, `short`, `full` oraz `fuller` pokazują wynik w mniej więcej tym samym formacie ale odpowiednio z odrobiną więcej lub mniej informacji:
|
527
|
+
|
528
|
+
$ git log --pretty=oneline
|
529
|
+
ca82a6dff817ec66f44342007202690a93763949 changed the version number
|
530
|
+
085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test code
|
531
|
+
a11bef06a3f659402fe7563abf99ad00de2209e6 first commit
|
532
|
+
|
533
|
+
Najbardziej interesująca jest tutaj jednak opcja `format`. Pozwala ona określić własny wygląd i format informacji wyświetlanych poleceniem log. Funkcja przydaje się szczególnie podczas generowania tychże informacji do dalszego, maszynowego przetwarzania - ponieważ sam definiujesz ściśle format, wiesz, że nie zmieni się on wraz z kolejnymi wersjami Gita:
|
534
|
+
|
535
|
+
$ git log --pretty=format:"%h - %an, %ar : %s"
|
536
|
+
ca82a6d - Scott Chacon, 11 months ago : changed the version number
|
537
|
+
085bb3b - Scott Chacon, 11 months ago : removed unnecessary test code
|
538
|
+
a11bef0 - Scott Chacon, 11 months ago : first commit
|
539
|
+
|
540
|
+
Tabela 2-1 pokazuje najprzydatniejsze opcje akceptowane przez `format`.
|
541
|
+
|
542
|
+
Opcja Opis
|
543
|
+
%H Suma kontrolna zmiany
|
544
|
+
%h Skrócona suma kontrolna zmiany
|
545
|
+
%T Suma kontrolna drzewa
|
546
|
+
%t Skrócona suma kontrolna drzewa
|
547
|
+
%P Sumy kontrolne rodziców
|
548
|
+
%p Skrócone sumy kontrolne rodziców
|
549
|
+
%an Nazwisko autora
|
550
|
+
%ae Adres e-mail autora
|
551
|
+
%ad Data autora (format respektuje opcję -date=)
|
552
|
+
%ar Względna data autora
|
553
|
+
%cn Nazwisko zatwierdzającego zmiany
|
554
|
+
%ce Adres e-mail zatwierdzającego zmiany
|
555
|
+
%cd Data zatwierdzającego zmiany
|
556
|
+
%cr Data zatwierdzającego zmiany, względna
|
557
|
+
%s Temat
|
558
|
+
|
559
|
+
Pewnie zastanawiasz się jaka jest różnica pomiędzy _autorem_ a _zatwierdzającym_zmiany_. Autor to osoba, która oryginalnie stworzyła pracę a zatwierdzający zmiany to osoba, która ostatnia wprowadziła modyfikacje do drzewa. Jeśli zatem wysyłasz do projektu łatkę a następnie któryś z jego członków nanosi ją na projekt, oboje zastajecie zapisani w historii - ty jako autor, a członek zespołu jako osoba zatwierdzająca. Powiemy więcej o tym rozróżnieniu w rozdziale 5.
|
560
|
+
|
561
|
+
Wspomniana już wcześniej opcja `oneline` jest szczególnie przydatna w parze z z inną, a mianowicie, `--graph`. Tworzy ona mały, śliczny graf ASCII pokazujący historię gałęzi oraz scaleń, co w pełnej krasie można zobaczyć na kopii repozytorium Grita:
|
562
|
+
|
563
|
+
$ git log --pretty=format:"%h %s" --graph
|
564
|
+
* 2d3acf9 ignore errors from SIGCHLD on trap
|
565
|
+
* 5e3ee11 Merge branch 'master' of git://github.com/dustin/grit
|
566
|
+
|\
|
567
|
+
| * 420eac9 Added a method for getting the current branch.
|
568
|
+
* | 30e367c timeout code and tests
|
569
|
+
* | 5a09431 add timeout protection to grit
|
570
|
+
* | e1193f8 support for heads with slashes in them
|
571
|
+
|/
|
572
|
+
* d6016bc require time for xmlschema
|
573
|
+
* 11d191e Merge branch 'defunkt' into local
|
574
|
+
|
575
|
+
Są to jedynie podstawowe opcje formatowania wyjścia polecenia `git log` - jest ich znacznie więcej. Tabela 2-2 uwzględnia zarówno te które już poznałeś oraz inne, często wykorzystywane, wraz ze opisem każdej z nich.
|
576
|
+
|
577
|
+
Opcja Opis
|
578
|
+
-p Pokaż pod każdą zmianą powiązaną łatkę
|
579
|
+
--stat Pokaż pod każdą zmianą statystyki zmodyfikowanych plików
|
580
|
+
--shortstat Pokaż wyłącznie zmienione/wstawione/usunięte linie z polecenia --stat
|
581
|
+
--name-only Pokaż pod każdą zmianą listę zmodyfikowanych plików
|
582
|
+
--name-status Pokaż listę plików o dodanych/zmodyfikowanych/usuniętych informacjach.
|
583
|
+
--abbrev-commit Pokaż tylko pierwsze kilka znaków (zamiast 40-tu) sumy kontrolnej SHA-1.
|
584
|
+
--relative-date Pokaż datę w formacie względnym (np. 2 tygodnie temu)
|
585
|
+
--graph Pokaż graf ASCII gałęzi oraz historię scaleń obok wyniku.
|
586
|
+
--pretty Pokaż zatwierdzone zmiany w poprawionym formacie. Dostępne opcje obejmują oneline, short, full, fuller oraz format (gdzie określa własny format)
|
587
|
+
|
588
|
+
### Ograniczanie wyniku historii ###
|
589
|
+
|
590
|
+
Jako dodatek do opcji formatowania, git log przyjmuje także zestaw parametrów ograniczających wynik do określonego podzbioru. Jeden z takich parametrów pokazaliśmy już wcześniej: opcja `-2`, która spowodowała pokazanie jedynie dwóch ostatnich rewizji. Oczywiście, możesz podać ich dowolną liczbę - `-<n>`, gdzie `n` jest liczbą całkowitą. Na co dzień raczej nie będziesz używał jej zbyt często, ponieważ Git domyślnie przekazuje wynik do narzędzia stronicującego, w skutek czego i tak jednocześnie widzisz tylko jedną jego stronę.
|
591
|
+
|
592
|
+
Inaczej jest z w przypadku opcji ograniczania w czasie takich jak `--since` (od) oraz `--until` (do) które są wyjątkowo przydatne. Na przykład, poniższe polecenie pobiera listę zmian dokonanych w ciągu ostatnich dwóch tygodni:
|
593
|
+
|
594
|
+
$ git log --since=2.weeks
|
595
|
+
|
596
|
+
Polecenie to obsługuje mnóstwo formatów - możesz uściślić konkretną datę (np. "2008-01-15") lub podać datę względną jak np. 2 lata 1 dzień 3 minuty temu.
|
597
|
+
|
598
|
+
Możesz także odfiltrować listę pozostawiając jedynie rewizje spełniające odpowiednie kryteria wyszukiwania. Opcja `--author` pozwala wybierać po konkretnym autorze, a opcja `--grep` na wyszukiwanie po słowach kluczowych zawartych w notkach zmian. (Zauważ, że jeżeli potrzebujesz określić zarówno autora jak i słowa kluczowe, musisz dodać opcję `--all-match` - w przeciwnym razie polecenie dopasuje jedynie wg jednego z kryteriów).
|
599
|
+
|
600
|
+
Ostatnią, szczególnie przydatną opcją, akceptowaną przez `git log` jako filtr, jest ścieżka. Możesz dzięki niej ograniczyć wynik wyłącznie do rewizji, które modyfikują podane pliki. Jest to zawsze ostatnia w kolejności opcja i musi być poprzedzona podwójnym myślnikiem `--`, tak żeby oddzielić ścieżki od pozostałych opcji.
|
601
|
+
|
602
|
+
W tabeli 2-3 znajduje się ta jak i kilka innych często używanych opcji.
|
603
|
+
|
604
|
+
Opcja Opis
|
605
|
+
-(n) Pokaż tylko ostatnie n rewizji.
|
606
|
+
--since, --after Ogranicza rewizje do tych wykonanych po określonej dacie.
|
607
|
+
--until, --before Ogranicza rewizje do tych wykonanych przed określoną datą.
|
608
|
+
--author Pokazuje rewizje, których wpis autora pasuje do podanego.
|
609
|
+
--committer Pokazuje jedynie te rewizje w których osoba zatwierdzająca zmiany pasuje do podanej.
|
610
|
+
|
611
|
+
Na przykład, żeby zobaczyć wyłącznie rewizje modyfikujące pliki testowe w historii plików źródłowych Git-a zatwierdzonych przez Junio Hamano, ale nie zespolonych w październiku 2008, możesz użyć następującego polecenia:
|
612
|
+
|
613
|
+
$ git log --pretty="%h - %s" --author=gitster --since="2008-10-01" \
|
614
|
+
--before="2008-11-01" --no-merges -- t/
|
615
|
+
5610e3b - Fix testcase failure when extended attribute
|
616
|
+
acd3b9e - Enhance hold_lock_file_for_{update,append}()
|
617
|
+
f563754 - demonstrate breakage of detached checkout wi
|
618
|
+
d1a43f2 - reset --hard/read-tree --reset -u: remove un
|
619
|
+
51a94af - Fix "checkout --track -b newbranch" on detac
|
620
|
+
b0ad11e - pull: allow "git pull origin $something:$cur
|
621
|
+
|
622
|
+
Z prawie 20000 rewizji w historii kodu Gita, podane polecenie wyłowiło jedynie 6 spełniających zadane kryteria.
|
623
|
+
|
624
|
+
### Wizualizacja historii w interfejsie graficznym ###
|
625
|
+
|
626
|
+
Do wyświetlania historii rewizji możesz także użyć narzędzi okienkowych - być może spodoba ci się na przykład napisany w Tcl/Tk program o nazwie gitk, który jest dystrybuowany wraz z Gitem. Gitk to proste narzędzie do wizualizacji wyniku polecenia `git log` i akceptuje ono prawie wszystkie, wcześniej wymienione, opcje filtrowania. Po uruchomieniu gitk z linii poleceń powinieneś zobaczyć okno podobne do widocznego na ekranie 2-2.
|
627
|
+
|
628
|
+
Insert 18333fig0202.png
|
629
|
+
Figure 2-2. Graficzny interfejs programu gitk przedstawiający historię rewizji.
|
630
|
+
|
631
|
+
Historia wraz z grafem przodków znajduje się w górnej połówce okna. W dolnej części znajdziesz przeglądarkę różnic pokazującą zmiany wnoszone przez wybraną rewizję.
|
632
|
+
|
633
|
+
## Cofanie zmian ##
|
634
|
+
|
635
|
+
Każdą z wcześniej wprowadzonych zmian możesz cofnąć w dowolnym momencie. Poniżej przyjrzymy się kilku podstawowym funkcjom cofającym modyfikacje. Musisz być jednak ostrożny ponieważ nie zawsze można cofnąć niektóre z tych cofnięć [FIXME]. Jest to jedno z niewielu miejsc w Gitcie, w których należy być naprawdę ostrożnym, gdyż można stracić bezpowrotnie część pracy.
|
636
|
+
|
637
|
+
### Poprawka do ostatniej rewizji ###
|
638
|
+
|
639
|
+
Jeden z częstych przypadków to zbyt pochopne wykonanie rewizji i pominięcie w niej części plików, lub też pomyłka w notce do zmian. Jeśli chcesz poprawić wcześniejszą, błędną rewizję, wystarczy uruchomić git commit raz jeszcze, tym razem, z opcją `--amend` (popraw):
|
640
|
+
|
641
|
+
$ git commit --amend
|
642
|
+
|
643
|
+
Polecenie bierze zawartość poczekalni i zatwierdza jako dodatkowe zmiany. Jeśli niczego nie zmieniłeś od ostatniej rewizji (np. uruchomiłeś polecenie zaraz po poprzednim zatwierdzeniu zmian) wówczas twoja migawka się nie zmieni ale będziesz miał możliwość modyfikacji notki.
|
644
|
+
|
645
|
+
Jak zwykle zostanie uruchomiony edytor z załadowaną treścią poprzedniego komentarza. Edycja przebiega dokładnie tak samo jak zawsze, z tą różnicą, że na końcu zostanie nadpisana oryginalna treść notki.
|
646
|
+
|
647
|
+
Czas na przykład. Zatwierdziłeś zmiany a następnie zdałeś sobie sprawę, że zapomniałeś dodać do poczekalni pliku, który chciałeś oryginalnie umieścić w wykonanej rewizji. Wystarczy, że wykonasz następujące polecenie:
|
648
|
+
|
649
|
+
$ git commit -m 'initial commit'
|
650
|
+
$ git add forgotten_file
|
651
|
+
$ git commit --amend
|
652
|
+
|
653
|
+
Wszystkie trzy polecenia zakończą się jedną rewizją - druga operacja commit zastąpi wynik pierwszej.
|
654
|
+
|
655
|
+
### Usuwanie pliku z poczekalni ###
|
656
|
+
|
657
|
+
Następne dwie sekcje pokazują jak zarządzać poczekalnią i zmianami w katalogu roboczym. Dobra wiadomość jest taka, że polecenie używane do określenia stanu obu obszarów przypomina samo jak cofnąć wprowadzone w nich zmiany. Na przykład, powiedzmy, że zmieniłeś dwa pliki i chcesz teraz zatwierdzić je jako dwie osobne rewizje, ale odruchowo wpisałeś `git add *` co spowodowało umieszczenie obu plików w poczekalni. Jak w takiej sytuacji usunąć stamtąd jeden z nich? Polecenie `git status` przypomni ci, że:
|
658
|
+
|
659
|
+
$ git add .
|
660
|
+
$ git status
|
661
|
+
# On branch master
|
662
|
+
# Changes to be committed:
|
663
|
+
# (use "git reset HEAD <file>..." to unstage)
|
664
|
+
#
|
665
|
+
# modified: README.txt
|
666
|
+
# modified: benchmarks.rb
|
667
|
+
#
|
668
|
+
|
669
|
+
Tekst znajdujący się zaraz pod nagłówkiem zmian do zatwierdzenia mówi "użyj `git reset HEAD <plik>...` żeby usunąć plik z poczekalni. Nie pozostaje więc nic innego jak zastosować się do porady i zastosować ją na pliku benchmarks.rb:
|
670
|
+
|
671
|
+
$ git reset HEAD benchmarks.rb
|
672
|
+
benchmarks.rb: locally modified
|
673
|
+
$ git status
|
674
|
+
# On branch master
|
675
|
+
# Changes to be committed:
|
676
|
+
# (use "git reset HEAD <file>..." to unstage)
|
677
|
+
#
|
678
|
+
# modified: README.txt
|
679
|
+
#
|
680
|
+
# Changes not staged for commit:
|
681
|
+
# (use "git add <file>..." to update what will be committed)
|
682
|
+
# (use "git checkout -- <file>..." to discard changes in working directory)
|
683
|
+
#
|
684
|
+
# modified: benchmarks.rb
|
685
|
+
#
|
686
|
+
|
687
|
+
Polecenie wygląda odrobinę dziwacznie, ale działa. Plik benchmarks.rb ciągle zawiera wprowadzone modyfikacje ale nie znajduje się już w poczekalni.
|
688
|
+
|
689
|
+
### Cofanie zmian w zmodyfikowanym pliku ###
|
690
|
+
|
691
|
+
Co jeśli okaże się, że nie chcesz jednak zatrzymać zmian wykonanych w pliku benchmarks.rb? W jaki sposób łatwo cofnąć wprowadzone modyfikacje czyli przywrócić plik do stanu w jakim był po ostatniej rewizji (lub początkowym sklonowaniu, lub jakkolwiek dostał się do katalogu roboczego)? Z pomocą przybywa raz jeszcze polecenie `git status`. W ostatnim przykładzie, pliki będące poza poczekalnią wyglądają następująco:
|
692
|
+
|
693
|
+
# Changes not staged for commit:
|
694
|
+
# (use "git add <file>..." to update what will be committed)
|
695
|
+
# (use "git checkout -- <file>..." to discard changes in working directory)
|
696
|
+
#
|
697
|
+
# modified: benchmarks.rb
|
698
|
+
#
|
699
|
+
|
700
|
+
Git konkretnie wskazuje jak pozbyć się dokonanych zmian (w każdym bądź razie robią to wersje Gita 1.6.1 i nowsze - jeśli posiadasz starszą, bardzo zalecamy aktualizację, która ułatwi ci korzystanie z programu). Zróbmy zatem co każe Git:
|
701
|
+
|
702
|
+
$ git checkout -- benchmarks.rb
|
703
|
+
$ git status
|
704
|
+
# On branch master
|
705
|
+
# Changes to be committed:
|
706
|
+
# (use "git reset HEAD <file>..." to unstage)
|
707
|
+
#
|
708
|
+
# modified: README.txt
|
709
|
+
#
|
710
|
+
|
711
|
+
Możesz teraz przeczytać, że zmiany zostały cofnięte. Powinieneś sobie już także zdawać sprawę, że jest to dość niebezpieczne polecenie: wszelkie zmiany jakie wykonałeś w pliku przepadają - w rzeczy samej został on nadpisany poprzednią wersją. Nigdy nie używaj tego polecenia dopóki nie jesteś absolutnie pewny, że nie chcesz i nie potrzebujesz już danego pliku. Jeśli jedynie chcesz się go chwilowo pozbyć przyjrzymy się specjalnemu poleceniu schowka (stash) oraz gałęziom w kolejnych rozdziałach - są to generalnie znacznie lepsze sposoby.
|
712
|
+
|
713
|
+
Pamiętaj, że wszystko co zatwierdzasz do repozytorium Gita może zostać w niemalże dowolnym momencie odtworzone. Nawet rewizje, które znajdowały się w usuniętych gałęziach, albo rewizje nadpisane zatwierdzeniem poprawiającym `--amend` mogą być odtworzone (odzyskiwanie danych opisujemy w rozdziale 9). Jednakże, cokolwiek utraciłeś a nie było to nigdy wcześniej zatwierdzane do repozytorium, prawdopodobnie odeszło na zawsze.
|
714
|
+
|
715
|
+
## Praca ze zdalnym repozytorium ##
|
716
|
+
|
717
|
+
Żeby móc współpracować za pośrednictwem Gita z innymi ludźmi, w jakimkolwiek projekcie, musisz nauczyć się zarządzać zdalnymi repozytoriami. Zdalne repozytorium to wersja twojego projektu utrzymywana na serwerze dostępnym poprzez Internet lub inną sieć. Możesz mieć ich kilka, z których każde może być tylko do odczytu lub zarówno odczytu jak i zapisu. Współpraca w grupie zakłada zarządzanie zdalnymi repozytoriami oraz wypychanie zmian na zewnątrz i pobieranie ich w celu współdzielenia pracy/kodu.
|
718
|
+
Zarządzanie zdalnymi repozytoriami obejmuje umiejętność dodawania zdalnych repozytoriów, usuwania ich jeśli nie są dłużej poprawne, zarządzania zdalnymi gałęziami oraz definiowania je jako śledzone lub nie, i inne. Zajmiemy się tym wszystkim w niniejszym rozdziale.
|
719
|
+
|
720
|
+
### Wyświetlanie zdalnych repozytoriów ###
|
721
|
+
|
722
|
+
Aby zobaczyć obecnie skonfigurowane serwery możesz uruchomić polecenie `git remote`. Pokazuje ono skrócone nazwy wszystkich określonych przez ciebie serwerów. Jeśli sklonowałeś swoje repozytorium, powinieneś przynajmniej zobaczyć origin (źródło) - nazwa domyślna którą Git nadaje serwerowi z którego klonujesz projekt:
|
723
|
+
|
724
|
+
$ git clone git://github.com/schacon/ticgit.git
|
725
|
+
Initialized empty Git repository in /private/tmp/ticgit/.git/
|
726
|
+
remote: Counting objects: 595, done.
|
727
|
+
remote: Compressing objects: 100% (269/269), done.
|
728
|
+
remote: Total 595 (delta 255), reused 589 (delta 253)
|
729
|
+
Receiving objects: 100% (595/595), 73.31 KiB | 1 KiB/s, done.
|
730
|
+
Resolving deltas: 100% (255/255), done.
|
731
|
+
$ cd ticgit
|
732
|
+
$ git remote
|
733
|
+
origin
|
734
|
+
|
735
|
+
Dodanie parametru `-v` spowoduje dodatkowo wyświetlenie przypisanego do skrótu, pełnego, zapamiętanego przez Gita, adresu URL:
|
736
|
+
|
737
|
+
$ git remote -v
|
738
|
+
origin git://github.com/schacon/ticgit.git
|
739
|
+
|
740
|
+
Jeśli posiadasz więcej niż jedno zdalne repozytorium polecenie wyświetli je wszystkie. Na przykład, moje repozytorium z Gritem wygląda następująco:
|
741
|
+
|
742
|
+
$ cd grit
|
743
|
+
$ git remote -v
|
744
|
+
bakkdoor git://github.com/bakkdoor/grit.git
|
745
|
+
cho45 git://github.com/cho45/grit.git
|
746
|
+
defunkt git://github.com/defunkt/grit.git
|
747
|
+
koke git://github.com/koke/grit.git
|
748
|
+
origin git@github.com:mojombo/grit.git
|
749
|
+
|
750
|
+
Oznacza to, że możesz szybko i łatwo pobrać zmiany z każdego z nich. Zauważ jednak, że tylko oryginalne źródło (origin) jest adresem URL SSH, więc jest jedynym do którego mogę wysyłać własne zmiany (w szczegółach zajmiemy się tym tematem w rozdziale 4).
|
751
|
+
|
752
|
+
### Dodawanie zdalnych repozytoriów ###
|
753
|
+
|
754
|
+
W poprzednich sekcjach jedynie wspomniałem o dodawaniu zdalnych repozytoriów, teraz pokażę jak to zrobić to samemu. Aby dodać zdalne repozytorium jako skrót, do którego z łatwością będziesz się mógł odnosić w przyszłości, uruchom polecenie `git remote add [skrót] [url]`:
|
755
|
+
|
756
|
+
$ git remote
|
757
|
+
origin
|
758
|
+
$ git remote add pb git://github.com/paulboone/ticgit.git
|
759
|
+
$ git remote -v
|
760
|
+
origin git://github.com/schacon/ticgit.git
|
761
|
+
pb git://github.com/paulboone/ticgit.git
|
762
|
+
|
763
|
+
Teraz możesz używać nazwy pb zamiast całego adresu URL. Na przykład, jeżeli chcesz pobrać wszystkie informacje, które posiada Paul, a których ty jeszcze nie masz, możesz uruchomić polecenie fetch wraz z parametrem pb:
|
764
|
+
|
765
|
+
$ git fetch pb
|
766
|
+
remote: Counting objects: 58, done.
|
767
|
+
remote: Compressing objects: 100% (41/41), done.
|
768
|
+
remote: Total 44 (delta 24), reused 1 (delta 0)
|
769
|
+
Unpacking objects: 100% (44/44), done.
|
770
|
+
From git://github.com/paulboone/ticgit
|
771
|
+
* [new branch] master -> pb/master
|
772
|
+
* [new branch] ticgit -> pb/ticgit
|
773
|
+
|
774
|
+
Główna gałąź (master) Paula jest dostępna lokalnie jako `pb/master` - możesz scalić ją do którejś z własnych gałęzi lub, jeśli chcesz, jedynie ją przejrzeć przełączając się do lokalnej gałęzi.
|
775
|
+
|
776
|
+
### Pobieranie i wciąganie zmian ze zdalnych repozytoriów (polecenia fetch i pull) ###
|
777
|
+
|
778
|
+
Jak przed chwilą zobaczyłeś aby uzyskać dane ze zdalnego projektu wystarczy uruchomić:
|
779
|
+
|
780
|
+
$ git fetch [nazwa-zdalengo-repozytorium]
|
781
|
+
|
782
|
+
Polecenie to sięga do zdalnego projektu i pobiera z niego wszystkie dane, których jeszcze nie masz. Po tej operacji, powinieneś mieć już odnośniki do wszystkich zdalnych gałęzi, które możesz teraz scalić z własnymi plikami lub sprawdzić ich zawartość. (Gałęziami oraz ich obsługą zajmiemy się w szczegółach w rozdziale 3).
|
783
|
+
|
784
|
+
Po sklonowaniu repozytorium automatycznie zostanie dodany skrót o nazwie origin wskazujący na oryginalną lokalizację. Tak więc, `git fetch origin` pobierze każdą nową pracę jaka została wypchnięta na oryginalny serwer od momentu sklonowania go przez ciebie (lub ostatniego pobrania zmian). Warto zauważyć, że polecenie fetch pobiera dane do lokalnego repozytorium - nie scala jednak automatycznie zmian z żadnym z twoich plików roboczych jak i w żaden inny sposób tych plików nie modyfikuje. Musisz scalić wszystkie zmiany ręcznie, kiedy będziesz już do tego gotowy.
|
785
|
+
|
786
|
+
Jeśli twoja gałąź lokalna jest ustawiona tak, żeby śledzić zdalną gałąź (więcej informacji na ten temat znajdziesz w następnej sekcji, rozdziale 3), wystarczy użyć polecenia `git pull`, żeby automatycznie pobrać dane (fetch) i je scalić (merge) z lokalnymi plikami. Może być to dla ciebie wygodniejsze; domyślnie, polecenie `git clone` ustawia twoją lokalną gałąź główną master tak aby śledziła zmiany w zdalnej gałęzi master na serwerze z którego sklonowałeś repozytorium (zakładając, że zdalne repozytorium posiada gałąź master). Uruchomienie `git pull`, ogólnie mówiąc, pobiera dane z serwera na bazie którego oryginalnie stworzyłeś swoje repozytorium i próbuje automatycznie scalić zmiany z kodem roboczym nad którym aktualnie, lokalnie pracujesz.
|
787
|
+
|
788
|
+
### Wypychanie zmian na zewnątrz ###
|
789
|
+
|
790
|
+
Jeśli doszedłeś z projektem do tego przyjemnego momentu, kiedy możesz i chcesz już podzielić się swoją pracą z innymi, wystarczy, że wypchniesz swoje zmiany na zewnątrz. Służące do tego polecenie jest proste `git push [nazwa-zdalnego-repo] [nazwa-gałęzi]`. Jeśli chcesz wypchnąć gałąź główną master na oryginalny serwer źródłowy `origin` (ponownie, klonowanie ustawia obie te nazwy - master i origin - domyślnie i automatycznie), możesz uruchomić następujące polecenie:
|
791
|
+
|
792
|
+
$ git push origin master
|
793
|
+
|
794
|
+
Polecenie zadziała tylko jeśli sklonowałeś repozytorium z serwera do którego masz prawo zapisu oraz jeśli nikt inny w międzyczasie nie wypchnął własnych zmian. Jeśli zarówno ty jak i inna osoba sklonowały dane w tym samym czasie, po czym ta druga osoba wypchnęła własne zmiany, a następnie ty próbujesz zrobić to samo z własnymi modyfikacjami, twoja próba zostanie od razu odrzucona. Będziesz musiał najpierw zespolić (pobrać i scalić) najnowsze zmiany ze zdalnego repozytorium zanim będziesz mógł wypchnąć własne. Więcej szczegółów na temat wypychania zmian dowiesz się z rozdziału 3.
|
795
|
+
|
796
|
+
### Inspekcja zdalnych zmian ###
|
797
|
+
|
798
|
+
Jeśli chcesz zobaczyć więcej informacji o konkretnym zdalnym repozytorium, użyj polecenia `git remote show [nazwa-zdalnego-repo]`. Uruchamiając je z konkretnym skrótem, jak np. `origin`, zobaczysz mniej więcej coś takiego:
|
799
|
+
|
800
|
+
$ git remote show origin
|
801
|
+
* remote origin
|
802
|
+
URL: git://github.com/schacon/ticgit.git
|
803
|
+
Remote branch merged with 'git pull' while on branch master
|
804
|
+
master
|
805
|
+
Tracked remote branches
|
806
|
+
master
|
807
|
+
ticgit
|
808
|
+
|
809
|
+
Informacja zawiera adres URL zdalnego repozytorium oraz informacje o śledzonej gałęzi. Polecenie mówi także, że jeśli znajdujesz się w gałęzi master i uruchomisz polecenie `git pull`, zmiany ze zdalnego repozytorium zaraz po pobraniu automatycznie zostaną scalone z gałęzią master w twoim, lokalnym repozytorium. Polecenie listuje także wszystkie pobrane zdalne odnośniki.
|
810
|
+
|
811
|
+
Poniżej znajdziesz prosty przykład na który, pewnie w nieco innej wersji, ale sam się wkrótce natkniesz. Używając intensywnie Gita, możesz zobaczyć znacznie więcej informacji w wyniku działania polecenia `git remote show`:
|
812
|
+
|
813
|
+
$ git remote show origin
|
814
|
+
* remote origin
|
815
|
+
URL: git@github.com:defunkt/github.git
|
816
|
+
Remote branch merged with 'git pull' while on branch issues
|
817
|
+
issues
|
818
|
+
Remote branch merged with 'git pull' while on branch master
|
819
|
+
master
|
820
|
+
New remote branches (next fetch will store in remotes/origin)
|
821
|
+
caching
|
822
|
+
Stale tracking branches (use 'git remote prune')
|
823
|
+
libwalker
|
824
|
+
walker2
|
825
|
+
Tracked remote branches
|
826
|
+
acl
|
827
|
+
apiv2
|
828
|
+
dashboard2
|
829
|
+
issues
|
830
|
+
master
|
831
|
+
postgres
|
832
|
+
Local branch pushed with 'git push'
|
833
|
+
master:master
|
834
|
+
|
835
|
+
Przywołane polecenie pokazuje która gałąź zostanie automatycznie wypchnięta po uruchomieniu `git push` na poszczególnych gałęziach. Zobaczysz także, których zdalnych gałęzi z serwera jeszcze nie posiadasz, które z nich już masz ale z kolei nie ma ich już na serwerze oraz gałęzie, które zostaną automatycznie scalone po uruchomieniu `git pull`.
|
836
|
+
|
837
|
+
### Usuwanie i zmiana nazwy zdalnych repozytoriów ###
|
838
|
+
|
839
|
+
Aby zmienić nazwę odnośnika, czyli skrótu przypisanego do repozytorium, w nowszych wersjach Gita możesz uruchomić `git remote rename`. Na przykład, aby zmienić nazwę `pb` na `paul`, wystarczy, że uruchomisz polecenie `git remote rename` w poniższy sposób:
|
840
|
+
|
841
|
+
$ git remote rename pb paul
|
842
|
+
$ git remote
|
843
|
+
origin
|
844
|
+
paul
|
845
|
+
|
846
|
+
Warto wspomnieć, że polecenie zmienia także nazwy zdalnych gałęzi. To co do tej pory było określane jako `pb/master` od teraz powinno być adresowane jako `paul/master`.
|
847
|
+
|
848
|
+
Jeśli z jakiegoś powodu chcesz usunąć odnośnik - przeniosłeś serwer czy dłużej nie korzystasz z konkretnego mirror-a, albo współpracownik nie udziela się już dłużej w projekcie - możesz skorzystać z `git remote rm`:
|
849
|
+
|
850
|
+
$ git remote rm paul
|
851
|
+
$ git remote
|
852
|
+
origin
|
853
|
+
|
854
|
+
## Tagowanie (etykietowanie) ##
|
855
|
+
|
856
|
+
Podobnie jak większość systemów kontroli wersji, Git posiada możliwość etykietowania konkretnych, ważnych miejsc w historii. Ogólnie, większość użytkowników korzysta z tej możliwości do zaznaczania ważnych wersji kodu (np. wersja 1.0, itd.). Z tego rozdziału dowiesz się jak wyświetlać dostępne etykiety, jak tworzyć nowe oraz jakie rodzaje tagów rozróżniamy.
|
857
|
+
|
858
|
+
### Listowanie etykiet ###
|
859
|
+
|
860
|
+
Wyświetlanie wszystkich dostępnych tagów w Gitcie jest bardzo proste. Wystarczy uruchomić `git tag`:
|
861
|
+
|
862
|
+
$ git tag
|
863
|
+
v0.1
|
864
|
+
v1.3
|
865
|
+
|
866
|
+
Polecenie wyświetla etykiety w porządku alfabetycznym; porządek w jakim się pojawią nie ma jednak faktycznego znaczenia.
|
867
|
+
|
868
|
+
Możesz także wyszukiwać etykiety za pomocą wzorca. Na przykład, repozytorium kodu źródłowego Gita zawiera ponad 240 tagów. Jeśli interesuje cię np. wyłącznie seria 1.4.2, możesz ją wyszukać w następujący sposób:
|
869
|
+
|
870
|
+
$ git tag -l 'v1.4.2.*'
|
871
|
+
v1.4.2.1
|
872
|
+
v1.4.2.2
|
873
|
+
v1.4.2.3
|
874
|
+
v1.4.2.4
|
875
|
+
|
876
|
+
### Tworzenie etykiet ###
|
877
|
+
|
878
|
+
Git używa 2 głównych rodzajów etykiet: lekkich i opisanych. Pierwsze z nich - lekkie - zachowują się mniej więcej tak jak gałąź, która się nie zmienia - jest to tylko wskaźnik do konkretnej rewizji. Z kolei, etykiety opisane są przechowywane jako pełne obiekty w bazie danych Gita. Są one opatrywane sumą kontrolną, zawierają nazwisko osoby etykietującej, jej adres e-mail oraz datę; ponadto, posiadają notkę etykiety, oraz mogą być podpisywane i weryfikowane za pomocą GNU Privacy Guard (GPG). Ogólnie zaleca się aby przy tworzeniu etykiet opisanych uwzględniać wszystkie te informacje; a jeżeli potrzebujesz jedynie etykiety tymczasowej albo z innych powodów nie potrzebujesz tych wszystkich danych, możesz po prostu użyć etykiety lekkiej.
|
879
|
+
|
880
|
+
### Etykiety opisane ###
|
881
|
+
|
882
|
+
Tworzenie etykiety opisanej, jak większość rzeczy w Gitcie, jest proste. Wystarczy podać parametr `-a` podczas uruchamiania polecenia `tag`:
|
883
|
+
|
884
|
+
$ git tag -a v1.4 -m 'my version 1.4'
|
885
|
+
$ git tag
|
886
|
+
v0.1
|
887
|
+
v1.3
|
888
|
+
v1.4
|
889
|
+
|
890
|
+
Parametr `-m` określa notkę etykiety, która jest wraz z nią przechowywania. Jeśli nie podasz treści notki dla etykiety opisowej, Git uruchomi twój edytor tekstu gdzie będziesz mógł ją dodać.
|
891
|
+
|
892
|
+
Dane etykiety wraz z tagowaną rewizją możesz zobaczyć używając polecenia `git show`:
|
893
|
+
|
894
|
+
$ git show v1.4
|
895
|
+
tag v1.4
|
896
|
+
Tagger: Scott Chacon <schacon@gee-mail.com>
|
897
|
+
Date: Mon Feb 9 14:45:11 2009 -0800
|
898
|
+
|
899
|
+
my version 1.4
|
900
|
+
commit 15027957951b64cf874c3557a0f3547bd83b3ff6
|
901
|
+
Merge: 4a447f7... a6b4c97...
|
902
|
+
Author: Scott Chacon <schacon@gee-mail.com>
|
903
|
+
Date: Sun Feb 8 19:02:46 2009 -0800
|
904
|
+
|
905
|
+
Merge branch 'experiment'
|
906
|
+
|
907
|
+
Jak widać została wyświetlona informacja o osobie etykietującej, data stworzenia etykiety, oraz notka poprzedzająca informacje o rewizji:
|
908
|
+
|
909
|
+
### Podpisane etykiety ###
|
910
|
+
|
911
|
+
Swoją etykietę możesz podpisać prywatnym kluczem używając GPG. Wystarczy w tym celu użyć parametru `-s` zamiast `-a`:
|
912
|
+
|
913
|
+
$ git tag -s v1.5 -m 'my signed 1.5 tag'
|
914
|
+
You need a passphrase to unlock the secret key for
|
915
|
+
user: "Scott Chacon <schacon@gee-mail.com>"
|
916
|
+
1024-bit DSA key, ID F721C45A, created 2009-02-09
|
917
|
+
|
918
|
+
Po uruchomieniu na etykiecie polecenia `git show`, zobaczysz, że został dołączony do niej podpis GPG:
|
919
|
+
|
920
|
+
$ git show v1.5
|
921
|
+
tag v1.5
|
922
|
+
Tagger: Scott Chacon <schacon@gee-mail.com>
|
923
|
+
Date: Mon Feb 9 15:22:20 2009 -0800
|
924
|
+
|
925
|
+
my signed 1.5 tag
|
926
|
+
-----BEGIN PGP SIGNATURE-----
|
927
|
+
Version: GnuPG v1.4.8 (Darwin)
|
928
|
+
|
929
|
+
iEYEABECAAYFAkmQurIACgkQON3DxfchxFr5cACeIMN+ZxLKggJQf0QYiQBwgySN
|
930
|
+
Ki0An2JeAVUCAiJ7Ox6ZEtK+NvZAj82/
|
931
|
+
=WryJ
|
932
|
+
-----END PGP SIGNATURE-----
|
933
|
+
commit 15027957951b64cf874c3557a0f3547bd83b3ff6
|
934
|
+
Merge: 4a447f7... a6b4c97...
|
935
|
+
Author: Scott Chacon <schacon@gee-mail.com>
|
936
|
+
Date: Sun Feb 8 19:02:46 2009 -0800
|
937
|
+
|
938
|
+
Merge branch 'experiment'
|
939
|
+
|
940
|
+
Nieco później, zobaczysz w jaki sposób można weryfikować podpisane etykiety.
|
941
|
+
|
942
|
+
### Etykiety lekkie ###
|
943
|
+
|
944
|
+
Innym sposobem na tagowanie rewizji są etykiety lekkie. Jest to w rzeczy samej suma kontrolna rewizji przechowywana w pliku - nie są przechowywane żadne inne, dodatkowe informacje. Aby stworzyć lekką etykietę, nie przekazuj do polecenia tag żadnego z parametrów `-a`, `-s` czy `-m`:
|
945
|
+
|
946
|
+
$ git tag v1.4-lw
|
947
|
+
$ git tag
|
948
|
+
v0.1
|
949
|
+
v1.3
|
950
|
+
v1.4
|
951
|
+
v1.4-lw
|
952
|
+
v1.5
|
953
|
+
|
954
|
+
Uruchamiając teraz na etykiecie `git show` nie zobaczysz żadnych dodatkowych informacji. Polecenie wyświetli jedynie:
|
955
|
+
|
956
|
+
$ git show v1.4-lw
|
957
|
+
commit 15027957951b64cf874c3557a0f3547bd83b3ff6
|
958
|
+
Merge: 4a447f7... a6b4c97...
|
959
|
+
Author: Scott Chacon <schacon@gee-mail.com>
|
960
|
+
Date: Sun Feb 8 19:02:46 2009 -0800
|
961
|
+
|
962
|
+
Merge branch 'experiment'
|
963
|
+
|
964
|
+
### Weryfikowanie etykiet ###
|
965
|
+
|
966
|
+
Do weryfikacji etykiety używa się polecenia `git tag -v [nazwa-etykiety]`. Polecenie używa GPG do zweryfikowania podpisu. Żeby mogło zadziałać poprawnie potrzebujesz oczywiście publicznego klucza osoby podpisującej w swoim keyring-u:
|
967
|
+
|
968
|
+
$ git tag -v v1.4.2.1
|
969
|
+
object 883653babd8ee7ea23e6a5c392bb739348b1eb61
|
970
|
+
type commit
|
971
|
+
tag v1.4.2.1
|
972
|
+
tagger Junio C Hamano <junkio@cox.net> 1158138501 -0700
|
973
|
+
|
974
|
+
GIT 1.4.2.1
|
975
|
+
|
976
|
+
Minor fixes since 1.4.2, including git-mv and git-http with alternates.
|
977
|
+
gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
|
978
|
+
gpg: Good signature from "Junio C Hamano <junkio@cox.net>"
|
979
|
+
gpg: aka "[jpeg image of size 1513]"
|
980
|
+
Primary key fingerprint: 3565 2A26 2040 E066 C9A7 4A7D C0C6 D9A4 F311 9B9A
|
981
|
+
|
982
|
+
Jeśli nie posiadasz klucza publicznego osoby podpisującej, otrzymasz następujący komunikat:
|
983
|
+
|
984
|
+
gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
|
985
|
+
gpg: Can't check signature: public key not found
|
986
|
+
error: could not verify the tag 'v1.4.2.1'
|
987
|
+
|
988
|
+
### Etykietowanie historii ###
|
989
|
+
|
990
|
+
Możesz także etykietować historyczne rewizje. Załóżmy, że historia zmian wygląda następująco:
|
991
|
+
|
992
|
+
$ git log --pretty=oneline
|
993
|
+
15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
|
994
|
+
a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support
|
995
|
+
0d52aaab4479697da7686c15f77a3d64d9165190 one more thing
|
996
|
+
6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'experiment'
|
997
|
+
0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc added a commit function
|
998
|
+
4682c3261057305bdd616e23b64b0857d832627b added a todo file
|
999
|
+
166ae0c4d3f420721acbb115cc33848dfcc2121a started write support
|
1000
|
+
9fceb02d0ae598e95dc970b74767f19372d61af8 updated rakefile
|
1001
|
+
964f16d36dfccde844893cac5b347e7b3d44abbc commit the todo
|
1002
|
+
8a5cbc430f1a9c3d00faaeffd07798508422908a updated readme
|
1003
|
+
|
1004
|
+
Teraz, załóżmy, że zapomniałeś oznaczyć projektu jako wersja 1.2, do której przeszedł on wraz z rewizją "updated rakefile". Możesz dodać etykietę już po fakcie. W tym celu wystarczy na końcu polecenia `git tag` podać sumę kontrolną lub jej część wskazującą na odpowiednią rewizję:
|
1005
|
+
|
1006
|
+
$ git tag -a v1.2 9fceb02
|
1007
|
+
|
1008
|
+
Aby sprawdzić czy etykieta została stworzona wpisz:
|
1009
|
+
|
1010
|
+
$ git tag
|
1011
|
+
v0.1
|
1012
|
+
v1.2
|
1013
|
+
v1.3
|
1014
|
+
v1.4
|
1015
|
+
v1.4-lw
|
1016
|
+
v1.5
|
1017
|
+
|
1018
|
+
$ git show v1.2
|
1019
|
+
tag v1.2
|
1020
|
+
Tagger: Scott Chacon <schacon@gee-mail.com>
|
1021
|
+
Date: Mon Feb 9 15:32:16 2009 -0800
|
1022
|
+
|
1023
|
+
version 1.2
|
1024
|
+
commit 9fceb02d0ae598e95dc970b74767f19372d61af8
|
1025
|
+
Author: Magnus Chacon <mchacon@gee-mail.com>
|
1026
|
+
Date: Sun Apr 27 20:43:35 2008 -0700
|
1027
|
+
|
1028
|
+
updated rakefile
|
1029
|
+
...
|
1030
|
+
|
1031
|
+
### Współdzielenie etykiet ###
|
1032
|
+
|
1033
|
+
Domyślnie, polecenie `git push` nie przesyła twoich etykiet do zdalnego repozytorium. Będziesz musiał osobno wypchnąć na współdzielony serwer stworzone etykiety. Proces ten jest podobny do współdzielenia gałęzi i polega na uruchomieniu `git push origin [nazwa-etykiety]`.
|
1034
|
+
|
1035
|
+
$ git push origin v1.5
|
1036
|
+
Counting objects: 50, done.
|
1037
|
+
Compressing objects: 100% (38/38), done.
|
1038
|
+
Writing objects: 100% (44/44), 4.56 KiB, done.
|
1039
|
+
Total 44 (delta 18), reused 8 (delta 1)
|
1040
|
+
To git@github.com:schacon/simplegit.git
|
1041
|
+
* [new tag] v1.5 -> v1.5
|
1042
|
+
|
1043
|
+
Jeśli masz mnóstwo tagów, którymi chciałbyś się podzielić z innymi, możesz je wszystkie wypchnąć jednocześnie dodając do `git push` opcję `--tags`. W ten sposób zostaną przesłane wszystkie tagi, których nie ma jeszcze na serwerze.
|
1044
|
+
|
1045
|
+
$ git push origin --tags
|
1046
|
+
Counting objects: 50, done.
|
1047
|
+
Compressing objects: 100% (38/38), done.
|
1048
|
+
Writing objects: 100% (44/44), 4.56 KiB, done.
|
1049
|
+
Total 44 (delta 18), reused 8 (delta 1)
|
1050
|
+
To git@github.com:schacon/simplegit.git
|
1051
|
+
* [new tag] v0.1 -> v0.1
|
1052
|
+
* [new tag] v1.2 -> v1.2
|
1053
|
+
* [new tag] v1.4 -> v1.4
|
1054
|
+
* [new tag] v1.4-lw -> v1.4-lw
|
1055
|
+
* [new tag] v1.5 -> v1.5
|
1056
|
+
|
1057
|
+
Jeśli ktokolwiek inny sklonuje lub pobierze zmiany teraz z twojego repozytorium, dostanie także wszystkie twoje etykiety.
|
1058
|
+
|
1059
|
+
## Sztuczki i kruczki ##
|
1060
|
+
|
1061
|
+
Zanim zamkniemy ten rozdział, pokażemy kilka sztuczek, które uczynią twoją pracę prostszą, łatwiejszą i przyjemniejszą. Wielu ludzi używa Gita nie korzystając z przytoczonych tutaj porad, ty też nie musisz, ale przynajmniej powinieneś o nich wiedzieć.
|
1062
|
+
|
1063
|
+
### Auto-uzupełnianie ###
|
1064
|
+
|
1065
|
+
Jeśli używasz powłoki Bash, Git jest wyposażony w poręczny skrypt auto-uzupełniania. Pobierz kod źródłowy Gita i zajrzyj do katalogu `contrib/completion`. Powinieneś znaleźć tam plik o nazwie `git-completion.bash`. Skopiuj go do swojego katalogu domowego i dodaj do `.bashrc` następującą linijkę:
|
1066
|
+
|
1067
|
+
source ~/.git-completion.bash
|
1068
|
+
|
1069
|
+
Jeśli chcesz ustawić Gita tak, żeby automatycznie pozwalał na auto-uzupełnianie wszystkim użytkownikom, skopiuj wymieniony skrypt do katalogu `/opt/local/etc/bash_completion.d` na systemach Mac, lub do `/etc/bash_completion.d/` w Linuxie. Jest to katalog skryptów ładowanych automatycznie przez Basha, dzięki czemu opcja zostanie włączona wszystkim użytkownikom.
|
1070
|
+
|
1071
|
+
Jeśli używasz Windows wraz z narzędziem Git Bash, które jest domyślnie instalowane wraz wraz z msysGit, auto-uzupełnianie powinno być pre-konfigurowane i dostępne od razu.
|
1072
|
+
|
1073
|
+
Wciśnij klawisz Tab podczas wpisywania polecenia Gita, a powinieneś ujrzeć zestaw podpowiedzi do wyboru:
|
1074
|
+
|
1075
|
+
$ git co<tab><tab>
|
1076
|
+
commit config
|
1077
|
+
|
1078
|
+
W tym wypadku wpisanie git co i wciśnięcie Tab dwukrotnie podpowiada operacje commit oraz config. Dodanie kolejnej literki m i wciśnięcie Tab uzupełni automatycznie polecenie do `git commit`.
|
1079
|
+
|
1080
|
+
Podobnie jest z opcjami, co pewnie przyda ci się znacznie częściej. Na przykład jeżeli chcesz uruchomić polecenie `git log` i nie pamiętasz jednej z opcji, zacznij ją wpisywać i wciśnij Tab aby zobaczyć sugestie:
|
1081
|
+
|
1082
|
+
$ git log --s<tab>
|
1083
|
+
--shortstat --since= --src-prefix= --stat --summary
|
1084
|
+
|
1085
|
+
Jest to bardzo przydatna możliwość pozwalająca na zaoszczędzenie mnóstwa czasu spędzonego na czytaniu dokumentacji.
|
1086
|
+
|
1087
|
+
### Aliasy ###
|
1088
|
+
|
1089
|
+
Git nie wydedukuje sam polecenia jeśli wpiszesz je częściowo i wciśniesz Enter. Jeśli nie chcesz w całości wpisywać całego tekstu polecenia możesz łatwo stworzyć dla niego alias używając `git config`. Oto kilka przykładów, które mogą ci się przydać:
|
1090
|
+
|
1091
|
+
$ git config --global alias.co checkout
|
1092
|
+
$ git config --global alias.br branch
|
1093
|
+
$ git config --global alias.ci commit
|
1094
|
+
$ git config --global alias.st status
|
1095
|
+
|
1096
|
+
Oznacza to, że na przykład, zamiast wpisywać `git commit`, wystarczy, że wpiszesz `git ci`. Z czasem zaczniesz też stosować także inne polecenia regularnie, nie wahaj się wówczas tworzyć sobie dla nich nowych aliasów.
|
1097
|
+
|
1098
|
+
Technika ta jest także bardzo przydatna do tworzenia poleceń, które uważasz, że powinny istnieć a których brakuje ci w zwięzłej formie. Na przykład, aby skorygować problem z intuicyjnością obsługi usuwania plików z poczekalni, możesz dodać do Gita własny, ułatwiający to alias:
|
1099
|
+
|
1100
|
+
$ git config --global alias.unstage 'reset HEAD --'
|
1101
|
+
|
1102
|
+
W ten sposób dwa poniższe polecenia są sobie równoważne:
|
1103
|
+
|
1104
|
+
$ git unstage fileA
|
1105
|
+
$ git reset HEAD fileA
|
1106
|
+
|
1107
|
+
Od razu polecenie wygląda lepiej. Dość częstą praktyką jest także dodawanie polecenia `last`:
|
1108
|
+
|
1109
|
+
$ git config --global alias.last 'log -1 HEAD'
|
1110
|
+
|
1111
|
+
Możesz dzięki niemu łatwo zobaczyć ostatnią rewizję:
|
1112
|
+
|
1113
|
+
$ git last
|
1114
|
+
commit 66938dae3329c7aebe598c2246a8e6af90d04646
|
1115
|
+
Author: Josh Goebel <dreamer3@example.com>
|
1116
|
+
Date: Tue Aug 26 19:48:51 2008 +0800
|
1117
|
+
|
1118
|
+
test for current head
|
1119
|
+
|
1120
|
+
Signed-off-by: Scott Chacon <schacon@example.com>
|
1121
|
+
|
1122
|
+
Jak można zauważyć, Git zastępuje nowe polecenie czymkolwiek co do niego przypiszesz. Jednakże, możesz chcieć także uruchomić zewnętrzne polecenie zamiast polecenia Gita. Rozpocznij je wówczas znakiem wykrzyknika `!`. Przydaje się to podczas tworzenia własnego narzędzia, które współpracuje z repozytorium Gita. Możemy pokazać to na przykładzie aliasu `git visual` uruchamiającego `gitk`:
|
1123
|
+
|
1124
|
+
$ git config --global alias.visual "!gitk"
|
1125
|
+
|
1126
|
+
## Podsumowanie ##
|
1127
|
+
|
1128
|
+
Umiesz już pracować z wszystkimi najważniejszymi, lokalnymi poleceniami Gita - tworzyć i klonować repozytoria, dokonywać zmian, umieszczać je w poczekalni i zatwierdzać do rewizji oraz przeglądać historię repozytorium. W dalszej kolejności zajmiemy się jedną z kluczowych możliwości Gita: modelem gałęzi.
|