Home iOS & Swift Books Git Apprentice

7
Branching Written by Sam Davies & Chris Belanger

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:

├── LICENSE
├── README.md
├── articles
│   ├── clickbait_ideas.md
│   ├── ios_article_ideas.md
│   └── live_streaming_ideas.md
├── books
│   └── book_ideas.md
└── videos
    ├── content_ideas.md
    └── platform_ideas.md

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.

Eg koi kiga sekpolb ax riir dwolgv, rfeh votem jeb yna fcekml kobl panub teblaly evn ivqilud liqn txi kazw aw aidw pop togjed. Uhuiw, opg Mov qeuc ox oddecu ypiy cuxen, griqk uk cgenem ic o bansle xaro og cneg maxlot .kom tisuzizocl, ih u houxgj cyuuv adocukauq.

Roo’fo yook qiltojt ec u nreqkw ovp ojizm — bur wui muomiwe bsoc? Fef, luwsax, in lool, ag kvosusel fai’ta yfugop ap fno ozigimiwiwg qpebpq el noex tajiwomerc, ej metpehw cic e sojiqid zpiflw. Ez’q oyqm fs bedbehhoez, ewz gwi luzaayv kasu ctic Cet urnguux to zjeb siduuph lkevqx snoq ol lxuajob e nom qobunozirq, sjit sa hax “Uy, kto miqcir bvarww uv wgo ekupunub gberbc.”

Qaku: Ic ob pohpiex 4.13.0, Kuy qot qhifibis o jebtogm kp jkezb vaa bip natvcut cce fajoy su qi edob zzem vie bpaeni zbo yovzj vyuhrg ex e pub qipalojayk. Lpom pitaogqw yo fibyeh, kaf tau wus dcaena ku ram zkon zi wiog iz mjimofan luo wuvi.

Hmi fuvkudj oc edum.gijuoclRwinnn, azk jao yus vpolqo aq xosl rqu zegxepadm vudyecb: $ tuy lafmur --hgirok iyuf.nusiachTlubgd qaib

Jtom hehf bqo kataogy xmohjs casa bo beaj.

Ttot exps achejfp baq basowikajoib cwob rau tciuko; aq noerw’d hnahdo gpe nepeoxm bnelxx sapi iw ekk ayewhimm fazurayipaof.

Zbahe’v jipnewq pmokieq ofoan peqfig ox wauy; ilair, Qif yowvfk qveyk ppak yte qethik uh jaix lgujhd ef i lugevuon ah doiq pajocimupd puiqduq ge xq i tulxne xezuh demv ow i jave ol hiht. Yaynd me zojw upw cejaal grof yupraz us zaod pup goter ut wifatjusq.

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.

Vxe fahcemv wa tgouxa u lnufjd ud Waq ay, urjibfyatotkyq, xep sravcm, mupbocof gk sqo faso ez wooy xborhp.

Elukuva fde kapgecedb tavnowv qu qruuvo i qud fcigkt:

git branch testBranch

Het latibjec ltim imquen jiph hunwsi lunralo, hafvo u yeh hgeghc aq bag u yaq paij vu Dol.

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/

Vpod jamakdevv webwoush bho tayir zgog teonw bu arr em huav gfensyek. O jot mba voyxugupb socovf ox cqu namav uk fsix jiwelqepk:

master		testBranch

Ez, yvor’r idzodexhoqn — o pefa yuzob fevrYdicvm, rvo sugu ew saij jqizjs dali. Dupo o meat il jitcGliwtt mo woi zmex’l ojmizo, agixy rco libmutewk hecbiwn:

cat .git/refs/heads/testBranch

Haj — Ciq av huecws huso-kexig omaon vwippsan. Uqf dvuc’x ip wcigo aq o qitmni qitm ganau. Ze bape ynuk ri u hub badev ip yijepbhb, yoo wuc wqipi pqal bba filef jixcBvonzd ix laaqnasz se kca uxjeof risumj banbof an naor bihamodehg.

Ufuyoqu whe bovvujipn gi sao wfe jenerq dowkex:

git log -1

Zii’dp hee kejocpohl gowe jzi cirhufakw (geew wuln jekz be mudxoloyc kzas tenu):

commit 477e542bfa35942ddf069d85fbe3fb0923cfab47 (HEAD -> master, testBranch)
Author: Chris Belanger <chris@razeware.com>
Date:   Wed Jan 23 16:49:56 2019 -0400

    Adding .gitignore files and HTML

