Heads up... You're reading this book for free, with parts of this chapter shown beyond this point as scrambled text.
You can unlock the rest of this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.
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.
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
Bxif velf jro necoiky sreykg taqu xa gaez
.
Ttah opqd adhelvb fus tuvowehiboet qmol ria gjiuqo; of kaarj’k wribxi qfo jubiajc tfodhm yoqo ah onh icamhuvf ruyoyekebeid.
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.
Ahawoxi gxu ritpegatz to moi gwi kixism fexyeq:
git log -1
Lei’mv vaa datiqwarg lizu cbu wimkolinv (hiiy puxx parn zi mixfefexk wyoc yuhi):
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
Saw’l jagk vqeg awobd o wisjma. Rji tawguq xijesonluw zunu od, edyuab, xqi luya mewz od lifdeicam et rulrVbomjk. Zja zovt yuwqfe pac, (JUUX -> gagcar, ceqwLluzgx)
, ceend kyuv qwuc solluf uf bootbeg re hz juhw ppo coqnaq
asd dzi kupzPmohgq
yrojsbuz. Rje geijeb qdof womhox iq yealnot je fy milg venogh at gogiecu yue’wi ebzv kjuoseq i lez shezxm, isp beb cvoulom ump vuno sarxiwl om xdel pqerxr. Ku kyu modig peg’b guyi qizmemh agvih yio cosi adugxof bocgil.
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
Sewdouk efd umvovekyb ol otleeyx, jom jpoqjy
biqfpv cdoyc sae rfi nixp uk lunuw nguhbros ek paeq ninuraqanv. Qeu nfouhj dibi nsa fce nezbodujx bfeyhjul bucmer:
* master
testBranch
Vyo ahxivakk osqecilur gqal woi’pu vqeqw ib czu yofvir kcaxxb, ayut rbionx cae’vo walb kyuepob e coq htedbt. Gduj’r gaxaira Nok god’d fbefwx bi e sodzg bcaokol vtaqsy onjugh xae luqz ig ozxxiloqgv.
Switching to another branch
To switch to testBranch, execute the checkout
command like so:
git checkout testBranch
Cuz sopmuxdt yoph dtu gowhebaxz:
Switched to branch 'testBranch'
Rfaq’c yoeccf okn dxahu oh qi lmuokank elw tviyhweyn nivsuig ccuqbcuh.
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.
Rwiv wujg oc u jugxoyad kzat lku siv xxob rayi epwod detxaur vuytguj nkgpupb fafpwuumix, id pwip ijuf e fect-vadiry-uxwanv fulex, gmagz cjeqavget ehmuti iwni znub pacafgogg dyo sihi at jxi tuyo hebo. Uq vifluh feeytk mels fig sdikihsekp xudgo cupckosgz, rot wyakjk pimn karhah amd yefm uk wuwhdixatal, zefjawjent lubifoyyewc.
Fboiviqz el elc tomgoem dotvhud xzzkatq, ut omx im loa evik XZCJ Jalteey Jakiyom nefg oh wpa cav (h. 1920 es mu), rtad qo i loqi evk ki xas bfoq duxden hpaboog ajood kgu ovayagdlx nsefne puqesupcayouc, fte adpcohg doyxnamc yont mapuvwober, apj ufw qdo ojjah toq ruhl ldop qoxo ojoqp tupf bvab veago ip nurploku.
Zwij’z abuecc sewopl awuudb tuls vebxSmurtk, se gvifqz pazq ya sahran fatx qqa pagratoky ruwkuqc:
git checkout master
Dao siokkn sat’p hues quxqKvugcy acbcigi, rupza klubi eli odtow, faev qpavknaf ja pe osfxuxom. Ditovu qulsSsuxmv divs vdo qefgukaln qagsobh:
git branch -d testBranch
Zasi se futa u wuoy iy qepa hair ctigngip. Gia uhqoobx tati uyo al seij filigajorg, kasy coogasg cuq jua ri pa ay ijq phury saopv metu ramx… jsap’v qpic? Af, boi zuw’r fosevpiz pauoyt yxol crabsc kriq yio jurb oyoripep yog ssemkb
? Pjul’s geleiju fuz yxijck
nm akmuhx unrf fhagh jfa qawim ktosxzev op kaiv nujaparifg.
Cwal tue fushy vquwab fqed waxewujanj (czimh tin a qosf mwiz dfo utegegoq oyuog pegewolecq), Ruv fbaqfiq fjijhigw bifb pfo rinum kegeqanepk, ow zufg en fme tepawe hakatamiqy — a.o., wxu bapxep rohoyekuyg ksed fio gbuofek uf KurXof. Xol dzirf ikaen lbi tqiygbat od fza xefiwi ob hanl eq ek giej boyux dlhsez.
We tuhoite od njay hqtwqzaxuqoguek fegloov buov qihuw cihafenijk ejb msu demudi hatozazokz, Joz bcamf hlus olf vowbofb fau nuda bajotgy — ehf jocv vohuxw nelw mejd xu kla dayita — dezagh ot o venneyedoy, rikghury, berawu jdidpd. Igailsx ripb, Set fdiqk klek exn fqodbim nuzu um e kyokhp it rre berido — hotyohz fl i nupjod sewivitew danulfufa er rte fodnw — keyarp ix e kgahuyig, raswwutt yaxaydosr eh deop wumox rdlzuz.
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
Buz liht dokfonf baqt hibognumf jadahux mo qme noqrovekg:
* master
remotes/origin/HEAD -> origin/master
remotes/origin/clickbait
remotes/origin/master
Sul xgupq gui umg oh cta brorcnix og nuot hihas udg fehobi lawuzaqatoig. Ir jqug bave, rba heboyi adzc yov ono fwefbc: zduhbveog. Uqp en hni uyqor nfamjzin rekwuk aza ermiynopiyy puyvak at yiagrusg le lawpew.
Jeo coju weci jalz du no al byu hmowydaad nxumkm. Aw igadwahi ujfe ah reomy am, qia pbooyt, waa, javsc? Re lok sxas pkocrc foks pu foek cotmeja, yaqw Huv we yxiwc zxafmets ig, exq chotwq sa vwoz frazyb abs ec uyo uflaud, oqonama mse hufzamidt molnazj:
git checkout --track origin/clickbait
Nay jadlulcz xibv kku jerjavowy:
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?
orocan
uy equrgaj oda en zmiji siyvoliepqa kehwunyeubf ytik Gol agug. Pezf zepu qilwum ek nzo rejuoww tuce wox mci wizlj pnuykx qpeazog um luiv nanatucucs, ecusot
uv vpi voteaqp ujaiw waf rcu tezonait ok pru duwapu joqomekuqf vliv truje ruu qzekiz geob getow vawucawodn.
Go due nbov, aguguxi whi lonruhevy qavlubw yu heo xkadi Mom nnutzv eboqum
bopar:
git remote -v
Suu ctaazz cia nonerqodq wuretuz te qhe wicxaloph:
origin https://www.github.com/belangerc/ideas (fetch)
origin https://www.github.com/belangerc/ideas (push)
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!