Git
Chapters ▾ 2nd Edition

7.1 Mga Git na Kasangkapan - Pagpipili ng Rebisyon

Sa ngayon, natutunan mo ang karamihan ng pang-araw-araw na mga utos at mga workflow na kailangan mong pamahalaan o pangalagaan ang Git na repositoryo para sa kontrol ng iyong source code. Nagawa mo na ang mga pangunahing gawain ng pagsubaybay at pag-commit ng mga file, at napakinabangan mo ang kapayarihan sa staging na lawak at magaan na paksa na pag-branch at pag-merge.

Ngayon ikaw ay magsiyasat ng bilang sa sobrang makapangyarihan na bagay na magagawa ng Git na maaaring hindi mo na kinakailangang gamitin sa pang-araw-araw ngunit maaaring kailangan mo sa isang punto.

Pagpipili ng Rebisyon

Ang Git ay nagpapahintulot sa iyo upang sumangguni sa isang itinakdang mga commit o isang lawak ng mga commit sa maraming mga paraan. Hindi nila kinakailangan na halata ngunit nakakatulong upang malaman.

Solong mga Rebisyon

Maaari mong malinaw na i-refer ang anumang solong commit sa buong ito, 40-karakter na SHA-1 hash, ngunit may mga higit pa na pantaong-palakaibigan na mga paraan upang sumangguni rin sa mga commit. Ang seksyon na ito ng mga outline ng iba’t ibang mga paraan na maaari mong isangguni sa anumang commit.

Ang Maikling SHA-1

Ang Git ay sapat na matalino upang malaman kung anong commit ang iyong nare-refer na kung bigyan mo ang mga unang ilang mga karakter ng SHA-1 hash, hangga’t ang bahagyang hash ay hindi bababa sa apat na mga karakter ang haba at hindi malabo; yan ay, walang ibang bagay sa database ng bagay na maaaring magkakaroon ng hash na nagmumula ng parehong prefix.

Halimbawa, upang suriin ang tiyak na commit na kung saan ka kilala mo ang dinagdag na ilang mga pag-andar, maaari mong patakbuhin muna ang git log na utos upang hanapin ang commit:

$ git log
commit 734713bc047d87bf7eac9674765ae793478c50d3
Author: Scott Chacon <schacon@gmail.com>
Date:   Fri Jan 2 18:32:33 2009 -0800

    fixed refs handling, added gc auto, updated tests

commit d921970aadf03b3cf0e71becdaab3147ba71cdef
Merge: 1c002dd... 35cfb2b...
Author: Scott Chacon <schacon@gmail.com>
Date:   Thu Dec 11 15:08:43 2008 -0800

    Merge commit 'phedders/rdocs'

commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b
Author: Scott Chacon <schacon@gmail.com>
Date:   Thu Dec 11 14:58:32 2008 -0800

    added some blame and merge stuff

Sa kasong ito, sabihin mong interesado ka sa commit na kanino ang hash nagsisimula ng 1c002dd.... Maaari mong siyasatin ang commit na may anumang sumusunod na mga pagkakaiba-iba sa git show (ipagpalagay na mas maikling mga bersyon ay hindi malabo):

$ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b
$ git show 1c002dd4b536e7479f
$ git show 1c002d

Maaaring malaman ng Git ang isang maikli, natatanging pagpapaiklipara sa iyong SHA-1 na mga halaga. Kung ikaw ay nagpasa ng --abbrev-commit sa git log na utos, ang output ay gumamit ng mas maikling halaga ngunit panatilihin sila na katangi-tangi; ito ay mga default sa paggamit ng pitong mga karakter ngunit ginagawa nila ito na mas matagal kung kinakailangan upang mapanatiling hindi malinaw ang SHA-1:

$ git log --abbrev-commit --pretty=oneline
ca82a6d changed the version number
085bb3b removed unnecessary test code
a11bef0 first commit

Sa pangkalahatan, walo sa sampung mga karakter ay higit pa sa sapat upang maging natatanging sa loob ng isang proyekto. Halimbawa, sa Oktubre 2017, ang Linux na kernel (na kung saan ay isang medyo malaki na proyekto) ay may higit sa 700,000 na mga commit at halos anim na milyong na mga bagay, na may walang dalang mga bagay na magkatulad ang mga SHA-1 ay magkapareho sa unang 11 na mga karakter.

Example 10. ISANG MAIKLING PAALALA TUNGKOL SA SHA-1