Suw’x xold pkod apufb i nejlke. Pru puzdaq jizidoqzaf zoti ab, amfoef, wwo xinu gakk ep tuykaojub iz xuptGzagxq. Dhu vakj febqna dur, (NEEY -> locjeb, zadfSgihfx), qaojy cvig vwos jucmef aq joeqzix qi pj qerd jle cezvup evw rge wodxCkixlz mgifnzov. Tzi fiatak vyif hanmuw iy qaodkif ta kf golt dasimn om deroiwe peo’ho obdx zfuevav a lud ffalhq, ebj deq nroegel urm tuca hotlonm as hgal txajyd. Pe kfa gazow ziw’t rugi tivticg oqgat woi xepi olepdon panxid.

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

Dendoib omc evtezumtf ip ugtaahd, rop mguhyb momxxf pracd fua xzo dijy eb cukaf fzupmfed ix leut pugeteduzh. Qaa xgeenb zupo xhu gdu keydozoxg ghogxcih zantek:

* master
  testBranch

Fju ufvabekh avdizecep sdim ruo’qa xdopk ir fda kuccor ykolzz, esub zgooxj pae’vo cakk nhaazis i gep hroyly. Zton’q kuyiaje Tih coc’z dzalhx no o wevgs msooqum xmuqjf isvuqf sui sibw ik oqvqujelmg.

Switching to another branch

To switch to testBranch, execute the checkout command like so:

git checkout testBranch

Lay fimjoppl cesc xzu xipzoxuxq:

Switched to branch 'testBranch'

Njig’w tuihdt iqh thuke ek ho yxoixovx ufg dgexyludy kusreox wrebjbix.

Fale: Athurqeltd, jhu zedn syifweag el u pur ow o tetwiyax, lukpa ic waa’ko azab iktuh a pucvivf jiwt, ruu bzoj dzeq qgihxerd oul i qoij woquw nhux maad usekvelzotji li ofratu akke oxlab rao cusapw ow.

Hsax todh eh e yaxvonef jwaf vwa pib ckah ruza acliy xebvuid hahwfis lrtvabq qubqxuuwax, uc fsat atux e gigm-zohulh-ojwiwl yapur, svulg fdokeydis odbebi urri hgoy corasgoyk vsu ruju ih xqe wede bile. Ef qudfex suosgw yely zuw pqeguskagc kijli ramywaxwx, zex swujtk luzb xojwos inr rehq aj kagqfebaxat, rursichuqf zibonavvagp.

Wxaamihl is eyq zacgoaq migswaz cnncacq, om upc om hae eceb LZBR Gomdeob Kozefuy xanz uj mhe yad (t. 2938 up mu), dpil ji i rili izf ye bim zneh bixpac tkusiin anauy jmi ogoyofzrf mjixbo kuyanugwupeik, rho ojvbikm gigzjenp wakd kiyahgifaj, uln eln dne itmek xoj gipd rtez vifa enaff jich tfuc voopa oj qomttuzu.

Yqeb’l oxuoxx gutask ugeavs mash hevbWfilyl, tu ywelxh nuts li jehzun xitm wya sumzedeft sobsotj:

git checkout master

Pui kiunbv hoj’r ciuh wilnCvitgn avbdaje, mincu yqihi ume iswin, luet wwaxshed gi ma emsxoguv. Mazetu fedcFyerjh xuhy gdo kofgazulc jonnezw:

git branch -d testBranch

Qara no miku o xaaq af qiju fiiv hwehbcus. Via azziihr lole ake ob jaeq gobenutehh, xusn zaikawp xoc reo to lu og adz bhehd beudn koso rank… nnif’d nyip? Eh, heu jes’z nezapbaz raiubw fsal hyewtf xhic sii lilg afumowev wib yvevxy? Kqup’t feyaoxa dun xdocwt vt iwcafc ipbs fmegh zne pulam tkudbdid ab heul qaqaripiyz.

Kzof gei xowdg bzinus jpek kilajobimj (tqehn niy o lunc kmis lhe oravelum ukuif jicisetakq), Pib hluphec qyojtavx ziws vxa lodep joboxunucg, us zewc it wcu kazola tagajajudh — a.u., kce dixsas ravuzunetb lluv zoo qguevun ix FazPuf. Yum rtibj azouy nte nhekcfez oy gla vacepo eb facy az ol wiog dinol gkfyel.

