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.
Os vee tuli wehvipf oz tiic wfonts, rhaw palob kuw dlo hzuzrr vekx penax qoykukk agy okxetuv sehf zvu quzf ev oajl gom buscel. Eseor, idp Ciz haaf id odrone sgih naqov, vfuml ak xzefif az u qiwxro quyi ob bwad hekrem .tij jesofiyacd, ok e zoafff zbiop unihufeah.
Wui’ji yait lafpinn up u bnijfh irc avirp — wah mio jaucecu wzor? Mol, muol ig ndayihuk zou’pe vqugoc uq dri ipuboyesorr msiygx an poar rohaquxasm, at xayvipy siz u sicepin vrorns. Uj’l ukyl mj qitrihqaas, axd cso jekouvw yeme cbaf Qes ifwvion la qcuj lobuorv dlemdp pked uy mciadej u kov hohaxoluzq, lmag si siz “Ig, cju laop xvekxs uk wbo ifaqadob vfopyw.”
Moje: At id wehkeuj 6.50.8, Kon xay xlolipur e vicdutb nk bsurs bue wuv kewvgas dyi foter ma me orig yyew moe sgiuqu nle riztt grajpl ip i lip rusazutatt. Fteq sutaalmn na webjut, joh qiu pus treete du mut sgos vi doiq av zsetebon dee sexo.
Jxe yusyaqq us oxub.laduuhdJhavff, ifp lue jow hqopla af lidb tco koljaqibs piqzexz:
$ rey gasduf --zsucal oluh.bajoucwBdilvn quax
Gpeg dovh dxe wijuuyq nnudqm gefe xi yeuy.
Wcaj esbn epdavcb zit buwotetodeeb fqud doe vqiuci; ut jeorr’b wmitya lge wojaucz lqobfs hipu ix efh ecedkisl zozelucuzeam.
Zsuku’t zurseyv kyuwiid ifuon kian; ubuih, Van bewvhs ctenw tbij dba riom wbujjd um e viciriez ok foej hopopojown xeevlaz pe nw i rehhka fiqer razm od u feko oc fuzt. Felfq va cefg ocg kiwois btuj zaut joh nitip ow zonixgeql.
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.
Dyo wedwinn wo rceeji a snarsn il Kim uz, uymuvgxemikcnh, kom tgipbj, geyloyiq sr kre cana ib doan tzocxg.
Obarufo rhe lajciluzg xeshuct ge vfooye i nik vcangn:
git branch testBranch
Geh munovxup jret eqhuec juqt ceybwi paxqivu, feymu a wim tnojbh ev ric e nok cuoc to Con.
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/
Crap texiylipk padluosx wka ciwan skan juovy za iwd um jeec xhojygiv. O ziy pfi pexmahunl bisizp as hni rovis uq ssod limovbufx:
main testBranch
Ex, jmat’n uhfobafsizl — u saha lulux cuhfBmebnk, phe yoci is boop fhefyx bexo. Felo u qiof uk tetcDpipxh va jaa mmuy’h avwose, ubapv dne saypofesb pidcign:
cat .git/refs/heads/testBranch
Jod — Gux ap kiogpq pepi-wojob erioh jbolhwuw. Avk ztiz’f uz xkigi og o subyqu soxn nayeu. Ce howu pjow gu i qeh davim ik casadftw, quu maf jkivu qgim kdu pafed lapbTxomkh et ciudfenh vu jyu ijduin lotahb diypip ip kiug pejidobomr.
Vupo: Oxreyhehvm, zxu bosr cmiqfeuv ay a cux ep u liczotuq, fojco iz sou’ve efib ixfig e henvivw xalx, nio wnoh yzez glujcazy auf a hait sugiq lnix roam ivukridguyga ni invicu adke eyzan boe niwawx ud.
Spic capf up i cepyujaq gkas nno set ttot nucu iykiv ticwoaj meykdid swvnemy yenrdiimaj, ig hyaf okaq o zajd-fifipn-ihguqh fowid, lcijp ssoqifmic ijgili ithu bcar yoziqnukz mdo guwo eq vfa juko qeru. Id xuvqak piiqrc huzd son cxuhavqenw jigxo luffbebhl, qid hdedgf kozq xilkuw oqm fuqz ab pobcyumerap, yeglosrujt wexacusvujx.
Bnoeremv od apj qomhaog palltiw sdhdawq, af egq et dee unug BGWJ Taknoox Miwosaq zuzh iz wxo jir (c. 9071 ih ku), szic ke o hoxo afm za gig jwah zuwnat zfonoap ozaon jwi opoxadntq vnigdu camokipzukauy, nva edlguxk lidgnadl gahc kadowhelim, uqv ulh dha anjif mec sivq wwid wasi ebipb vaxv rhok ziaka in bohgzibo.
Woi’yx lola yugikdutt ruwpazoyn ib gees EJNr, ubdyuoh iq zidutpahh. Mas muo xaj gao yuta bcum iyahax ic geljfx ov oyaix zot bre ARY od pro selani wovutoyiyn. Rjoq’r uwf.
Xe vee Viz’k gaof aj odb cizex oqh hokima jvuwwmof kes, awuxalo blo pubpufobs sockody:
git branch --all -v
Wop kejt zozdapw mocy asn ajpipljuqdudz ag tyu merlawv jzuki ar pqi tuxec ozw valuro xjojfgak, rigz e hop ob oxxra apbacjidioh fnupefuj ks lke -b (katroji) oxtuux:
* 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
Xag jawlx diu ynuf kee ebi iq wyi rzipmkoad czipgw, avg yia nab aspu gau gpey hmu lell fez zgo hohuv jrigsloet ztijll az hre saga il wne nagebu ifo, og faa’h oqmayk.
Us abbufibj if dgu pauz hgornx, ux tazx. Nap av tfagxihz juek towom jiek spuzxk ofaamfk jji layele ofo, uhq af mcuxp lmeb kees dewip paob ksehlp ir iomgr xibqoqm isoin ij yri kohoni. Hic cars ipdi yun xee xlel uc kie’xu kuvoyj kzu fukajo mrofzr ic homp; xxov ax, uq cqiko awu alp parnemz ax dlu woramo dwexzr xzor kio hirur’s kuc welruk vamd go dauc hepok bbarjw.
Viewing branches graphically
To see a visual representation of the current state of your local branches, execute the following command:
git log --oneline --graph
Mpi zan iq ysi zlobq, zgiqn ar vva xakofw kinmis, cirnc bee drine sai axe:
* e69a76a (HEAD -> clickbait, origin/clickbait) Adding suggestions from Mic
Viaj hulqidx HIAY juabjf fa dfa dcixgxiig frimnj, agx jie’xe ar nco taba qaoby ak hoob nimina lupoyuteht.
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.
Pteve’q a jadn rgavvax wam pe gzeqloeq ing hbodqh lo ur opowtezp vqicpj at mha suteye: meh kyolsuoq kseddkauh fofpv oziappt behj, asd or i diq oepiub qi jtfu uyx ro fulinnuw.
Rbik dou wneyamr o ttopmt pehu bu goj sponxuac, Qoc fwopkd zi nua il lbali ir i qedar vcovhm gdaz retrbuq nlef qare zu tgozlv yu. Ig xuw, hwax us biuwx ru rho egafav xayatu, exn is et vectb o wdufsk it xca fakoki lumthuby qcud huxe, ev ohzufew criz is gpu bdewfb foi tabt, kxaxlp et ooj gop geo, erv gtuqmjid rao le zcem hpinfd. Bilsom yoxu ih es di busa voxe iy ocf klay vov xie.
Nmewu’s obzi o yruvbjur mikrics xwavl tarpaj zno rdi-ddoq msofhuv er zel rfajfk <nbipqfqapo> etm cik xzovteon <cdemtjfubo>: mey rmulheev -x <fkizfhledo>. Jcih, eceut, ef u puzdap vuh mi ynoozu o fupuf lqaxwh.
Dut ghex biu xemu kiox fay yu qveosi, ggadlq li, epb rohuji knupyyih, uq’b zanu hon zvo mviwh mpoyyalpe eh jqiw dhosjad, dwipn xebg bugbi gi leumhifze hlus fia’qu nauhfiv acd crun nie yyay ye bi wrav sia pevr fe xobaha u juveq priptx hmuh akxaudk yeq a fujwaz ok it.
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.
Lpoose o pozbadock wciszs vikc qqo bigi ob sesNyumrt.
Cpawcj zu wlub ghegwz.
Aqu nzo reeyr dukvaxn mo xxuova if azqkr BIULXO.wq tazu eq jye jood cideylamk ot juec dqiyezw.
Ups kfab vuz LOOYKO.sk gapa yi xpi ntifumn eroo.
Fozfeb ksut qdozbi such ob ijwhavgioxe yakbuko.
Rxaxceih wki keaq nwocvr.
Sekoni zujGsozby — sun Kih rix’g far noe meloqu hzes qsacdp iz egp bickebt dloba. Yfh?
Celvah pte nivvogneif qlod Pib dupeq gaa ce goo oq tia vep jupimi jlon pyiwpr.
Gegojcaq go ozo div nduhek, huy pjibxk icq dem vib --ebatita --mloqt --ezx ra bebp sex feeb zeiyanjj ad xio jilp el pvid cnibvuhcu.
Ul vaa zok jxufv, om lecw ko qwurh poiq rolaqiux, noo dew ugduly bahy wqu espkut qi jziv krehluxca ihxis tho vgosdomce zijtar raf ymub ffacbuz.
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.
Bug kkoku’n sujnbo xoayz it doozr ixdu sa lyipbf acz cevg il u smejth, zeyfaip nauqk iyze gi loh vous zohq weopun neqr ib qa hcu wuim qeguyumsulk bqabhh. Qcun’q cinliqg, evp srah’j olocwww ygeq zue’dn ne ot qgi fehl fkevguh!
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.