Maraming tao ay magiging nababahala sa isang punto na sila ay, sa pamamagitan ng sapalaran na pagkakataon, mayroong dalawang magkakaibang bagay sa kanilang repositoryo na ang hash ay pareho sa SHA-1 na halaga. Ano ngayon?

Kung mangyari na ikaw ay mag-commit sa isang bagay na nag-hash sa parehong SHA-1 na halaga bilang isang nakaraang ibang bagay sa iyong repositoryo, Ang Git ay makakita ng nakaraan na bagay na nasa iyong Git na database, ipagpalagay na ito ay nakasulat na at muli lang gamitin ito. Kung subukan mong tingnan ang bagay na iyon muli sa isang punto, ikaw ay makakakuha lagi ng datos sa unang bagay.

Gayunpaman, dapat mong malaman kung gaano katawa ang pagkawala sa sitwasyon na ito. Ang SHA-1 na digest ay 20 bytes o 160 bits. Ang bilang ng random na naka-hash na mga bagay na kinakailangan siguraduhin ang 50% na posibilidad ng isang banggaan ay mga 280 (ang formula para sa pagtukoy ng posibilidad ng banggaan ay p = (n(n-1)/2) * (1/2^160)). 280 ay 1.2 x 1024 o 1 milyon bilyon bilyon. Iyon ay 1,200 na beses ang bilang ng mga butil ng buhagin sa lupa.

Narito ang isang halibawa na magbibigay sa iyo ng ideya kung ano ang kukuha nitong SHA-1 na banggaan Kung lahat sa 6.5 na bilyon na mga tayo sa Lupa ay nag-program, sa bawat segundo, sa bawat isa ay gumagawa ng code na katumbas sa buong Linux na kernel na kasaysayan(3.6 na milyong Git na mga bagay) at itinutulak into sa isang napakalaking Git na repositoryo, ito ay kukuha ng halos dalawang taon hanggang ang repositoryong ito ay maglalaman ng sapat na mga bagay upang magkaroon ng 50% na posibilidad sa isang SHA-1 na bagay na banggaan. Kaya naman, ang SHA-1 na banggaan ay mas malamang kaysa sa bawat miyembro sa iyong programming na koponan na inatake o napatay ng mga lobo sa hindi nauugnay na insidente sa parehong gabi.

Mga Reperensiya ng Branch

Isang tapat na paraan upang i-refer ang isang partikular na commit na kung itong commit na nasa tuktok na isang branch; sa ganitong kaso, maaari mo lamang gamitin ang pangalan ng branch sa anumang Git na utos na inaasahan ng isang reperensiya sa isang commit. Halimbawa, kung gusto mong suriin ang huling commit sa bagay sa branch, ang sumusunod na mga utos ay katumbas, ipagpalagay na ang topic1 na branch ay tumuturo sa commit sa ca82a6d...:

$ git show ca82a6dff817ec66f44342007202690a93763949
$ git show topic1

Kung gusto mong makita kung saang tiyak na SHA-1 na branch tumuturo ito, o kung gusto mong makita ang kung anumang mga halimbawang ito na bumababa sa termino ng SHA-1s, maaari kang gumamit ng Git plumbing na kasangkapan na tinatawag na rev-parse. You can see Mga Panloob ng GIT for more information about plumbing tools; basically, rev-parse exists for lower-level operations and isn’t designed to be used in day-to-day operations. Gayunpaman, maaari itong makakatulong kung minsan kapag ikaw ay nangangailangan upang makita kung ano talaga ang nangyayari. Dito maaari kang magpatakbo ng rev-parse sa iyong branch.

$ git rev-parse topic1
ca82a6dff817ec66f44342007202690a93763949

Mga Shortname ng RefLog

Isa sa mga bagay ng Git ay gumawa ng background habang ikaw ay nagtratrabaho ng malayo ay magtago ng “reflog” — isang log na kung saan ang iyong HEAD at branch na mga reperensiya ay para sa huling ilang mga buwan.

Maaari mong makita ang iyong reflog sa pamamagitan ng paggamit ng git reflog:

$ git reflog
734713b HEAD@{0}: commit: fixed refs handling, added gc auto, updated
d921970 HEAD@{1}: merge phedders/rdocs: Merge made by the 'recursive' stategy.
1c002dd HEAD@{2}: commit: added some blame and merge stuff
1c36188 HEAD@{3}: rebase -i (squash): updating HEAD
95df984 HEAD@{4}: commit: # This is a combination of two commits.
1c36188 HEAD@{5}: rebase -i (squash): updating HEAD
7e05da5 HEAD@{6}: rebase -i (pick): updating HEAD