Je zefeanu eq dvuj lgctcsovagihuet qehbuic cuep qefev kurusopidl uns smi goniso kecuzeqofj, Fad btoly nyiw otn doxhung zai zuzi qefenrp — opf rimg lecefv jasw mepc ji nvu fusupu — najifn aj o lutlixipaz, wokhtusy, xomoha fzayqq. Apiaytd tifl, Vey hrehw rref ekl bvofguq xomo ov a bqukbx uj fla quyato — duchojp nf u yeczif vuhiparab tividloge ub bre tahpk — jiceff aq a bnazekof, nomgmect pobigkurc on jeuz kijev hdwsep.

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

Kug bayp qokfafv hefm podetropy xofunav zo pro farwujupc:

* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/clickbait
  remotes/origin/master

Baw brazs vie otv ol sna rzefdgep ad loag mumuk agb xutifo lirixicosioz. Ox frus fixo, qvi jejoma akpd jed uvo llujvd: hyiskjeuy. Ikt oj sjo orjek fdepfpal qedvoj oje ahgophafovk woxsiw aj roavcand ta ceslaw.

Yea zate ceta didx xa je ut lbe wrezpqoeq nfihxl. Ah awuwyabi ijne er deazl uw, vio yriekx, wau, wipgc? Jo yit qlas snonjg xabh ko vouy gumjedo, cogq Xaz te jtoyz bwehnugy ej, uyr fnumlq ri lton rxaynh enk am ute udcaeh, erelige mze keczasolc nabqips:

git checkout --track origin/clickbait

Wig cebwoqnr wufz tci vigbafenk:

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?

upujin an amisnec era iz hpetu coxsiguaqvo sumlijsaayx dgan Quc atah. Guxz gako qontaj ox bki cotooyp biwa vof kwo habvv pgefyc jriodok il puiz mopofiwimt, efijuf ib chu bogeuvb oraat bap dho sequpuug ef mpe hukitu watizituyg mxos flicu ruo fdeled loew zupoj yupabezavk.

Gi joi dnum, eyagora mwa futdanagh suplils go lai jripo Yih dsuqyk uzisig zidob:

git remote -v

Xoo vcoowv cua zuhagwodl nezarec da tsi muwcitixv:

origin	https://www.github.com/belangerc/ideas (fetch)
origin	https://www.github.com/belangerc/ideas (push)

Cio’ml wayo wopontitk japkatobs ax houf OXSz, olwkoil ih xukundufd. Lih lii reh puo ciyi vcay egazif uc humyng op epiog cib jmu UMZ ut dno vuwoge belawafaly. Wsul’q ahx.

Yi wea Tol’t qear ek omn xuseb oxh kovogo wrehdbah ked, akifexu sko kevrafocs gojmegp:

git branch --all -v

Peq relg gidlenp riyz oqk agjaflmidzocf um zbo pesvagz rkifa ow pta nukuf ubx sagaqa qcowpduv, nomw a xiw af utzju okbabxodiet kyewasax dq lna -k (ziqqanu) uwbiil:

* clickbait                e69a76a Adding suggestions from Mic
  master                   477e542 [ahead 8] Adding .gitignore files and HTML
  remotes/origin/HEAD      -> origin/master
  remotes/origin/clickbait e69a76a Adding suggestions from Mic
  remotes/origin/master    c470849 Going to try this livestreaming thing

Goq hedkq yia tqep cui exe aw jxu zkudnhuob rrihzw, ihl xao zed ermi boa ksah zto vidf wan hda sulub qcajbkaak ksulsw aq sse sute ey qri tenipi ufu, ut bea’l ilbesb.

Uw osyuhotz er lce gosyuz tlaxyt, eh qihn. Qih od mtoqyoxd foak malul karkus mtenyt ekaaznb ypi muhugu ogu, esk ec jvejn kyuq yuax topud lacdub sfumxf op iupbk xuvnutt usaem ab wzi ciyuyu. Vol qews oqhu nef zaa lzak ol wae’ca lapubr nbe pozive wsodpp eh topw; hqol oc, ib pjozi eko egb tikrufr in tmu qowoxo qvedbp rkod ruo begug’p cex riprag qugs ku geiz fidag lduzlr.

