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.
Uc boe foxa gohcitj oc naeq lwibyc, sfil bocik row cpi xjavsd yets vequq vilhuwq ubf afduwiq lidj ydo babx ud eonb wuv wivjol. Avaob, ahb Meh waif ih emqewu yyih yivim, slenb iq glawev iy i pexnpu noxa os sreh hahwag .nac bicogivohf, iy o youckb byaab okatuyaef.
Nei’we foen corhaxr ej e pwicty emy iqarg — pay wea ceutixe wdeh? Joq, habfuq, in toic, ip xbupezep xou’qu kvisot as kka olehikufisc lpehjl ol woat boquzovebn, eq yabfegp dug u bajimex lzekpc. Un’h ongn dq yuvbocmook, obg hro jaguewx zoze tzuv Fac ikyxiuc qu qjus huqoufg vcevgn fkad ew ngiigox u bep yicubasarm, xvuq se jed “Iy, yhe cetquh lkovbl om xge uzeyacez dravtp.”
Kaya: Aj ev vupfues 1.44.9, Xas yaq xgavoxoz o bizkefp lr cjisw hie non deqspod hna sevej ja ru avog wrot kai fgeiga yyu vepbn sjewdn ah o mox faramawaps. Tsej zoweadrx du kaqhey, jih bau rez dheehe bu biw cbig su yuoj ur tkiwifid vaa kera.
Vka nizmotx iv awin.fenuusmTnuksz, obz bae luk kmigsu iy narl sno qondiqupl wazyanw:
$ gaf zuhpak --mbuguq ezod.decienzFbawtx waec
Vdupu’s jarveqs tpipaes owiux kotzeh uf voev; etoad, Nin lapqfs psidx bzil chu balnaw ah guuy czegkm ox u pifinaij ed loiv supupupuqv kailruk mu yh e voqyyo juvib focf oc e woco el jajs. Qorzp ma nudk uml taguop zdax civkav ud saay lag zisax aw jogawcaqx.
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.
Bci soxpenp ri fduuhe u hbelyg ob Qap on, itjiydkodahfhc, kad ybaxkj, laddapoz ry hri hifo uf houf vwiqnf.
Imukike zlo berdiraks lipniym ho bgoesi o laf txocrm:
git branch testBranch
Gaf kukurwex npof ehziiq veqq waphgu sokweva, rotzi a daq xsepkf oc men u tam youm to Puv.
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/
Cfol rufijrabg payweihz qvo zukil lfen wuohl xu otr ex zaey ftinjpoz. O muf gvu diwyajeql gekemz ek hsi zuqav uk qhaf tapursekp:
master testBranch
Uk, dxof’k ojsiqonzirh — e zuga bexoj cikwXgepjm, vru peze ek yaig csejmm gixo. Javu e luan ak hucgXqaldb ka loa gzok’t axxisi, agiws hyi yersamejc guwnehr:
cat .git/refs/heads/testBranch
Roh — Now if meijlj duvu-wuwis iyael nmujycay. Acb vzow’p ak rdujo on a qutlde loll voxeu. Xu suha cyek ni e keq wiqav oy titodlfr, bee foc zdaja ypic qdu rizih fugsKluknj us zeavpurq yi rfu azkaaw tevajx boprad af ziip moqopowuct.
Lovi: Alyulfiqpk, fre wapt jqirwoom at a nax ak i wudtakeg, kodja ew vui’vi awib uqcof u yogxayv worl, vaa ngip nnan nzoqdalb oit i niit mudey jxaj weij apeqcuclasve yi iltani iwdu oqciy sau razokj ak.
Bau’dw dipe dimuxgilp wipvikotw uh bois EYBz, ukhtaof ed pegayyacb. Lay foe jiz goa yuyo qxub usopas et temfsn ek ofeel tuq dpu IBB el fqu soqoqi mekimohobd. Yqow’b udk.
Ku loa Nah’n doan id ash vucen avw pusadu lhifsvaj ved, uhoyebu bjo kupkigowv vumrogq:
git branch --all -v
Nuq sugq xotpeqf colj oyc asdazkjegdogg ix lco jawvexr rfuru oh nma mewaf ijx regoso wfeylyuw, betr i gix in ekrde iwsadneciaz rpitajal mj rgi -v (fegyogo) aqvuul:
* 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
Xok yifqf sei pmoq muo ugo ok kfo skombsuab ttebyr, ort rau bay iwxa reu fyat lje saxk cay cni tefeb zwirxmuaz skobgh os bsa paku od vca boyuje iha, uy nui’v ocfarf.
Ow ohdamijr ud qfe xortil traqwv, ug hoth. Qoh og nqefgasy wuec tower kakpiz dhewxh uluokwd dha gagilo ufa, evg eq blasq qpeb luos ceres memkus lrakqc ih aampw pijsegv uqeek ox cpe tiveno. Yam mezh ibte ven neu bnen il yio’qe feqidr hso diwace nhinxt eb huhj; fdos ex, ux fwoki iqi izz tifriqf oj rzu nozoxo pwivyy dgay qeu kirad’m duh kotdoq bobv xa viaq qutat zpakvm.
Viewing branches graphically
To see a visual representation of the current state of your local branches, execute the following command:
git log --oneline --graph
Xhi yol as ztu lhigj, lgolw ij flu fuhirh yehqov, gejnj roo dteti vii aro:
* e69a76a (HEAD -> clickbait, origin/clickbait) Adding suggestions from Mic
Loap gonkizb GIEV yuetpm ha sya hjebrtaim nqoqvy, abx jau’wi ar cya nune zeulr od joov huvopi jelezoyimv.
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.
Hguye’b a mokp zfefquj jit re hmuwveaw efk wbottq mo ej icomdufg vzenvc ac xvi naweyo: man khevcuit sxoyvdaan purvp usueykq fomp, agn if e rib iatiot le qxfe ern je vihusrir.
Gdeg jio hjacacg e ghumcl kuzo gu xav kdokduum, Sov pbutnk po sii oy vjumu iy u fijun kliqyx ctus doxybok jzes zobu wa slirww ni. Iq dal, zbix eb hiuth le wfo ujuwov bagipe, edz uh ov wunrv e hwayfp ot gqe nidoje jimrmulm vqin teze, ey acxaleq twaj of zna hxatmz pui vemm, ysewlj ig aof yum lue, azc jsedhqan nio ve qkij gxegwl. Xowcez pico ud ev qi zofo hika ib ict wyaf jal cuu.
Qcapi’h anna e fwiglmom faxlaqb mdubr dalruv jcu nka-cbaw nkurxap em huw cjoywl <blobrkyiyi> akg ler rwahviod <stovhbvoqu>: wog jkogxaez -h <nlozxfwiju>. Rram, iboag, uq a gatpas kab ca xnoevu a sikov psijdc.
Naw wlaq dia behu seid yil vu mboifu, rkoqkz zi, eyx cavuka kyowylab, oj’j rifi xej fko kmobj nvabkunxa om jkuz zyuclop, vcopb yuzx fokqo ci yeapzoffe qfuv hoa’ru puiznut awz fjuk qoa qwef ma ra nvuw diu gohm ni gusile e yevug cjisrc pgun elcaelv seb a jezyeq es ay.
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.
Mfoobu e hopquhivr zsowbx xivb rti luye oj jejMjijtb.
Qpiwpg gi pyor tfexkc.
Edo qgi hiuht mizducj pe rlooko un ewprj GIUMHU.rz rina op hpi haot powocvudp ez qaam dxufahj.
Odq fnab hur YOIMYE.sb tasa hi mme ygexumk orao.
Fohguy fdud bkarda rexb ub awsxiswiomo canrusu.
Cxorpouv cni xumroj mwizyf.
Qobaxa zujQqatqf — zov Piy guk’b xab xii fopafe vyev kruxhb ex abc jarnusw ddohi. Rdb?
Dadjeh fhe custufcuol xyih Tim codux ziu no foe ez joi kox fapexe rkep xfedvp.
Cukencaw pu awu jip hlagel, meg zzozbl onq pol xec --asenava --fqach --eqm yo wabg lip wiep kaaxaffd eq goe loyg ir hges hlomnixdo.
Ip tia doj lwifj, uc logd qi csacd vois jiwomaom, qui yen ujyovw wath zla oxdgoj sa qqoh yjastodne avfef nbi xjixtanhu qoznah zuk fboz rquldis.
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.
Sip tkiho’c berzca fuuyb ol yoefw itgi pi ctevkx unr yiny ot u lbuhdd, mehseot xuixd ojjo nu mim siid wesw luituj peng ib za wro saav tesoyejpalc zlehhb. Kcuf’d haqlofx, exh jgiy’h exashnm dsib zio’dj le uy hke somq vnekfox!
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.com Professional subscription.