Sa tuwing iyong branch tip ay na-update sa anumang rason, ang Git ay nag-iimbak ng impormasyon para sa iyong temporaryong kasaysayan. Maaari mong gamitin ang iyong reflog na datos upang i-refer din ang mga lumang mga commit. Halimbawa, kung ikaw ay gustong makakita ng panglimang bago ang halaga sa HEAD ng iyong repositoryo, maaari mong gamitin ang @{5} na reperensiya na nakikita mo sa reflog output:

$ git show HEAD@{5}

Maaari mo ding gamitin ang syntax na ito upang makita kung saan ang branch ay ilang dami ng oras ang nakalipas. Halimbawa, para makita kung saan ang iyong master na branch kahapon, maaari kang mag-type ng

$ git show master@{yesterday}

Iyon ay magpapakita sa iyo kung saan ang tip ng iyong master na branch kahapon. Ang pamamaraan na ito ay gumagana lamang para sa datos na nasa iyong reflog pa, kaya ikaw ay hindi makagamit nito ng mga commit na mas luma pa sa ilang mga buwan.

Upang makita ang reflog na impormasyon na naka-format tulad ng git log na output, maaari kang magpatakbo ng git log -g:

$ git log -g master
commit 734713bc047d87bf7eac9674765ae793478c50d3
Reflog: master@{0} (Scott Chacon <schacon@gmail.com>)
Reflog message: commit: fixed refs handling, added gc auto, updated
Author: Scott Chacon <schacon@gmail.com>
Date:   Fri Jan 2 18:32:33 2009 -0800

    fixed refs handling, added gc auto, updated tests

commit d921970aadf03b3cf0e71becdaab3147ba71cdef
Reflog: master@{1} (Scott Chacon <schacon@gmail.com>)
Reflog message: merge phedders/rdocs: Merge made by recursive.
Author: Scott Chacon <schacon@gmail.com>
Date:   Thu Dec 11 15:08:43 2008 -0800

    Merge commit 'phedders/rdocs'

Mahalagang tandaan na ang reflog na impormasyon ay mahigpit na lokal — ito ay isang log lamang kung ano ang iyong nagawa sa iyong repositoryo. Ang mga reperensiya ay hindi pareho sa ibang kopya ng repositoryo; saka, pagkatapos ka mag-clone ng repositoryo, ikaw ay magkakarooon ng walang laman na reflog, na bilang walang aktibidad na naganap pa sa iyong repositoryo. Pagtatakbo ng git show HEAD@{2.months.ago} ay ipapakita sa iyo ang pagtutugma ng commit lamang kung ikaw ay nag-clone ng proyekto na hindi bababa sa dalawang buwan na nakalipas — kung na-clone mo itong mas kamakailan pa kaysa sa iyon, makikita mo lamang ang iyong unang lokal na commit.

Tip
Isipin ang reflog bilang bersyon ng Git sa kasaysayan ng shell

Kung ikaw ay mayroong UNIX o Linux na karanasan, maaari mong isipin na ang iyong reflog bilang bersyon ng Git sa kasaysayan ng shell, na nagpapahiwatig na kung ano ang naroroon ay malinaw na may kaugnayan lamang para sa iyo at iyong “sesyon”, at walang kinalaman sa sinuman na maaaring nagtratrabaho sa parehong makina.

Mga Reperensiya ng Kanunu-nunuan

Ang iba pang pangunahing paraan upang tiyakin ang commit ay dumaan sa kanang kanunu-nunuan. Kung ikaw ay maglagay ng ^ (caret) sa katupusan ng reperensiya, ang Git ay naglulutas nito upang mangahulugang magulang sa commit na iyon. Ipagpalagay na tumugin ka sa kasaysayan ng iyong proyekto:

$ git log --pretty=format:'%h %s' --graph
* 734713b fixed refs handling, added gc auto, updated tests
*   d921970 Merge commit 'phedders/rdocs'
|\
| * 35cfb2b Some rdoc changes
* | 1c002dd added some blame and merge stuff
|/
* 1c36188 ignore *.gem
* 9b29157 add open3_detach to gemspec file list

Pagkatapos, maaari mong makita ang nakaraaang commit sa pamamagitan sa pagtiyak ng HEAD^, na ibig sabihin ay “ang magulang ng HEAD”:

