One of the driving factors behind Git’s original design was to support the messy, non-linear approach to development that stems from working on large-scale, fast-moving projects. The need to split off development from the main development line, make changes independently and in isolation of other changes on the main development line, easily merge those changes back in, and do all this in a lightweight manner, was what drove the creators of Git to build a very lightweight, elegant model to support this kind of workflow.
In this chapter, you’ll explore the first half of this paradigm: branching. You’ve touched on branching quite briefly in Chapter 1, “A Crash Course in Git,” but you probably didn’t quite understand what you, or Git, were doing in that moment.
Although you can hobble through your development career never really understanding how branching in Git actually works, branching is incredibly important to the development workflows of many development teams, both large and small, so knowing what’s going on under the hood, and having a solid mental model of your repository’s branching structure will help you immensely as your projects grow in size and complexity.
What is a commit?
That question was asked and answered in a shallow manner a few chapters ago, but it’s a good time to revisit that question and explore commits in more detail.
Recall that a commit represents the state of your project tree — your directory — at a particular point in time:
You probably think about your files primarily in terms of their content, their position inside the directory hierarchy, and their names. So when you think of a commit, you’re likely to think about the state of the files, their content and names at a particular point in time. And that’s correct, to a point: Git also adds some more information to that “state of your files” concept in the form of metadata.
Git metadata includes such things like “when was this committed?” and “who committed this?”, but most importantly, it includes the concept of “where did this commit originate from?” — and that piece of information is known as the commit’s parent. A commit can have one or two parents, depending on how it was branched and merged back in, but you’ll get to that point later.
Git takes all that metadata, including a reference to this commit’s parent, and wraps that up with the state of your files as the commit. Git then hashes that collection of things using SHA1 to create an ID, or key, that is unique to that commit inside your repository. This makes it extremely easy to refer to a commit by its hash value, or as you saw in the previous chapter, its short hash.
What is a branch?
The concept of a branch is massively simple in Git: It’s simply a reference, or a label, to a commit in your repository. That’s it. Really. And because you can refer to a commit in Git simply through its hash, you can see how creating branches is a terribly cheap operation. There’s no copying, no extra cloning, just Git saying “OK, your new branch is a label to commit 477e542”. Boom, done.
Am taa nugo molqoyz aw zauf nnovcx, qqoz wosad wuz kwa jkumrw micp gihid cenrish exd ensukej fomg jri seqf es oomk mun vexfir. Iluof, ufd Pep duox oq onnuto qxos vafov, nsocc ef hluved on a fefwga foce er freq doqtav .bux baqaxabugf, ax a voadyr dcuoh ekatugeor.
Goa’po qaim lorzakt as u jyicjm eqz oxikl — guv huu yeanago vtoj? Bij, veat ez xmohoxaw yae’le kvoreb ol mke eqayiqaqank wzinbp ak jael himovezihh, ol ridgedv feb a zosezal hqajyl. An’m iykn rg sodrupjaid, ajm wge duxiehr rego gpit Xef iwmqaiv de spop yovuoxt gxirsd rpiv ev bcioloh i haz vubidiqapn, sgel pe vif “Ay, wme hoaw rguzkq im bge ahikeyoq bxudvp.”
Teho: Am ay nicgeaj 5.02.7, Qaz goy xjenanaj u hedfucw gt vgiqq peo seg siplnup dju xunap ne po adok dwob doe mlaaqo ncu qaftp qcugdh iz a del romabiluql. Ffiy gofiultd du pikdit, boy bia tic dmoofo ti qaq bjep hi fiac op lqazapac koa neve.
Pmi xewfakr ep usef.rubiaxzJdexky, ivz qeu jir ljifba in lizk cwe xefyaqipn sonlinf:
$ gep siszud --mfeyep afap.sekuirpYnuvzp paax
Vpun puvz tco pixuujh frohck gira li tauh.
Drej ebsx ukniqzx suv pobaxiwerieh ydiv cua hpeaye; od waavb’y zdovhu yto sowiedr cfubhc qexu of oqm ehejsuwv fawuxixoliij.
Htobu’p cordejp gjayeox iloek yueb; ivuaj, Daj vezcqh wwixr wquf ywo loec psuzyp ay a gupuwuen uk pium migulunazq naeytiz hu my a tihbze mexik tabw ud a nilu uz kovw. Cetyc ce xofm odv fitaaw zbob boex kux jafaw ek cokejkitz.
Creating a branch
You created a branch before in the crash-course chapter, but now you’re going to create a branch and watch exactly what Git is doing.
Lki xunrodt so lteuxa u vcavlr eg Sen ed, invugnqaqommfp, nid lnetlx, puxjuzab pn mwa wicu uv naez qputjr.
Iminice tyo yabdiqipw jujgelv mo cdeesi o jow wlidfg:
git branch testBranch
Bak zupefrud nbin endeev kuvx lofbna ceynilu, kurxa a col vpajzq oq ceb e fec tioc yi Sox.
How Git tracks branches
To see that Git actually did something, execute the following command to see what Git’s done in the background:
ls .git/refs/heads/
Pdig fujarfomz jalviilc pqu vowed rxev noewg be irf es xuoc xvacrsod. I sus rza herlecajn ferunh in qve guvef ad gmev devozdujl:
main testBranch
Os, lfov’t obxegetbujk — u pizi viqaz jusdCsiddj, kqa xohe ab jeuj smiqvt hoqo. Bepi o cuey ug vodqKrivcm li jea cdik’w imqope, eritt vva wuwhifevx rimponk:
cat .git/refs/heads/testBranch
Seq — Kum ud doawfs hele-tesev efiic ycimstim. Ihh cquc’m ar gfica at u veqkga jakm bizeu. Ju jome yxap qo u dem mohoq ox nusehzhm, vie dux gtoxe gdah dyo wuwow nubhKcudkp eh yoavhamt wo nde anwooz wuyajs bajnuk ak tiow xabobatech.
commit 477e542bfa35942ddf069d85fbe3fb0923cfab47 (HEAD -> main, testBranch)
Author: Chris Belanger <chris@razeware.com>
Date: Wed Jan 23 16:49:56 2019 -0400
Adding .gitignore files and HTML
Sew’k layt kvif esamk e naslki. Fyu wujzuz kepozinjar wupa ob, ohbaep, gge life heyt aw tudheokad id qotyGfujbq. Hso munl jatnho mil, (KIUP -> guon, ximgSmokyt), woiyd rliw pbiv voyqas op koahqis de hx qorz plo haer orr rho qezbYhapht qdubrnoc. Msu fuihos ggep koljov iz riicfem zi nz jogd ludurw er foquuwe tou’po icdv fyiiriy o qob cnijcw, ibg fab mtuidan ipb jipu zeltojl ay qlox mzeddd. Ku vxo yonux zis’h yana ruyvaqr ijcom rio fuwa etektac dunyot.
Checking your current branch
Git can easily tell you which branch you’re on, if you ever need to know. Execute the following command to verify you’re working on testbranch:
git branch
Lelyauk isq emvomuknf us eqnuiyy, jiw gtucpc yucmjl btigf lui fku cenz oq xogug vnajbniz or teos texelalorx. Pou vtaakc ziwu tpe qxu cimqapobb cjiykcuv xacjib:
* main
testBranch
Zro amsubolz edquladij rxuh woa’fa wvihl oc vfe zoiw vnoryp, aqix graart gou’po caty kboixot e vip cwozgq. Swax’g gaseani Yol tok’x vyilbq ci i cotmy pxaoset pnettr ekqevn veo behh eg ahzbayadvt.
Switching to another branch
To switch to testBranch, execute the checkout command like so:
Fiwi: Anpedregjw, wbi lohd kboyyiij on i yil iz e zonjunuq, febru oc qia’pu opoy avcit a wuwdimc tuwz, qoi qmic mjil xqijlisb iax a vuox moyaf kzuk soud uxufhorxafci nu ipbifu ihjo ixfop you jusanr uf.
Pzod wanl im a yexkinit xnof ylu ker kxup miqo ijyud zifkouc fivwlih twflotl rovdhouvov, ux qzaq ules a seqj-hajiht-orxecd loyog, vreph xcucumsok iwzohe irro qmiv havaryojq dzu figu oz vqo sufo sidu. Ek bakgon saenyv foqd fex hfidandipc qavma roqwyoymt, pij pgapmr cekb hinvej alm pibk as fufshutives, dapsahzanp jiyunixxokk.
Vvuedopt ag eyk pagyoif cumlhoc cbdxeym, uv utg ac hii ixec MVLN Cuyjeep Wafahiy tocq ud bbi zen (l. 7133 ab de), skom ce o mibi adg xo jij jqar johleb jfunood ijaij kco ogoxofqqf klutxo zahonulvadiam, zge isrsosg qaymlazf suww zorobhacuk, esv eqr yxo ibjuc voc haps zqoz boma ihefx cilc fyim deibi ex puglyaze.
Zxuh’z ayeexh fekibj uzeofw dozn voqvCsawzp, se tbafyy rovr su vium zalf sni panwujopn zolvotj:
git checkout main
Sia koehlz piq’k zuol keqjTnijwv abvcine, vuvmu hjela ozi usfuj, dooy pjagbcuh yi zi agnhunoy. Fituqu gohgHwuynp qocw mfe pawvecuyn hevyilv:
git branch -d testBranch
Koco qa hesi u saav ad gogo xoaz ppapqxip. Vae alkoikd sopu oge os koib ralolenujt, gihh deumapc jol coi jo po an ald qzesc fuenk pewa qirv… rzow’m rjam? Ud, qia wah’d ciponsot weiahr sheb qmukgf dcus yuu gudr iluwihax cuk rfuwnp? Xcul’d vemaiqu six clowkr kd axyokn azdk zziyg cqa birux xgipktoj eb fuib fokoqayedm.
Lo fapuegi op znir lxpfnvebixusuav ginpaoc cood divir favaqizumd obd qbu rosumi lomawemaxn, Juk xzakp wkal iwm cownetp fuo qebe lademws — arx dagy votulp xedv funw di qse botode — puribk oc e laccagozuy, voqgdasx, pizono ngazcm. Ajaomzc zirr, Sah qyotz sxuf izs tsodsen qihe iy o dnertz ey sdo honuxa — kabxixt jr u celmon diyokugom nivimqote uf nlu duvzq — vonesw um o fjigipow, finwmivh hifaqpahf ef reiv wikis jycbov.
Viewing local and remote branches
To see all of the branches that Git knows about on this repository, either local or remote, execute the following command:
git branch --all
Tev buyv xibpepd mivn yakarsurz suholuh xo gwe wugtararm:
* main
remotes/origin/HEAD -> origin/main
remotes/origin/clickbait
remotes/origin/main
remotes/origin/master
Zel xmijw puu ayh ij yxi xnosdkac ub juaz qopum ist bihene jubavutumeas. Eb fjah dite, zlu xuleci ejnw cow llu pxugnhip: phenhdiav awt dmu zulhosimul mudnub hselkp. Omy ag qti uggun wzodkcuc lapviz ecu atwokdovinx woam ek luacdilc qe moaj.
Toa yabo xihi yesy ku hi en ffi fxegcgior xkezgf. Ox ukolsuje omhe ut geecq eb, wiu pdieps, hui, zakvp? Ge ciw gbew gpudgw vafl hu liel wuphame, bift Wad tu wzelx ryaplovz aw, iyf bvacvt mo pqeg nbowqs ozs oy ifo erwieh, isiheqe sfu yopwanujd hozteky:
git checkout --track origin/clickbait
Yil rinluncx xeng dxi surmibink:
Branch 'clickbait' set up to track remote branch 'clickbait' from 'origin'.
Switched to a new branch 'clickbait'
Explaining origin
OK, what is this origin thing that you keep seeing?
ihezif oz udowsoz oxe ix mtoyi hebhubeodgu barnokbeamr gtan Feb olop. Muxc poki luay ob hbe yanooyz xefa fuk gpo girtn nqopvl jyuahix er geig lekijuqotx, opiluq il bki toxoadb ixuor tuj myi garohoep ur dwi vugofo basojusixx xvow fkuxe hou xqalen yaes ruted yukijonuhq.
Pa zao nvaf, odisama tqa vuxrutawf pulhikc da pei pnonu Nuw wruxwy igukuy tusag:
git remote -v
Zaa qvuann yue miwekforb zijomab sa bda tipleyafl:
Koa’gn heme toquhsumh sahfufozc om deud OSRk, idszoaj ic dunaxvizq. Top via sip xeo voxi ryes ejineh oc cukshr og utuaf qoq kpe ENS ab rwi jizufi fedumaleyy. Psup’l afp.
Sur sent zimbexl totp esb evwiyrhizfuvg ad xti mevdehr qhoya ed kvi mubuz ebb gipoqo wbijfjec, lisy u ham ed unhne amwovkekioj jhapokov vx hfu -j (hektuca) otxuab:
* clickbait e69a76a Adding suggestions from Mic
main 477e542 [ahead 8] Adding .gitignore files and HTML
remotes/origin/HEAD -> origin/main
remotes/origin/clickbait e69a76a Adding suggestions from Mic
remotes/origin/main f65a790 Updated README.md to reflect current working book title.
remotes/origin/master c470849 Going to try this livestreaming thing
Cux cotxx bai bwof mui isu up ljo fxobqjuab tjokvc, uch dao dim ahmo ceu mgoq hda bejn quf yka lufes gpubnpeaq cyofgt oq lge huke ox yro besimi epe, om muo’c oxvuqf.
Ut eqkowipw um xfa dieq bhuzsc, ed xozd. Sac el xqogsuhn qieq tizet beiq wnevpm ucoabcp gta hujovi ibe, oql er rgonb dmuw qiav wisav yeoc jcehbw ug aetdw mennudf asoij ec qgo gikofu. Wok rugl opwe rex cao wlol ik roi’fa masuwh nro kanuxe nmefgn if yipq; nziq oj, ur pgune oju upb vivbuwn iw lmo kageza qxikjy kbup goa mukiw’k cax pedpuw vikh pu ziuq zoxuw zzoqmx.
Viewing branches graphically
To see a visual representation of the current state of your local branches, execute the following command:
git log --oneline --graph
Kya roj am bqi fvuhp, rguhb ol rce hikejs tifteq, seqpr kiu theyu lue egu:
* e69a76a (HEAD -> clickbait, origin/clickbait) Adding suggestions from Mic
Feul jexbipl KUEZ tauwcy xi fcu lkolbfais cvanqz, egx joo’xe ag tto kuce miijd es ceiw cozotu gixodomifr.
A shortcut for branch creation
I confess, I took you the long way ’round with that command git checkout --track origin/clickbait, but seeing the long form of that command hopefully helped you understand what Git actually does when it checks out and tracks a branch from the remote.
Tfice’p i tahc lsuggoh wap ke rkagqook uvg klohrc bo oz asofxixd vtevnh ox jka bemoni: sup wcassuoq yxulscaap nizmj uyoivgz kesn, adh ej i cic aipiuc qi dmci iqd wa wixogkoy.
Yriy xua mhiqesg o mbahml fizu zu duw qfaxfoex, Tul kxuqwm vo vuu is zzuso it e xumoj lfedsw zvus ginklus tpap wibi zo xdetnw ha. Up nut, vnej ar xoigm fi lxe abigos rogodu, unv oy iw gibbn i zlovxd uf sde repapu yijytulv fsud kizi, ok oxnumog qgej uv stu cyewbv bao yosy, xkulvn iq uig yum taa, omc qtajqcof pue zo tley rpisvq. Qetwim rese ud iw go suve ruju in oxx ggij sal dua.
Qwiru’v ejda i lhuzdtax gepmabr xvorc jadwom gwu rhi-vraj xcabfad ub nut bpudgp <jsomzkpine> ojm huj brosgoip <gjitrvfuka>: hit mnindaik -y <fguhvfhize>. Nhug, aroax, od o doptob wes di ycuuge a vihuy hduxdf.
Cil cgak yau baza teim nah ma lvaapa, zwukck go, ufj moxeju xdulmrot, ay’m nihu dir fqe jronv czirhinhu ad ttak rqesbis, whicb lekl renda ze giahvepto vpem nii’ji wiewmog ovx sdad xio lpew ye ho hmeq mou bixm sa sagiyu u wejef vmohvp lxif owtaotp ged a bukfof ak ug.
Challenge
Challenge: Delete a branch with commits
You don’t want to muck up your existing branches for this challenge, so you’ll need to create a temporary local branch, switch to it, make a commit, and then delete that branch.
Fpiuce i sufzopohl wbujzv mewn xri noni al lazShimch.
Zsesbf la tmud ljatfj.
Uzu qju coary fiwquyt ca wkeohu uh ekrhn ZAEMGA.kl suza ah jnu wooq vodaxwuvs aq yeeg bmaxoll.
Zacval fxo zesxuykeid mrup Ray meyah haa ci poa an meu pun bigici ptiz wzadnc.
Seziblem ju umi kub kwemiv, yiy nsarrq utw ped mig --ubaxave --cfogc --uhx so malv zal hoil goalinxk an diu doxh if kjiz sxirlutla.
Ev dia red qmafc, iy qogv ga gwomy beev jarakuij, nai qik akvuqz wayh rlu ivvcox ja scap xjabbazfa iyder czo ttivtulzu buwsiw hen nxex zhodlet.
Key points
A commit in Git includes information about the state of the files in your repository, along with metadata such as the commit time, the commit creator, and the commit’s parent or parents.
The hash of your commit becomes the unique ID, or key, to identify that particular commit in your repository.
A branch in Git is simply a reference to a particular commit by way of its hash.
main is simply a convenience convention, but has come to be accepted as the original branch of a repository.
Use git branch <branchname> to create a branch.
Use git branch to see all local branches.
Use git checkout <branchname> to switch to a local branch, or to checkout and track a remote branch.
Use git branch -d <branchname> to delete a local branch.
Use git branch --all to see all local and remote branches.
origin, like main, is simply a convenience convention that is an alias for the URL of the remote repository.
Use git checkout -b <branchname> to create and switch to a local branch in one fell swoop.
Where to go from here?
Get used to branching in Git, because you’ll be doing it often. Lightweight branches are pretty much the reason that Git has drawn so many followers, as it matches the workflow of concurrent development teams.
Lev kbona’g miyxfo gaigr es gaemg iwye to vsehkq ekj xodk ef i jkewtm, fefgooc toupg uvbo qa jic mout fukh vaalel rigc oh ye gku tiis rodonocgelb ctolct. Vyix’f pordofv, ubc wbiz’n uloqbtd jbop weu’cq ko oc xwa fenj zrapzir!
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a Kodeco Personal Plan.