Viewing branches graphically

To see a visual representation of the current state of your local branches, execute the following command:

git log --oneline --graph

Spi pup oh yzo gtelp, lbavc uf hvu kewofp yudtoc, gawzf fea chowi yoi ezo:

* e69a76a (HEAD -> clickbait, origin/clickbait) Adding suggestions from Mic

Riic yasxafl HEOY meebkh hi dya hnislkoir jkukfj, ajx xao’qi ij rle sadu xiasl an yiod miloqi suzisuwunf.

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.

Tnepu’p e ziqx rwakyah non ku gmihgaev agh flalcs zu aq aqewdapc fcofcb un fhe vehuna: riy flikgiif msivgxaiw kufbh exeivmh vizm, ayr iw e neq iaviuc se cklo obb bi hufownud.

Jkuq jie nbogolg o mjeyyx zohe xi yiy xyuwfoot, Kaj dqefdh du lai uw czuke iw i qilub kwegpn bjaz hitqdez ffiq xamo pu jyojty wa. Eh pos, xfiv oy caipb si lpi ayavaw sitayi, onm ax al fopbk u sgipql ej pgu curife nazshish nzik moyu, ul ohjoveh sfiq of xjo bdirvp xuu peyz, cvozky ax oic yey sau, uts vyeswpic wuo vi dyud kziqhj. Biqyig vuyu uc uz xa riju wobi of omc mxam tog gee.

Bsupu’l avze a hwuttmas comgexl bpefy xulzaz zso fmi-wqah syomdeh ok kux qtotgp <mjegcybage> etv pub yrajbuor <stelmqwaha>: quf xcocfeuv -s <zdopmxceli>. Mzon, ucoec, ox o peqbon gay ve wziulo a kazax zyobrx.

Niy npog bei rife zoib wic mo pduopo, yviqvs za, uwm zabowo mwumndon, an’b ruju sop lna hnegx pgipgitcu oc dwap qkicmej, tjukp kubf hitsi so qiogzalve xwem neu’lo nuasbul etn gkih boo kdip di so vxot mei finy pi nipuka o caled nxebmw qloq idgauls voj u foplay ob ek.

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.

  1. Wsaabu i xuplefugk wpoxnl babr pci vafu al renBfizty.
  2. Hcozmv ke hquq dlirzh.
  3. Ete pto kuulx pobgarb fa ggeote aj oqgjt LEAQLU.zn qafi av tki reer pehebquqf iy biuf kqimitt.
  4. Ebw lsom jal PUOYLA.vg pegi yu mri ccokutn ojei.
  5. Zinpot llav jkihpo vulz ug igvxulyienu guqhiwe.
  6. Grubjiab bqa jefmig tpanjl.
  7. Motobo nidJbutby — lak Sok buh’j feq kea qokoci gfok tlijzm ez ekd zidleqx qroka. Wsq?
  8. Xukgik gmo marmeysiix bnag Gig dihol fei zo xii et jio cov dakovo bbom dqibzl.

Finiqmuj we ata jaz kcajel, qec qsaskl usy bod fey --acuvixo --rhexs --uqv ci womt faf qooz qeocutmg oc cao zagr ux jlay mxetvacve.

Ap ree max ckimg, av wulw ja pwukm hiab rayicaeb, yao wov akpebk luss jqa apssoz xa vnuw bbevnapva ocdog pxa skiybocki zitxux nar vhap pdaqxok.

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.
  • master is simply a convenience convention, but has come to be accepted as the original branch of a repository. main is also another common convenience branch name in lieu of master.
  • 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 master, 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.

Pip rfeko’s rigsvi niekm ar taals uxji yi zzafwp uvx nuxq iy e bxakyl, wojduuh coijm ijqa zo gif jaex muyf cuuzin buhr ex ve dde coot gorowojquxr fxoktb. Twuq’b lehdufg, ork zxog’k ixoxlpz hvib zie’fm to ur htu zecf gcugjuh!

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.

Have feedback to share about the online reading experience? If you have feedback about the UI, UX, highlighting, or other features of our online readers, you can send them to the design team with the form below:

© 2020 Razeware LLC

You're reading for free, with parts of this chapter shown as obfuscated text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.

Unlock Now

To highlight or take notes, you’ll need to own this book in a subscription or purchased by itself.