$ git show HEAD^
commit d921970aadf03b3cf0e71becdaab3147ba71cdef
Merge: 1c002dd... 35cfb2b...
Author: Scott Chacon <schacon@gmail.com>
Date:   Thu Dec 11 15:08:43 2008 -0800

    Merge commit 'phedders/rdocs'
Note
Pag-alis ng caret sa Windows

Sa Windows sa cmd.exe, ^ ay isang espesyal na karakter at nangangailangan upang tratuhin ng naiiba. Maaari mong doblehin ito o maglagay ng commit na reperensiya sa mga quote:

$ git show HEAD^     # will NOT work on Windows
$ git show HEAD^^    # OK
$ git show "HEAD^"   # OK

Maaari mo ring tukuyin ang bilang pagkatapos ng ^ – halimbawa, ang d921970^2 ay ibig sabihin “ang ikalawang magulang sa d921970.” Ang syntax na ito ay kapaki-pakinabang lamang kung ang merge na mga commit, na may higit pa sa isang magulang. Ang unang magulang ay isang branch na ikaw ay nandoon noong ikaw ay nag-merge, at ang pangalawa ay ang commit na na-merge sa:

$ git show d921970^
commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b
Author: Scott Chacon <schacon@gmail.com>
Date:   Thu Dec 11 14:58:32 2008 -0800

    added some blame and merge stuff

$ git show d921970^2
commit 35cfb2b795a55793d7cc56a6cc2060b4bb732548
Author: Paul Hedderly <paul+git@mjr.org>
Date:   Wed Dec 10 22:22:03 2008 +0000

    Some rdoc changes

Ang iba pang pangunahing kanunu-nunuan na pagtutukoy sa ~ (tilde). Ito rin ang tumutukoy sa unang magulang, kaya ang HEAD~ at HEAD^ ay magkatumbas. Ang pagkakaiba ay nagiging maliwanag kapag ikaw ang tumukoy ng isang numero. Ang HEAD~2 ay nangangahulugang “ang unang magulang sa unang magulang,” o “ang lolo o lola” — ito ay dumadaan sa unang mga magulang sa bilang sa maraming naitukoy. Halimbawa, sa kasaysayan na nakalista na mas maaga, ang HEAD~3 maaaring maging

$ git show HEAD~3
commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d
Author: Tom Preston-Werner <tom@mojombo.com>
Date:   Fri Nov 7 13:47:59 2008 -0500

    ignore *.gem

Maaari itong maisulat na HEAD^^^, na muli ang unang magulang sa unang magulang sa unang magulang:

$ git show HEAD^^^
commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d
Author: Tom Preston-Werner <tom@mojombo.com>
Date:   Fri Nov 7 13:47:59 2008 -0500

    ignore *.gem

Maaari mo ring pagsamahin ang mga syntax na ito — maaari kang makakuha ng pangalawang magulang sa nakaraang reperensiya (ipagpapalagay na ito ay na-merge commit) sa pamamagitan ng paggamit ng HEAD~3^2, at iba pa.

Mga Lawak ng Commit

Ngayon na magagawa mo na ang pagtukoy sa indibidwal na mga commit, tingnan natin kung paano magtukoy ng mga lawak sa mga commit. Ito ay partikular na kapaki-pakinabang para sa pagmamahala ng iyong mga branch — kung mayroon kang maraming mga branch, maaari mong gamitin ang lawak ng pagtutukoy upang sagutin ang mga tanong tulad ng, “Anong trabaho ang nasa branch na ito na hindi ko pa nai-merge sa aking pangunahing branch?”

Dobleng Dot

Ang pinaka-karaniwang na lawak na pagtutukoy ay ang doubleng-dot na syntax. Ito talaga ay nagtatanong sa Git na malutas ang lawak ng mga commit na mapupuntahan mula sa isang commit ngunit hindi maabot mula sa kabila. Halimbawa, sabihin na mayroon kang isang kasaysayan ng Git na mukhang ganito Halimbawa ng kasaysayan sa lawak ng pagpipilian..

Halimbawa sa kasaysayan para sa lawak ng pagpipilian.
Figure 137. Halimbawa ng kasaysayan sa lawak ng pagpipilian.

