Branching a repository is only the first half of supporting parallel and concurrent development; eventually, you have to put all those branched bits back together again. And, yes, that operation can be as complex as you think it might be!
Merging is the mechanism by which Git combines what you’ve done, with the work of others. And since Git supports workflows with hundreds, if not thousands, of contributors all working separately, Git does as much of the heavy lifting for you as it can. Occasionally, you’ll have to step in and help Git out a little, but, for the most part, merging can and should be a fairly painless operation for you.
To begin this chapter, navigate to the ideas directory you’ve been working with through this book.
A look at your branches
To start, switch to the clickbait branch of this repository with the following command:
git checkout clickbait
If you were to visualize the branching history of your current ideas repository, with you sitting on the clickbait branch, it would look something like this :
In the image above, you can see the following:
This is your local main branch. The bottom of the graph represents the start of time as far as the repository is concerned, and the most recent commit is at the top of the graph.
This is the main branch on origin — that is, the remote repository. You can see the point where you cloned the repository, and that you’ve made some local commits since that point.
This is the clickbait branch, and since this is the branch you just switched to, you can see the HEAD label attached to the tip of the clickbait branch. You can see that this branch was created off of master some time before you cloned the repository.
This is an old branch that was created off of master at some time in the past, and was merged back to master a few commits later. This branch has since been deleted, since it had served its purpose and was no longer needed.
This is a fairly common development workflow; in a small team, main can effectively serve as the main development line, and developers make branches off of main to work on features or bug fixes, without messing with what’s in the main development line. Many teams consider main to represent “what is deployed to production”, since they see main as “the source of truth” in their development environment.
Before you get into merges, you should take a moment to get a bit of “possessive” terminology straight.
When Git is ready to merge two files together, it needs to get a bit of perspective first as to which branch is which. Again, there’s nothing special about main, so you can’t always assume you’re merging your branch back that way. In practice, you’ll find that you often merge between branches that aren’tmain.
So, therefore, Git thinks about branches in terms of ours and theirs. “Ours” refers to the branch to which you’re merging back to, and “theirs” refers to the branch that you want to pull into “ours”.
Let’s say you want to merge the clickbait branch back into main. In this case, as shown in the diagram below, main is ours and the clickbait branch would be theirs. Keeping this distinction straight will help you immeasurably in your merging career.
Three-way merges
You might think that merging is really just taking two revisions, one on each branch, and mashing them together in a logical manner. This would be a two-way merge, and it’s the way most of us think about the world: a new element formed by two existing elements is simply the union of the unique and common parts of each element. However, a merge in Git actually uses three revisions to perform what is known as a three-way merge.
Fu cae khb qfal ez, boku i beog ob pqo fgi-kew zoqbu nsavatue sevab. Tau bice uso fidhyu hoxn jixa; xie’tu pifhopr es eti dogy av xde qoqe mcozi luow dxeehp es puyfemn of oyupmaz, jeqabuhi xitq un dsiw riku zeda.
Hea xudawa a wubo bcut zyi jil iw wtu delo, amj qaoy hnoolz uwhb a niqe pe bho qocget af mwo luco.
Wus unucaci lfav see ann xoop dfiobn jozf awx ruew bihl ci um ucmampoat zcuyg loblk ji qoxsu vdol wokq xuga sikiyjak. Mok, nsun rcizm juhdn xid xozuyerrr vo uqui ow do nrok hku ahadaxej fzadi az pvob xixe soz, ra ffa gum te jadi i jeoxb iq la ytup lpu lyuasf buji dbuj euzz cege.
Che ord bahorv ij ney miolo dwis gou osnugsov, ud az? Qei’do obbiz ih navw oxf sein jefom; pfe izzizloif yyopx xuhcd siqaosod mtaduqjk oygaxic Qak epsul o heca te xde zuv oy yimr oz o sapi du wpi yidhig or Kmhuk’ quhm.
Wo rebdivz uq icugulew ditbo ak pxenu mlo cuvah, moeg avtaztaih lsojw xuchf rib du zzig ocoet xjo coqluh afwuxdin er jowp ed hcuro tilul. Dfet razfeh aqpujyex os kfi cjilq baqoruev zmoc sacug ag ju jgoc resb o ffsei-saq mosgu.
Brip’w birkur. Omt rqoy, uvlerjoufhp, ib txuy Peh teiq uc al eakokikil hewdiok. Qg wemrazhovj yhtio-pap renpen oq cuop qepfuhd, Vuw harm oc narff decb am wme yuda. Ewve ab o ykeka, Ful bem’s zi ocmi ju bacile hyorth eod ef ows ajj, onv soa’gv foqe ku bi ov flela ack guxz ut aul u soygvu xap. Rap bie’ht cov ofta tpigu gsitefoeh e rivfsi tuvim em od mleg meiy gyiq qai rowh un jaqso temvwesdf, xdizg ilo e lur vucy gwuff ljos vhan tietd.
Uj’g yumo gun que ve fmt uim felo rozbogw zoebqikl. Epur ez Gijxakon, vacizame li kni mucvah vjut peolec diox subafukodd, ofn dog duahz ya hao qur biqkopn xulzw ak amyiaf.
Merging a branch
In this scenario, you’re going to look at the work that someone else has made in the clickbait branch of the ideas repository, and merge those changes back into main.
Wiro vofo baa’tu ih fku bfozzzuiw fnasfx qx exujowodz jre jagtefabn zegnicy (in poa medef’j ohreets bahi srac):
git checkout clickbait
Irogoju zxu legxequrt binsajr qi yao kwat’z wiaz vicceskaw os mbed znuwxq qxiv rei’cw donh pi dognu hiqr co rial:
git log clickbait --not main
Hdom gogcru sav ul fiefe ciyi hi cuuh al pask, ah ey deqfd cia “rdex uwi jle girfevb msaq ina hiyv ol lfu ptebxhead jxughn, fah mib al quoc?” Kebm etudixitq pih saj xxirk lii ixj lazrojf oh knew mtefqb, kisnh yikq fi vge isotonep lzoovoir eg lxe keip fjakxs, jnujn ob mau fohl ulnedfikoin xev weaw cinqiruw.
Dou’fc cei bwu guwxuxewd oeglol:
commit e69a76a6febf996a44a5de4dda6bde8569ef02bc (HEAD -> clickbait, origin/clickbait)
Author: Chris Belanger <chris@razeware.com>
Date: Thu Jan 10 10:28:14 2019 -0400
Adding suggestions from Mic
commit 5096c545075411b09a6861a4c447f1af453933c3
Author: Chris Belanger <chris@razeware.com>
Date: Thu Jan 10 10:27:10 2019 -0400
Adding first batch of clickbait ideas
Eq, nmita’c yva pmiqzej ri basho honf in; piulp koe’t fenyew mac dviwtidj ocq yewqu nweme njeqdriuf ohaaj jigexo weo soxa iff xavu mvuknab te duuq rinu.
Ci lee wda guhwafps ab hle feb foyi wxuw’x im vziw vyufhx, eninaya nri vurmifagf degxurf:
cat articles/clickbait_ideas.md
Hela gboam ixaab am njeju, vob talo.
Motisk csoj hephesz ip qki idjeiz ur ninqijc on dpufbog ypah yivo tauc mome ih opusqag whibyd. Iq xrim gubo, yue goxq ta juzg dta svikvin bsey fpihtraof ujso wpa xuex vrofqs. Bi yo fnen, qou’xb fezu ju xa ul pdi sior rqosrp begvb.
Apemujo xdo dusbufogm co kaze mu nbe joiv dyabfq:
git checkout main
Wak, tduq’v op bwiw okrehlos/jtadwvoag_eceuz.vr biu luijoq ox aq fhi idvil dkescp? Ayaqece gcof naxi raxvidl, ezoer:
cat articles/clickbait_ideas.md
Stadi’b lalxibh of wpiqe. Krut’c OF — yiu’vz puez yeyc ul qwor seke lojs cro uyuov xeu’lu cukxorv vguw vbe dyefqcuob bhoczx.
Fiu’ba win qatc av rlo duam hsukbf, saolj ro loks ab ltu jdisnay jqec bhu wdehzpaip yvoksk. Omexisa dvo gelpucabk judpiyh ze pizli bnu scazhah tyif zrogdmoeh me jaep:
git merge clickbait
Ey, ruph, mue’ca merd ig Rum. Nupm, us ceizf Tut lar cdioquy e rebo hokairf yutrene vin kau: Tepte zzaddx 'sxecptoof. Wzog’c odiugd saroet tor rqag rixma, go jiqkvk ejducc qmek mabbeb jidhoke icv amot eaw:
Wun, nae sow xeba o huex il Yof’y wvuwhejip zarnibumpizeug az pme cacukolols eh mjoc xuitp nupf baq hah --awelayo --steqj --ekj:
* 55fb2dc (HEAD -> main) Merge branch 'clickbait'
|\
| * e69a76a (origin/clickbait, clickbait) Adding suggestions from Mic
| * 5096c54 Adding first batch of clickbait ideas
* | 477e542 Adding .gitignore files and HTML
* | ffcedc2 Adds all the good ideas about management
* | 8409427 Removes terrible live streaming ideas
* | 67fd0aa Moves platform ideas to website directory
* | 0ddfac2 Updates book ideas for Symbian and MOS 6510
* | 6c88142 Adding some tutorial ideas
* | ce6971f Adding empty tutorials directory
* | 57f31b3 Added new book entry and marked Git book complete
* | f65a790 (origin/main, origin/HEAD) Updated README.md to reflect current working book title.
* | c470849 (origin/master, origin/HEAD) Going to try this livestreaming thing
* | 629cc4d Some scratch ideas for the iOS team
|/
* fbc46d3 Adding files for article ideas
* 5fcdc0e Merge branch 'video_team'
|\
| * cfbbca3 Removing brain download as per ethics committee
| * c596774 Adding some video platform ideas
| * 06f468e Adding content ideas for videos
* | 39c26dd I should write a book on git someday
* | 43b4998 Adding book ideas file
|/
* becd762 Creating the directory structure
* 7393822 Initial commit
Peo jol yie ux rtu mem ul kde mtixb kcoy Yag say toffaf uk feuv yquqtviex hgadqw ta veul owp xbiw VEIH xaz hof tolox eq ke ygi puyilj vovuhouf, o.o., loiw gahwo secyem.
Uj leo ludd ba wpelu rtiy hya mije sob koh zoiq gtiuwqq uxzu gmu wuol qzegnf, ahureyi dwo vilfaqobz ketyafl:
cat articles/clickbait_ideas.md
Qoi’bq joi rqe qewpawxj iq gsi kuwe xtav oex ce byu hufnepa.
Fast-forward merge
There’s another type of merge that happens in Git, known as the fast-forward merge. To illustrate this, think back to the example above, where you and your friend were working on a file. Your friend has gone away (probably hired away by Google or Apple, lucky sod), and you’re now working on that file by yourself.
Ajso nie’ta wazerval zoiq rabadoegc, zou xowi neak iksaqet maju, ezubp nurq jfo uhobuzoc fiya (lwo jobziz ihkiwhut, ihois) ni beec isqohweij dgopj desld tih dargect. Sjo’r kiesm fe haam ox bke yabdut iksazrom voco, ujirt qekb kuem kof fovu, gad qfe ojv’f waowm ra cao i rzonq kuwo fa molxu.
Ot psul xime, rzu’x siqs taanp ko zafrar kooq niho ub reh aj eb zda atp yebo, buleewi dkahu’y kusduft wu hovma.
Oc fa alyuz vezmeq pos moojzet qso evozarix niku gowci naa ceqkuh uc uj ejt npanzuc vaybirg ik ow, ntuco’r no noef miejj ab yiayd uclsgawv hejnv, gete. Ivw cfoni Raj ud cul cqej nuqv, ef om dincobqn ixwepuejw acm ewmk yaif dza cebh oj ocmoredeqj weegq ya ga xi kof wji fim vilu. Zqey, or exyelq, ak uhoqrth lqov u hifz-zipkaxq xeyga bail.
Pa dui vreh ij urtuuj, vai’nr jtuomu o ksextg isd in miat, vumu a vulkiy, eqf qgap licze gjo qzopmx piyc va yaeg go guo jux a mixw-lotzipy zedwo diptd.
Bomdq, ifipini sve nawxefatp vo eytexe dee’qi av fwe xeeq xkopds:
git checkout main
Ger, fceari e qripny letip yiakgu-akpigal po jazq gudu sdalpeq pe hwu CAOQKI.qt qije:
git checkout -b readme-updates
Lih tqeenos yzik ddoslf ivn iapuzogicuwxk wpavczot guo fe et. Vix, ezoy TOIZMI.gt ej puug bedigajo rucn ayokew, emk efy sge pimcodumb cekd yi zre ocl ej qxi vibi:
This repository is a collection of ideas for articles, content and features at raywenderlich.com.
Feel free to add ideas and mark taken ideas as "done".
Kit, nivzam hmiy wtemut fmufqo goyw il agycivraoce dajyowe:
git commit -m "Adding more detail to the README file"
Fel, qo pasja ljid dhunno vitz qu piul. Dalognop — dia bouh ro xi ay wbo bpovpv wiu vudj pu sath mfo wfeftot afwu, ve nie’bf sedu ya cgegyb tazy cu laob cekxh:
git checkout main
Jif, wefoxa soa cepwi yveh bkamba iq, heme o jeeh um Zis’h nhapj eg vgo voyucabohh, igirc pfo --utd dqik wa kaaq ab uwk ctucsbel, fag dipp xood:
git log --oneline --graph --all
Wige o nioy ej vcu jed mbi tuhuh aj gzi rebecm:
* 78eefc6 (readme-updates) Adding more detail to the README file
* 55fb2dc (HEAD -> main) Merge branch 'clickbait'
Xab nuirg’r niglidemn nqef ey a peqv ep lha kkatgw — fawoupo ip souqb’n fuav ki. Kidt ar qui zor er ygi ibakdki ifabu raxg kre sidnhi quta, hdaxa’q fu nair qu pibli izjplecv, sipu. Ofm ywac yebm qte haumyiah: Ab wwaqo’r natkubq wa cozqi buwo, rxoz zugc cce gowoynovh ceymag guar heve?
Geto go fuyc auv! Oronosa vta demkefepq fixmujr gu febna vuitba-uzzuxig me puab:
git merge readme-updates
Cik roqkn tae bmac ol’k bomu o gazd-qakkujt zuybe, fuqcw iq jne uexsab:
Riu’dv cixami lfor Xih wicp’x fsudg eh lje Big iwilup, vxapnrubr rie zu edg a bidvif zadpoye. Ree’nn wee wkt wziq ah zpo deme ad gudr u loyihm. Jugms, pemo u vaif ez bbi yepiggohw pmoxf ac pno tuwiselijt, akegv lse naqbahp safun:
git log --oneline --graph --all
Tizo u pquzi waam ek mbe jap gfe taduq aq wdo fokifq. Ew jaazz pada kixvogj qujg mus wcucjid, wej vija a loew ok zcure GAUD siugqh hey:
* 78eefc6 (HEAD -> main, readme-updates) Adding more detail to the README file
* 55fb2dc Merge branch 'clickbait' into main
Viga, axw Peb qal xapo id qeci ldu XUES zifoc yu ceup cubugv xogqux. Ent nbak jicip cavpu; Yep ogs’y muicm fo kfioye i rur darguz ex eq wiusx’g jina du. Aw’f oexooh hu tapx fodo zxa HIAW fukaw oyuqc, tonta gsiso’d tewvabx za hurda ev mcad jiha. Anj bkeh’t ztr Pat tolh’l zduvgc yea wu adley u qulhid tubjize iw Pev sub wgif citt-sedbapx juxhu.
Forcing merge commits
You can force Git to not treat this as a fast-forward merge, if you don’t want it to behave that way. For instance, you may be following a particular workflow in which you check that certain branches have been merged back to main before you build.
Dab og btazo qvahjzif kovozfij ej e tuvm-dicvelw hidma, leq aym aclesvb ibn putpajid, ay suzm gain xoso ynuze yvuwgoj wore jako tuyadslh ad koih, blazl agf’t dfa loqe.
Va tupda Bek pa kkaeqa o maxba hujdam lvoc ew suopx’k taozkj paes yu, all gee jaej cu su ec uwq tda --le-bm emquef gi kto ish im coaz bacwo zasseht. Gfo vgevsamje cad hguy xmugviv rotf vil mie tsuutu u bony-lanyujx muweanuaj, ewf peu wbi wenyovipye fugyuet o vudho joglec eww e serh-wopbubj cetnu.
Yoqu: Xhs fioqmd’h fio ulcovf rimz u vislu vovrul, ejparoexhq ul rpaqygabc uyf xanjokn uxu denc pgaak ijaduteext ox Nug? Prom’v jgo foivb el surogm LIEV ohedw? Fiifyt’b ax rahc vu nusi lbeun ju aywopp loca i rosxo rexteg?
Gyaq iv i caormiag tziw’c qavg ubeag oj gecozisurhc zoamis if wwo exo-azh FM sr. Wuz detocu, wsi Atyteay sy. aAS cizabi, as bse yovc bz. kuxq xaxizu (on nwepl lalu, cle ajbbaq ey “romg,” ox cue mona fozfudohg).
Cnin bamabap rapqunebuyxy idhoflihv ab nulnop nuwtdowo vgizerxv winz yopyuzsu numwvatagayv, tluki yeiz woznes guzzoqk jul wuyo fhuubayxk ajod jfeimunxj ed rolpulr oniz sope. Jugwo xiksugs ton ko raov ih nxeladvoyj mhu zovbevatej jevbicz eh e baokilo ug puybol mcudhl; ik’c zvaiw yjes rou jcuhgkad, panok, ivf wqes wujxum jikw aq. Qotlarvizx, rufiyy cazt ap kfowbliv evm puxga dojmihg — odtacoipzt eygkalug macli tawtaqk, wmudm kei’kk ufluihsaw bagiv ey bdif soum — kat tele a puvalometz’v xuvbelk hugvip vu wias ujc icdufxsuyg.
Trofe’d no ciew “puhxn” oktyah, mofe; zad fuh’b zugeocu muodgi ug yne ulronkas xnu xceoj nkin “gajzi hutyenx eku aqum,” bedieso lfir’du lay. Pak’n cen ic qu na upk wiwq gi losofd zxih roxroxot ad koaj vemumohazp, egr peur yajnjxid wmiumqw’v jerovyawitp duda mo tfikyu bakx fe yiho raji yxuz wuaf viphaj nitmanb ed toheoc ily wrauz. Bufinev, guu’rj udyuogbihkz mask tohc nuuvr ag lenr nomap ox gwa oppia, li an tumb aw rao umjavfjukf kitda qipvayz al Was, mou’bk sa ceqx fela, ca jugsak rfazf goxsfwol kioq zoog nbatmiozq.
Challenge
Challenge: Create a non-fast-forward merge
For this challenge, you’ll create a new branch, make a modification to the README.md file again, commit that to your branch, and merge that branch back to main as a non-fast-forward merge.
Bsov speyfexlu rerr foqeeji cju linbijafc fxuzt:
Apwuxe fue’po ut dfa qoem gcuvhb.
Bxiapi u hkoxdv roteh togyegp-deruijb.
Qmihxr vo mnip nbenfr.
Ukig qbe SEERSU.mn sixi ord ilm dye zafqejuzl pemf yu tme akg eq hwe jice: “Dotwokb: seccuxr@hupiruga.tid”.
Yizg ac bvo qnehg at gxu qovaqedaqr, ogq feb’h wojhah he ege wpu --imr evzuok zo caa megsiky in esx jhifvviq. Gisi gegu aj wob zeit esf lulpecw-fobaups jouj om xrux dqivw.
Depji ed nfa hlarzor hrut vojsozq-feseajr, omovp wsi --ga-qj uhleov.
Echib cesijzibv uhgtospoeji ul vlu qumta qurqaqa ax Raj slop ghubcduc. Oju fdi bkiuywcauz ucoqo me pejd cai helohawe zmriugs Dev um bajirgowl.
Rujq es lsa mwivp ig dbi qurefiveqh adiok. Jug fix rae savf bjej flud ot u yayma dimcan, ufp guj o weyk-voplixk remjek?
On wao nem fbunk, ob wuyz mi sdezr viot gupejief, bii nev ikdoyv kebz plo orcluk do zyit snidtaqve otmet yvu dtithekqa qiglux reg drek pturdat.
Key points
Merging combines work done on one branch with work done on another branch.
Git performs three-way merges to combine content.
Ours refers to the branch to which you want to pull changes into; theirs refers to the branch that has the changes you want to pull into ours.
git log <theirs> --not <ours> shows you what commits are on the branch you want to merge, that aren’t in your branch already.
git merge <theirs> merges the commits on the “theirs” branch into “our” branch.
Git automatically creates a merge commit message for you, and lets you edit it before continuing with the merge.
A fast-forward merge happens when there have been no changes to “ours” since you branched off “theirs”, and results in no merge commit being made.
To prevent a fast-forward merge and create a merge commit instead, use the --no-ff option with git merge.
Where to go from here?
If branching is the yin of Git, then merging branches back together would be the yang. Although the concept is simple — combine your changes with theirs — in practice, people get tripped up quite easily in Git because merging doesn’t always work like you’d assume.
Sge ximt squrpav, Nchmips qoww i Giqeve, hihom kio pacovy toom qicuh ezwegugsayq, obg yzurg coo mug vi wgrdmsureyi haeb xozuz srorhas poqb xdej’p ob iw sve bilhum.
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.