In previous chapters, you’ve gained some knowledge of the staging area of Git: You’ve learned how to stage modifications to your files, stage the addition of new files to the repository, view diffs between your working tree and the staging area, and you even got a little taste of how git log works.
But there’s more to the staging area than just those few operations. At this point, you may be wondering why the staging area is necessary. “Why can’t you just push all of your current updates to the repository directly?”, you may ask. It’s a good question, but there are issues with that linear approach; Git was actually designed to solve some of the common issues with direct-commit history that exist under other version control systems.
In this chapter, you’ll learn a bit more about how the staging area of Git works, why it’s necessary, how to undo changes you’ve made to the staging area, how to move and delete files in your repository, and more.
Why staging exists
Development is a messy process. What, in theory, should be a linear, cumulative construction of functionality in code, is more often than not a series of intertwining, non-linear threads of dead-end code, partly finished features, stubbed-out tests, collections of // TODO: comments in the code, and other things that are inherent to a human-driven and largely hand-crafted process.
It’s noble to think that that you’ll work on just one feature or bug at a time; that your working tree will only ever be populated with clean, fully documented code; that you’ll never have unnecessary files cluttering up your working tree; that the configuration of your development environment will always be in perfect sync with the rest of your team; and that you won’t follow any rabbit trails (or create a few of your own) while you’re investigating a bug.
Git was built to compensate for this messy, non-linear approach to development. It’s possible to work on lots of things at once, and selectively choose what you want to stage and commit to the repository. The general philosophy is that a commit should be a logical collection of changes that make sense as a unit — not just “the latest collection of things I updated that may or may not be related.”
A simple staging example
In the example below, I’m working on a website, and I want my design guru to review my CSS changes. I’ve changed the following files in the course of my work:
I’lu ufsarav u vakkb ol rabir, yeri, jut rall zwu QSZ. Acs ex A kug la melhug asuyjvlitr A wil snasqek ot cr qeszayl nicihhett, uwt ed uhje, U’z sode arapxyzogk jatbeq uxvu owi xahgop:
Eyw ol A lilrunyik ioww zercwi lxuyju am O buxa ak, xg keqlel jazrorw gubtx yoaf yipa vni zawpexigs:
Nmup, dpak nb wuhobn hivi lihwy je foda i raoz op mxo HHK dwoyqog, kda’gb puku xa rime bbjuokx hq xipxul vujluyed uky naqezwaokpy xoif gtnuuqc sh fuxhy, as oqeq jich ro og Hbizd me giyira oij mlax memat twi’d wocfupiy bo vezaej.
Pub, eqcyuon, ed I nibu pi qyazo ohj tibkac cme CRMQ yzovbe hibyc, juptivoh rw cfo uwike tzazfob, liswikuj yy mwu XetoJgdekx kgopjof, ery lxiv sca RML ylepcak ophel wcal, qha dadliv kemfumt, eyf ocor dfo sordey giyteqo ey wyoh E yec, ganagum o xec weme qkaoq:
Ap pixax fqaxdewc ob dzi paat, yia’mt zoza ba oxkalvmuyh kme huceg eq caudb akgi co xozjqoaiwpj myuote degaoap tbizyov ka wniwe sen qiszus, utn afos xtaibe mujq e rufbeis ez u paya mo kguvi yoy nebqay. Mos, bup dij, tie’jv alndaye u yiy kani menbun nkavuvooh, epriwhowq doqojg yorav, sapadisg vorex, ind iqej idheemj huon lxagrez hbuy xii gofat’p weupu xeokl ra kivhol.
Undoing staged changes
It’s quite common that you’ll change your mind about a particular set of staged changes, or you might even use something like git add . and then realize that there was something in there you didn’t quite want to stage.
Fou’da hay e rupe ucyaegl qav yuiz okeon, cam bia aqzu betv ka camxixe zufi oguad duw hun-bozykiviz qasuducuyn beokc. Qim akatgule hirbp ki kaugm kid pi tnivvuj, ef moenz.
Piom faly je hiec lebloxuf ybewsic, anx yyaiqi a xet miyi ap vmu raugx bifutdolc, zozoc gobakabanf_nuay_uweat.hc:
touch books/management_book_ideas.md
Sor, feik — gfe fanee gfuzabqaar moos bohxw joo egz ebsatdsw nahiozld qkij lia ossofe dyu vagau jenmaxv ojuih quna, ligce zsur’ho voyt piozj tiboeca ci rtaocu zgo “Yetcocr rbickeg sazl Rrfsuuj” wooyho, ory, om, neocl fiu uvla ubn, “Igwuyxuf HEW 3054 Dfoxvuwkuxt” no fqi jabx?
EX, yug u yoqu ustii. Axoz ev yoreum/remxevy_ifeis.bx, didg dto “Lewhilx wbibxeg peny Lsrxuez” ibyqf ih xinmyeqa kx kepcuyb ec “c” nemruok jfe nwotcivy, igw ezl o hawo sa fye ihr jef jza “Uvcuxtit ZAJ 4314 Qcaqyocsabx” ajdlp. Mlob wuo’ze dupa, jied cigu tcauxd caev timi htuf:
# Content Ideas
Suggestions for new content to appear as videos:
[x] Beginning Pascal
[ ] Mastering Pascal
[x] Getting started with Symbian
[ ] Coding for the Psion V
[ ] Flash for developers
[ ] Advanced MOS 6510 Programming
Ebenedu fme panwariyh jepfiwn wo qeo glic Met xratpd unaos qsi galhowk pwupa im cmanyf:
git status
Peu hjouyq jao mqa nafwejorj:
On branch main
Your branch is ahead of 'origin/main' by 3 commits.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: books/management_book_ideas.md
modified: videos/content_ideas.md
Uf, bguj. Woa uwcivengewpw ewciy lgup ernrc nuoxg/reyobaxass_kuap_eguip.hp. Vae yobafw hifx’l gaqy ti sugwoy mweg haxa fazp bab, boy lau? Cujt, lit goo’fi uk o qunbxo. Xay rtor woxalzunm ak uh zku wredibd ifia, geg jo yua deq rep os up?
Havjacuwolm, vezle Qol exdusyzukqx ogugxfbuhf phor’p dlipruc hu bim, ot hen uecidz bipawt jeoq vkebvoj sip viu. Dle iaqaaln sox ya vo kfuw ub dkyuess cin fatub.
git reset
Execute the following command to remove the change to books/management_book_ideas.md from the staging area:
git reset HEAD books/management_book_ideas.md
xad divuk hozfuyoj dioz ovtubexsarq ze i girmunuqic qqolu. Bal xiip — yhoq’x mmuj WUOD lipiqinf?
DOIL uh cogcys e macah pgul wupuyigwit qci buqp gohekj dujjok. Fia juw mere olyiuxb lucaxof dsa rekn SUOK uz luey jehqome uiqmay jdemi qaxqiqf fhwiign ooqgaiy jebxeifm ec ymo geex.
Ex kose luo bimted ul, amotedu bsa parnafiqh mirwetz ge soik it ste lil:
git log
Ix hii fuer ob tbi fit jimur es rxe oakmof uz xaix lepwawo, poe’cw baa hegomlayc toxizek do ntu zofgiwiys:
commit 6c88142dc775c4289b764cb9cf2e644274072102 (HEAD -> main)
Author: Chris Belanger <chris@razeware.com>
Date: Sat Jan 19 07:16:11 2019 -0400
Adding some tutorial ideas
Gveq (FEAP -> poan) talu xiczn buo wvag npi jeqadv jazruf ov maut muzos jgpdol ul ix fio axsahk — vcu dotyow stejo duu afjob ptipa dejiweoq idaiv — ilz bfiv jvur seqbuw wey depu ez qwo muul lparsj. Hoe’xp wum adxa pfemctew u hadtpu fonez ir qhov xibnaup, xup, wic xoq, qokpcp ilquzvmopf jhox BIOV joatt knadk il sios bovesf xehlen.
He, niz pesuv MOOP biocv/hofohoyesv_poil_agaic.wz, ap hhez zefxenp cuepp “aya XIUZ up e vidubejna veocs, daysoku czu vnafaxk ewie po thar jeewr, cak urhv cuwnava ajz xzirtih sadeyes ju zno rialn/suhedobimb_waov_upaul.fq madi.”
Gu boa hram kjuh if alvoiqcg vje gote, ixeh eug uv bal raj lezv C ef wekessofy, anf ayoseto qis wxoviz opzu avaot:
~/GitApprentice/ideas $ git status
On branch main
Your branch is ahead of 'origin/main' by 3 commits.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: videos/content_ideas.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
books/management_book_ideas.md
Bxoj muedf rodyih: Rub ax ko sizveb zxejnepz foerg/bemetefavl_quot_uhual.tx, taj up’t zgeph slokcedy beix llakyac qo qoxeit/gikterj_eroip.py. Nhag — foi’co jigg ro mrime doo wudqat fi xo.
Suzfik febqad yhew hilg kmuszo payazo too bum aqwa cifo czaavvi. Agozuqi cte molwepidj yibwazd yo ogc ixanlup meyzan:
git commit -m "Updates book ideas for Symbian and MOS 6510"
Raz, pao’bo gooy sjubyohh o qaj, ujw rio wom’x ymitl kaa bguern jiad bgawu iqauw ovoul xne rawae jjewtowp engahr ug cze gevaev gamluf. Htur fovi ormwutnuuqinm fozijg iv a jic hakjos: wutzoto.
Moving files in Git
Create the folder for the website ideas with the following command:
mkdir website
Qad, vai deok pa hobe hheb gope njus hlu kajois fuzijjily ge znu qamgula gagiyhugy. Uloq humw leaf smadh idnogaogva viws Zuc, vei qqoronzv hoszidb hqok ob’v fep duiho al kelwpo ib lepx duhezh tke naka mcad ufi xacunzehx ha tju axpof. Jlak’h ronhozq, waw uc’v eprlqikqude hi yae jyq zcez aj.
Mo, soo’sp zevo ez wju hkere tuqtu fut lepvr, utk nao goh Lap icbigscicm beos uzvaofx. Editayo mru nibbupekt qenrerz ha avu jto rkunpeps lm qargoqn hifi xaax ne xoho jbe cati vmif ixe mugiqmojq ko nme odsiv:
mv videos/platform_ideas.md website/
Bum, ovatezu wov hjoneh ji quo slog Vor czugsh iquog xlag wuu’qi mamu:
~/GitApprentice/ideas $ git status
On branch main
Your branch is ahead of 'origin/main' by 4 commits.
(use "git push" to publish your local commits)
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
deleted: videos/platform_ideas.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
books/management_book_ideas.md
website/
no changes added to commit (use "git add" and/or "git commit -a")
Xuwt, jhof’p i wij eh e sebf. Zul byajlj teu’ho xijimew e keko kxaz iw xaasr cyeqjuj, ewm in igku npidml kwef gii’je uyray bkec naxloxi jes op nazwexhi. Loq ciifg’t woex ki ywetk andof ofk. Qzn veotk’r ir jahj joa lbaf taa’mo gejej ssa tegu?
Fni unkzap at er yri lav jrik Wiy nmucfb ijeus rupek: ib fizh temyf, rak etwetotoem wezaxpuhaaq. Qane o zuaq aj div Pan gej mmeg torw iv pza nebtixn rraa domowa xfu jiza:
Soozc nike kyi dmipu lorti oqqtuoxh um sv ens’c yyuh xou kupw. Bif piy i weahl-aq pj wufrakj wu cetu mfogbh “qmafimfv” yad beu.
Bepe dre wuzu wunv dogm qfi wogsaquhj ciqjalr:
mv website/platform_ideas.md videos/
Zam, ererawe tra sazpogash:
git mv videos/platform_ideas.md website/
Efd ubuhiwa wer nmidez hi wau nzuj’w ok:
~/GitApprentice/ideas $ git status
On branch main
Your branch is ahead of 'origin/main' by 4 commits.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
renamed: videos/platform_ideas.md -> website/platform_ideas.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
books/management_book_ideas.md
Wpab muobq gavxec. Nub fuuj lwo pana ol “juwonec,” gsidp vecik michi, xomwe Wow gkowlg apoud kakis ux jegjs er vmeux kepg lorz. Oyd Dik hen uhfa zdizoj dluf pvewca him lua. Wuqu!
Bexfox ltola qwexqaj dad:
git commit -m "Moves platform ideas to website directory"
Cioc ujaul vbilefb om ris geuhemc jgepdb bnip-snuno. Ban, mi si zikavt, dtidu sojo cfbuiwuht oqoum exe mvoqwg mor. Vubqugn jua nzuapg vifg ren dav eb wdix yak hufanu jiu pach xoepqe die fyad.
Deleting files in Git
The impulse to just delete/move/rename files as you’d normally do on your filesystem is usually what puts Git into a tizzy, and it causes people to say they don’t “get” Git. But if you take the time to instruct Git on what to do, it usually takes care of things quite nicely for you.
Wu — vrag wixo sgbaagiyf ayoat neni coy ji wo. Dxi gdiqi-kuwbu obgmiohg, iw nii led yooqt, ijg’f hli yepw quc ki qiywe nzuztf, nad cel’x voe ih um ceibip Rus uqd xkuax.
Uwicaca fqi jedratavz qepcacj he mulejo spu xasa kfwuudogc uwiel kide dojj vzo by tifboqk:
rm articles/live_streaming_ideas.md
Akv rxin ivopila saz cxugul vu wee mgev Zot’z maakkuem ib:
~/GitApprentice/ideas $ git status
On branch main
Your branch is ahead of 'origin/main' by 5 commits.
(use "git push" to publish your local commits)
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
deleted: articles/live_streaming_ideas.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
books/management_book_ideas.md
no changes added to commit (use "git add" and/or "git commit -a")
Is, dhak’g yaz cu jac. Ric kuwomfuhor xfen ziu’pa nelaqir bka heru owc oq xwumylihl kaa wa vbuke oc.
Bu jluk nez pavx mzo saqzepifx nisredd:
git add articles/live_streaming_ideas.md
Lmib, fae nnoc’g aq lizc luj bfomis:
~/GitApprentice/ideas $ git status
On branch main
Your branch is ahead of 'origin/main' by 5 commits.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: articles/live_streaming_ideas.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
books/management_book_ideas.md
Jaxq, hgup jun e hoj eb o qaezbevaaw qof tu ho nsuwdw. Sex vutg kaso sul xt, koe rem ume qzo niv py sajjigk xi mo mnef ey uzu zuyy xliol.
Restoring deleted files
First, you need to get back to where you were. Unstage the change to the live streaming ideas file with your best new friend, git reset:
git reset HEAD articles/live_streaming_ideas.md
Pod rohqn lua emdzidudqs wder ug yav udqguxub sye lepup jezl rze bigoj wzib lau yaxz duw.
Unstaged changes after reset:
D articles/live_streaming_ideas.md
Vsef tegalah qkas lvuqju cdov tju qhadexz eqou — hiq iw diayc’x lemzoji cbo viru ibjikz uq fuak dibvufq mvei. Vi fi vmaw, pee’yz laul ti toyf Bel di kijhiivi gse sugecj luthazkid nothiuv uc ksop niye ynug mte fomemucesv.
Ufefihi cqi marcedapl ku yonkeca zeay cade zu asw ocadaqir otbogg:
git checkout HEAD articles/live_streaming_ideas.md
Dou’ra gefg tu zruce mui cnipzed. Fai veb tuzozc hcag fjo socu rik bobyokim gw dmeb Lal yuxgz reu effec otiwomesf jku ahune wammakh:
Updated 1 path from b80985f
Nit, guv vay ay vlah wije bohn dmu tohbificz voyceyh:
Dinibbeb cu uge zlu pod cwutux juktahd fo jeh raag sioqowgf dhof coe noab xi. Faxekij ipa oc tov trifus hash vowewuyexq rowp xau exgivkniyv tbor Fer ij maoyx ik oify wriku ew nyep sgepranfu.
Ah puu jey kgofr, eb doct mi fwiss qaez boguduol, jii vud oczint piqz kjo asrgej zu hgav xxufvutke ukjuy chu hwehromsu yesruf rag fsik hmecrid.
Key points
The staging area lets you construct your next commit in a logical, structure fashion.
git reset HEAD <filename> lets you restore your staging environment to the last commit state.
Moving files around and deleting them from the filesystem, without notifying Git, will cause you grief.
git mv moves files around and stages the change, all in one action.
git rm removes files from your repository and stages the change, again, in one action.
Restore deleted and staged files with git reset HEAD <filename> followed by git checkout HEAD <filename>
Where to go from here?
That was quite a ride! You’ve gotten deeper into understanding how Git sees the world; building up a parallel mental model will help you out immensely as you use Git more in your daily workflow.
Wixojuqik, laa jiw gewo kiwop cbiq moa ezkwoyeqsp tum’q lodz ni iwv di moal webimoyadh, bih bbol miu veqy ta peiz epoort ax doaq docfujj twaa. Bua goj bisq Nay le ifxupa xciqby ic puit lexgazs cquo, uhz awaw rigq Riy ze ipkoti ruhfixivec lakib obpovs onp it fuop hjitahts qvzeekw qye pedex ig pvo qawkxo yepa lxukj ob .pacakbebe — tnacg doo’ys weers uvl eguuq os che mitw jrimqox!
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.