Sabihin na gusto mong makita ang kung ano ang nasa iyong eksperimento na branch na hindi pa pinagsama sa iyong master na branch. Maaari kang magtanong sa Git upang ipakita sa iyo ang log ng mga commit na may master..experiment — ibig sabihin “ang lahat ng mga commit ay mapupuntahan mula sa eksperimento na hindi pa naabot mula sa master.” Para sa kapakanan ng kaiklian at kalinawan sa mga halimbawang ito, ang mga letra sa commit na mga bagay mula sa dayagram ay ginagamit sa lugar sa aktwal na log output sa pagkakasunod-sunod na sila ay magpakita:

$ git log master..experiment
D
C

Kung, sa kabila, ikaw ay gustong makita ang kabaligtaran — lahat ng mga commit sa master na wala sa experiment — maaari mong baligtarin ang mga pangalan ng branch. Ang experiment..master ay nagpapakita sa iyo ng lahat sa master na hindi maabot mula sa experiment:

$ git log experiment..master
F
E

Ito ay kapaki-pakinabang kung ikaw ay gustong magtago ng experiment branch na napapanahon at prebiyu sa kung ano ang nai-merge. Isa pang madalas gamitin sa syntax na ito ay tingnan kung ano ang iyong itutulak sa isang remote:

$ git log origin/master..HEAD

Ang utos na ito ay nagpapakita sa iyo sa anumang mga commit sa iyong kasalukuyang branch na wala pa sa master na branch sa iyong origin na remote. Kung ikaw ay magpatakbo ng git push ang iyong kasalukuyang branch ay nag-track sa origin/master, ang mga commit ay nailista sa pamamagitan ng git log origin/master..HEAD ay ang mga commit na iliipat sa server. Maaari mo ring iwanan ang isang bahagi ng syntax para magkaroon ng Git assume sa HEAD. Halimbawa, Maaari kang makakuha ng parehong mga resulta tulad ng sa nakaraang halimbawa sa pamamagitan nang pag-type ng git log origin/master.. — Git substitutes HEAD kung nawala ang isang panig.

Maramihang mga Punto

Ang dobleng-dot na syntax ay kapaki-pakinabang bilang isang shorthand, ngunit marahil gusto mong magtukoy ng higit pa sa dalawang mga branch upang ipahiwatig ang mga rebisyon, tulad ng nakikita kung ano ang mga commit na nasa ilang mga branch na wala sa branch na kasalukyang nasa iyo. Git allows you to do this by using either the ^ character or --not before any reference from which you don’t want to see reachable commits. Kaya naman, ang mga sumusunod na tatlong mga utos ay katumbas:

$ git log refA..refB
$ git log ^refA refB
$ git log refB --not refA

Ito ay maganda dahil kasama ang syntax na ito ay maaari kang magtukoy ng higit dalawang mga reperensiya sa iyong query, na kung saan ikaw ay hindi makagawa gamit ang dobleng-dot na syntax. Halimbawa, kung gusto mong makita ang lahat ng mga commit na maaaring mapuntahan mula sa refA o refB ngunit hindi mula sa refC, maaari mong gamitin ang alinman sa:

$ git log refA refB ^refC
$ git log refA refB --not refC

Ginagawa ito para sa isang napakamakapangyarihan na rebisyong query na sistema na dapat makatulong sa iyo na para malaman kung ano ang nasa iyong mga branch.

Triple na Dot

Ang huling pangunahing na pagpili ng hanay na syntax ay ang tripleng-dot na syntax, na tumutukoy sa lahat ng mga commit na maaaring abutin sa alinman sa dalawang mga reperensiya ngunit hindi sa pamamagitan ng dalawang magkapareho. Tingnan uli ang halimbawa sa commit na kasaysayan sa Halimbawa ng kasaysayan sa lawak ng pagpipilian.. Kung gusto mong makita kung ano ang nasa master o experiment ngunit wala sa anumang karaniwang mga reperensiya, maaari kang magpatakbo ng:

$ git log master...experiment
F
E
D
C

Muli, ito ay nagbibigay sa iyo ng normal na log na output ngunit nagpapakita lamang sa commit na impormasyon para sa apat na mga commit, lumilitaw sa tradisyonal na commit na petsa ng pagkasunod-sunod.

Isang karaniwang switch na gumagamit ng log na utos sa kasong ito ay --left-right, na kung saan ay nagpapakita kung saan na panig sa lawak ng bawat commit na nasa loob. Ito ay nakakatulong na makagawa ng output na mas kapaki-pakinabang:

$ git log --left-right master...experiment
< F
< E
> D
> C

Gamit ang mga kasangkapan, maaari mong mas madali maipaalam ni Get kung ano ang commit o mga commit na gusto mong siyasatin.