-
1. Pagsisimula
-
2. Mga Pangunahing Kaalaman sa Git
-
3. Pag-branch ng Git
-
4. Git sa Server
- 4.1 Ang Mga Protokol
- 4.2 Pagkuha ng Git sa isang Server
- 4.3 Ang paglikha ng iyong Pampublikong Susi ng SSH
- 4.4 Pag-Setup ng Server
- 4.5 Git Daemon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Mga Opsyon ng Naka-host sa Third Party
- 4.10 Buod
-
5. Distributed Git
- 5.1 Distributed Workflows
- 5.2 Contributing to a Project
- 5.3 Maintaining a Project
- 5.4 Summary
-
6. GitHub
-
7. Mga Git na Kasangkapan
- 7.1 Pagpipili ng Rebisyon
- 7.2 Staging na Interactive
- 7.3 Pag-stash at Paglilinis
- 7.4 Pag-sign sa Iyong Trabaho
- 7.5 Paghahanap
- 7.6 Pagsulat muli ng Kasaysayan
- 7.7 Ang Reset Demystified
- 7.8 Advanced na Pag-merge
- 7.9 Ang Rerere
- 7.10 Pagdebug gamit ang Git
- 7.11 Mga Submodule
- 7.12 Pagbibigkis
- 7.13 Pagpapalit
- 7.14 Kredensyal na ImbakanCredential Storage
- 7.15 Buod
-
8. Pag-aangkop sa Sariling Pangangailagan ng Git
- 8.1 Kompigurasyon ng Git
- 8.2 Mga Katangian ng Git
- 8.3 Mga Hook ng Git
- 8.4 An Example Git-Enforced Policy
- 8.5 Buod
-
9. Ang Git at iba pang mga Sistema
- 9.1 Git bilang isang Kliyente
- 9.2 Paglilipat sa Git
- 9.3 Buod
-
10. Mga Panloob ng GIT
- 10.1 Plumbing and Porcelain
- 10.2 Git Objects
- 10.3 Git References
- 10.4 Packfiles
- 10.5 Ang Refspec
- 10.6 Transfer Protocols
- 10.7 Pagpapanatili At Pagbalik ng Datos
- 10.8 Mga Variable sa Kapaligiran
- 10.9 Buod
-
A1. Appendix A: Git in Other Environments
- A1.1 Grapikal Interfaces
- A1.2 Git in Visual Studio
- A1.3 Git sa Eclipse
- A1.4 Git in Bash
- A1.5 Git in Zsh
- A1.6 Git sa Powershell
- A1.7 Summary
-
A2. Appendix B: Pag-embed ng Git sa iyong Mga Aplikasyon
- A2.1 Command-line Git
- A2.2 Libgit2
- A2.3 JGit
-
A3. Appendix C: Mga Kautusan ng Git
- A3.1 Setup at Config
- A3.2 Pagkuha at Paglikha ng Mga Proyekto
- A3.3 Pangunahing Snapshotting
- A3.4 Branching at Merging
- A3.5 Pagbabahagi at Pagbabago ng mga Proyekto
- A3.6 Pagsisiyasat at Paghahambing
- A3.7 Debugging
- A3.8 Patching
- A3.9 Email
- A3.10 External Systems
- A3.11 Administration
- A3.12 Pagtutuberong mga Utos
3.1 Pag-branch ng Git - Mga Branch sa Maikling Salita
Halos bawat VCS ay mayroong ilang porma ng suporta ng pag-branch. Ang pag-branch ay nangangahulugang ikaw ay hihiwalay mula sa pangunahing linya ng pagde-develop at magpapatuloy sa paggawa ng trabaho na hindi nanggugulo sa pangunahing linyang iyon. Sa karamihan ng mga kasangkapan ng VCS, ito ay isang medyo magastos na proseso, na madalas ay kinakailangan mong gumawa ng isang panibagong kopya ng iyong source code na direktoryo, na maaaring tumagal ng mahabang panahon para sa mga malalaking proyekto.
Iilang mga tao ay tumutukoy sa modelo ng pag-branch ng Git bilang “mamamatay na tampok,” nito at tiyak nitong tinatakda ang Git na hiwalay sa VCS na komunidad. Bakit ito sobrang espesyal? Ang paraan ng pag-branch ng Git ay hindi kapani-paniwalang magaan, na ginagawa ang mga operasyon ng pag-branch na halos madalian, at ang pagpapalit pabalik at patungo sa pagitan ng mga branch sa pangkalahatan na kasing bilis. Hindi katulad ng karamihan sa ibang mga VCS, ang Git ay hinihikayat ang mga daloy ng trabaho na madalas na nagba-branch at nagme-merge, kahit maramihan pa sa isang araw. Ang pagkaunawa at pagkadalubhasa ng tampok na ito ay nagbibigay sa iyo ng isang makapangyarihan at natatanging kasangkapan at maaaring buong baguhin ang paraan ng iyong pagde-develop.
Mga Branch sa Maikling Salita
Upang talagang maintindihan ang paraan ng Git sa paggawa ng pag-branch, kailangan nating umatras at suriin kung paano nag-iimbak ng data ang Git.
Kung iyong natatandaan mula sa Pagsisimula, ang Git ay hindi nag-iimbak ng data bilang isang serye ng mga changeset o mga kaibahan, ngunit sa halip ay isang serye ng mga snapshot.
Kapag ikaw ay gumawa ng isang commit, ang Git ay nag-iimbak ng isang commit na object na naglalaman ng isang pointer sa snapshot ng nilalaman na iyong na-stage. Ang object na ito ay naglalaman din ng pangalan at email ng may-akda, ang mensahe na iyong na-type, at mga pointer sa commit o mga commit na direktang dumating bago ang commit na ito (magulang nito o mga magulang): zero na mga magulang para sa paunang commit, isang magulang para sa isang normal na commit, at maramihang mga magulang para sa isang commit na nagreresulta mula sa isang pag-merge ng dalawa o higit pang mga branch.
Upang maisalarawan ito, ipagpalagay natin na ikaw ay may isang direktoryong naglalaman ng tatlong mga file, at na-stage mo lahat ang mga ito at na-commit. Ang pag-stage ng mga file ay nagkakalkula ng isang checksum para sa bawat isa (ang SHA-1 na hash na nabanggit namin sa Pagsisimula), nag-iimbak sa bersyong iyon ng file sa Git na repositoryo (tinutukoy ng Git ang mga ito bilang mga blob), at nagdaragdag ng checksum na iyon sa staging na lawak:
$ git add README test.rb LICENSE
$ git commit -m 'Ang paunang commit ng aking proyekto'
Kapag nagawa mo ang commit sa pamamagitan ng pagpapatakbo ng git commit
, ang Git ay ichi-checksum ang bawat subdirectory (sa kasong ito, ang root na direktoryo ng proyekto lamang) at iiimbak ang mga tree object na iyon sa Git na repositoryo. Ang Git ngayon ay gagawa ng isang commit na object na may metadata at isang pointer sa root project ng tree upang ito ay makalikha muli ng snapshot na iyon kapag kinakailangan.
Ang iyong Git na repositoryo ngayon ay naglalaman ng limang mga object: isang blob para sa mga nilalaman ng bawat isa sa iyong tatlong mga file, isang tree na naglilista ng mga nilalaman ng direktoryo at tinutukoy kung anong mga pangalan ng file ang naimbak bilang mga blob, at isang commit na may pointer sa root tree at lahat ng mga metadata ng commit.
Kung gagawa ka ng ilang mga pagbabago at magku-commit muli, ang susunod na commit ay mag-iimbak ng isang pointer sa commit na dumating kaagad bago nito.
Ang isang branch sa Git ay simpleng isang magaan na nagagalaw na pointer sa isa sa mga commit na ito. Ang default na pangalan ng branch sa Git ay master
. Habang nagsisimula kang gumawa ng mga commit, ikaw ay bibigyan ng isang master
na branch na tumuturo sa huling commit na ginawa mo. Sa bawat pagkakataon na ikaw ay mag-commit, awtomatikong ginagalaw ito nang pasulong.
Ang “master” na branch sa Git ay hindi isang espesyal na branch. Ito ay eksaktong kapareho ng anumang ibang branch. Ang dahilan lamang kung bakit halos bawat repositoryo ay mayroong isa ay ang git init
na utos na gumagawa nito bilang default at karamihan sa mga tao ay hindi mag-aabalang baguhin ito.
Paggawa ng isang Bagong Branch
Ano ang mangyayari kung ikaw ay gumawa ng isang bagong branch? Ang paggawa nito ay lumilikha ng isang bagong pointer para sa iyo upang ilipat kahit saan. Sabihin nating gumawa ka ng isang bagong branch na tinatawag na testing. Gagawin mo ito gamit ang git branch
na utos:
$ git branch testing
Gumagawa ito ng isang bagong pointer sa parehong commit kung saan nandoon ka.
Paano nalalaman ng Git kung anong branch ka naroroon? Ito ay nagpapanatili ng isang espesyal na pointer na tinatawag na HEAD
. Tandaan na ito ay mas kakaiba kaysa sa konsepto ng HEAD
sa ibang mga VCS na nakasanayan mo, katulad ng Subversion o CVS. Sa Git, ito ay isang pointer sa lokal na branch kung saan nandoon ka. Sa kasong ito, nasa master
ka pa rin. Ang git branch
na utos ay gumawa lamang ng isang bagong branch — hindi ito lumipat sa branch na iyon.
Madali mong makikita ito sa pamamagitan ng pagpapatakbo ng isang simpleng git log
na utos na nagpapakita sa iyo kung saan nakaturo ang mga pointer ng branch. Ang opsyon ay tinatawag na --decorate
.
$ git log --oneline --decorate
f30ab (HEAD -> master, testing) add feature #32 - ability to add new formats to the central interface
34ac2 Fixed bug #1328 - stack overflow under certain conditions
98ca9 The initial commit of my project
Maaari mong tingnan ang “master” at “testing” na mga branch na nasa sunod ng f30ab
na commit.
Paglilipat ng mga Branch
Upang lumipat sa isang umiiral na branch, patakbuhin mo ang git checkout
na utos. Lumipat tayo sa bagong testing
na branch:
$ git checkout testing
Nililipat nito ang HEAD
upang tumuro sa testing
na branch.
Ano ang kabuluhan nito? Gumawa tayo ng iba pang commit:
$ vim test.rb
$ git commit -a -m 'gumawa ng isang pagbabago'
Ito ay kawili-wili, dahil ngayon ang iyong testing
na branch ay nilipat nang pasulong, ngunit ang iyong master
na branch ay nakaturo pa rin sa commit kung saan nandoon ka noong pinatakbo mo ang git checkout
upang maglipat ng mga branch. Lumipat tayo pabalik sa master
na branch:
$ git checkout master
Ang utos na iyon ay gumawa ng dalawang bagay. Inilipat nito ang HEAD na pointer pabalik upang tumuro sa master
na branch, at ibinalik nito ang mga file sa iyong tinatrabaho na repositoryo pabalik sa snapshot na tinuturo ng master
. Ito ay nangangahulugan ding ang mga pagbabago na ginawa mo mula sa puntong ito nang pasulong ay magkaiba mula sa isang mas matandang bersyon ng proyekto. Mahalagang iri-rewind nito ang trabahong nagawa mo sa iyong testing
na branch upang maaaring kang pumunta sa iba pang direksyon.
Importanteng tandaan na kapag ikaw ay lumilipat ng mga branch sa Git, ang mga file sa iyong tinatrabaho na direktoryo ay mababago. Kung ikaw ay maglilipat sa isang mas matandang branch, ang iyong tinatrabaho na direktoryo ay maibabalik upang magmukha ito katulad sa huling pagkakataong ikaw ay nag-commit sa branch na iyon. Kung ang Git ay hindi maaaring malinis na gumawa nito, hindi ka hahayaan nitong maglipat.
Gumawa tayo ng ilang kaunting mga pagbabago at mag-commit muli:
$ vim test.rb
$ git commit -a -m 'gumawa ng iba pang mga pagbabago'
Ngayon ang kasaysayan ng iyong proyekto ay humiwalay na (tingnan ang Divergent na kasaysayan). Ikaw ay lumikha at lumipat sa isang branch, gumawa ng ilang trabaho dito, at pagkatapos ay lumipat pabalik sa iyong pangunahing branch at gumawa ng iba pang trabaho. Parehong ang mga pagbabagong iyon ay magkaiba sa hiwalay na mga branch: maaari kang lumipat pabalik at patungo sa pagitan ng mga branch at pagsamahin sila kapag handa ka na. At ginawa mo lahat iyon gamit ang simpleng branch
, checkout
, at commit
na mga utos.
Maaari mo ring madaling tingnan ito gamit ang git log
na utos. Kung patatakbuhin mo ang git log --oneline --decorate --graph --all
ito ay maglilimbag ng kasaysayan ng iyong mga commmit, na nagpapakita kung nasaan ang iyong mga branch pointer at kung paano humiwalay ang iyong kasaysayan.
$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) made other changes
| * 87ab2 (testing) made a change
|/
* f30ab add feature #32 - ability to add new formats to the
* 34ac2 fixed bug #1328 - stack overflow under certain conditions
* 98ca9 initial commit of my project
Dahil ang isang branch sa Git ay talagang isang simpleng file na naglalaman ng 40 na karakter na SHA-1 na checksum ng commit na itinuturo nito, ang mga branch ay mura lamang gawin at sirain. Ang paggawa ng isang bagong branch ay kasing dali at kasing simple katulad ng pagsulat ng 41 bytes sa isang file (40 na mga karakter at isang newline).
Ito ay nasa matingkad na kaibahan sa paraan ng karamihan sa mas matandang mga kasangkapan ng VCS na branch, na nagsasangkot ng pagkopya sa lahat ng mga file ng proyekto sa isang pangalawang direktoryo. Ito ay maaaring magtagal ng ilang segundo o kahit mga minuto, depende sa laki ng proyekto, samantalang sa Git ang proseso ay palaging madalian. Gayundin, dahil nagtatala tayo sa mga magulang kapag tayo ay magku-commit, ang paghahanap ng isang nararapat na merge base para sa pag-merge ay awtomatikong nagagawa para sa atin at kadalasang sobrang madaling gawin. Ang mga tampok na ito ay nakakatulong maghikayat sa mga developer upang madalas gumawa at gumamit ng mga branch.
Tingnan natin kung bakit dapat mong gawin ito.