1.1
1.2
1.2.1
1.2.2
1.2.3
1.3
1.3.1
1.3.2
1.3.3
1.3.4
1.3.5
1.3.6
1.3.7
1.3.8
1.4
1.4.1
1.4.2
1.5
1.5.1
1.5.2
1.5.3
1.5.4
1.5.5
1.5.6
1.5.7
1.5.8
1.6
1.6.1
1.6.2
1.6.3
1.6.4
1.6.5
1.7
TableofContentsIntroduction
GettingStarted
GettingReadyforClass
GettingStarted
GitHubFlow
Project1:CaptionThis
BranchingwithGit
LocalGitConfigs
WorkingLocally
CollaboratingonCode
EditingonGitHub
MergingPullRequests
LocalHistory
StreamlineWorkflowwithAliases
Project2:MergeConflicts
Definingamergeconflict
ResolvingmergeConflicts
Project3:GitHubGames
WorkflowReview
ProtectedBranches&CODEOWNERS
GitBisect
RevertingCommits
HelpfulGitCommands
ViewingLocalChanges
Tags&Releases
WorkflowDiscussion
Project4:LocalRepository
CreateaLocalRepo
FixingCommitMistakes
RewritingHistorywithGitReset
CherryPicking
MergeStrategies
Appendix
2
3
WelcometoGitHubTodayyouwillembarkonanexcitingnewadventure:learninghowtouseGitandGitHub.
Aswemovethroughtoday'smaterials,pleasekeepinmind:thisclassisforyou!Besuretofollowalong,trytheactivities,andasklotsofquestions!
License
Theprose,coursetext,slidelayouts,classoutlines,diagrams,HTML,CSS,andMarkdowncodeinthesetofeducationalmaterialslocatedinthisrepositoryarelicensedasCCBY4.0.TheOctocat,GitHublogoandotheralready-copyrightedandalready-reservedtrademarksandimagesarenotcoveredbythislicense.
Formoreinformation,visit:http://creativecommons.org/licenses/by/4.0/
Introduction
4
GettingReadyforClassWhileyouarewaitingforclasstobegin,pleasetakeafewminutestosetupyourlocalworkenvironment.
Step1:SetUpYourGitHub.comAccount
Forthisclass,wewilluseapublicaccountonGitHub.com.Wedothisforafewreasons:
Wedon'twantyouto"practice"inrepositoriesthatcontainrealcode.Wearegoingtobreaksomethingssowecanteachyouhowtofixthem.(therefore,refertothebulletabove)
Youcansetupyourfreeaccountbyfollowingthesesteps:
1. AccessGitHub.comandclickSignup.2. Choosethefreeaccount.3. Youwillreceiveaverificationemailattheaddressprovided.4. Clickthelinktocompletetheverificationprocess.
Ifyoualreadyhaveanaccount,verifythatyoucanvisitgithub.comwithinyourorganization'snetwork.
GitHubisdesignedtorunonthecurrentversionsofallmajorbrowsers.Inparticular,ifyouuseMicrosoft'sInternetExplorer(IE),youmustbeusingthelatestversion.Takealookatourlistofsupportedbrowsers.
Step2:InstallGit
Gitisanopensourceversioncontrolapplication.YouwillneedGitinstalledforthisclass.
YoumayalreadyhaveGitinstalledsolet'scheck!OpenTerminalifyouareonaMac,orPowerShellifyouareonaWindowsmachine,andtype:
$git--version
Youshouldseesomethinglikethis:
$git--version
gitversion2.11.0
Anythingover2.0willworkforthisclass!
DownloadingandInstallingGit
Ifyoudon'talreadyhaveGitinstalled,youcandownloadGitatwww.git-scm.com.
IfyouneedadditionalassistanceinstallingGit,youcanfindmoreinformationintheProGitchapteroninstallingGit:http://git-scm.com/book/en/v2/Getting-Started-Installing-Git.
WhereisYourShell?
NowisagoodtimetocreateashortcuttothecommandlineapplicationyouwillwanttousewithGit:
IfyouareworkingonWindows,werecommendGitBashwhichisinstalledwiththeGitpackage,sothatyoucanfollowalongwiththefacilitatorwhowillbeusingBash.IfyouareworkingonaMacorotherUnix-basedsystem,youcanusethebuilt-inTerminalapplication.
GettingReadyforClass
5
Step3:TrycloningwithHTTPS
Openyourchosenshell,andtype:
gitclonehttps://github.com/githubschool/scratch
Ifthecloneissuccessfulyou'llsee:
$gitclonehttps://github.com/githubschool/scratch
Cloninginto'scratch'...
remote:Countingobjects:6,done.
remote:Compressingobjects:100%(2/2),done.
remote:Total6(delta0),reused0(delta0),pack-reused0
Unpackingobjects:100%(6/6),done.
Ifyourcloneisunsuccessful,readaboutauthenticatingwithGitHubfromGit.Pleasenote:manycorporatenetworksrestrictSSHtraffic,sowehighlyrecommendusingHTTPSandverifyingthecloneworksbeforeclass.Also,ifyouhavetwo-factorauthenticationenabledandwishtouseHTTPS,youwillneedtosetupapersonalaccesstoken.
Proxyconfiguration
Ifyourorganizationusesaproxy,youwillneedtoconfiguretheproxysettingsinGit.OpenGitBash(onWindows)orTerminal(onMacor*nix)andcompletetheappropriatestepsbelow:
Ifyourproxydoesnotrequireauthentication:
gitconfig--globalhttp.proxyhttps://YOUR.PROXY.SERVER:8080
ReplaceYOUR.PROXY.SERVERwithyourproxy'sURL.
Ifyourproxydoesrequireauthentication:
gitconfig--globalhttp.proxyhttps://YOUR_PROXY_USERNAME:[email protected]:8080
ReplaceYOUR_PROXY_USERNAMEwiththeusernameusedtoauthenticateintoyourproxy,YOUR_PROXY_PASSWORDwiththepasswordusedtoauthenticateintoyourproxy,andYOUR.PROXY.SERVERwithyourproxy'sURL.
Step4:SetUpYourTextEditor
Forthisclass,wewilluseabasictexteditortointeractwithourcode.Let'smakesureyouhaveoneinstalledandreadytoworkfromthecommandline.
PickYourEditor
Youcanusealmostanytexteditor,butwehavethebestsuccesswiththefollowing:
AtomVisualStudioCodeNotepadViorVimSublimeNotepad++GitPad
GettingReadyforClass
6
Ifyoudonotalreadyhaveatexteditorinstalled,goaheadanddownloadandinstalloneoftheaboveeditorsnow!YoucanalsoconfigureAtomasyourdefaulttexteditorforGitcommandsusingtheinstructionsathelp.github.com.
YourEditorontheCommandLine
Afteryouhaveinstalledaneditor,confirmyoucanopenitfromthecommandline.
Ifinstalledproperly,thefollowingcommandwillopentheAtomtexteditor:
$atom.
IfyouareworkingonaMac,youwillneedtoInstallShellCommandsfromtheAtommenu,thishappensaspartoftheinstallationprocessforWindows.
Exploring
Congratulations!YoushouldnowhaveaworkingversionofGitandatexteditoronyoursystem.Ifyoustillhavesometimebeforeclassbegins,herearesomeinterestingresourcesyoucancheckout:
github.com/exploreExploreisashowcaseofinterestingprojectsintheGitHubUniverse.Seesomethingyouwanttore-visit?Startherepositorytomakeiteasiertofindlater.lab.github.comTheLearningLabbotwillguideyouthroughprojectsandprovidefeedbackrightfromyourGitHubrepository,helpingyoubuildeverystepoftheway.
GettingReadyforClass
7
GettingStartedWithCollaborationWewillstartbyintroducingyoutoGit,GitHub,andthecollaborationfeatureswewillusethroughouttheclass.EvenifyouhaveusedGitHubinthepast,wehopethisinformationwillprovideabaselineunderstandingofhowtouseittobuildbettersoftware!
WhatisGitHub?
GitHubisacollaborationplatformbuiltontopofadistributedversioncontrolsystemcalledGit.GitHubisfocusedondevelopers,thepeoplewhocodeandcreatesoftware.Ourfocusisalsothepeoplewhopartnerwithandemploydevelopers,whoareencouragingthemtobuildamazingthings.
Wedoallwecantohelpunlockthecreativityofdevelopersandtofosteracommunityofdevelopersthatcancometogether—asindividualsandinteams—tocreatethefutureofsoftwareandmakeadifferenceintheworld.
GitHubconcentratesonthreethings:
Buildingatechnologyplatformthatislikenoother,onwhichdeveloperscancreate,shareandgrowthebestcodepossibleNurturingacommunityfordevelopers;asafeandcollaborativeplacethatfacilitatessharing,amplifiescreativity,andsupportstheprinciplesofopensourceProvidingaccess,openingupacommunityofopportunity,wherenewdeveloperscanbebornandwhereexperienceddeveloperscanhonetheirskillsandexpandtheirknowledge
InadditiontobeingaplacetohostandshareyourGitprojects,GitHubprovidesanumberoffeaturestohelpyouandyourteamcollaboratemoreeffectively.Thesefeaturesinclude:
IssuesPullRequestsProjectsOrganizationsandTeams
GettingStarted
8
TheGitHubEcosystem
Ratherthanforceyouintoa"onesizefitsall"ecosystem,GitHubstrivestobetheplacethatbringsallofyourfavoritetoolstogether.Formoreinformationonintegrations,checkouthttps://github.com/integrations.
Youmayevenfindsomenew,indispensabletoolstohelpwithcontinuousintegration,dependencymanagement,codequalityandmuchmore.
WhatisGit?
Gitis:
adistributedversioncontrolsystemorDVCS.
GettingStarted
9
freeandopensource.designedtohandleeverythingfromsmalltoverylargeprojectswithspeedandefficiency.easytolearnandhasatinyfootprintwithlightningfastperformance.
Gitfeaturescheaplocalbranching,convenientstagingareas,andmultipleworkflows.
AswebegintodiscussGit(andwhatmakesitspecial)itwouldbehelpfulifyoucouldforgeteverythingyouknowaboutotherversioncontrolsystems(VCSs)forjustamoment.GitstoresandthinksaboutinformationverydifferentlythanotherVCSs.
WewilllearnmoreabouthowGitstoresyourcodeaswegothroughthisclass,butthefirstthingyouwillneedtounderstandishowGitworkswithyourcontent.
Snapshots,notDeltas
OneofthefirstideasyouwillneedunderstandisthatGitdoesnotstoreyourinformationasseriesofchanges.InsteadGittakesasnapshotofyourrepositoryatagivenpointintime.Thissnapshotiscalledacommit.
OptimizedforLocalOperations
Gitisoptimizedforlocaloperation.Whenyoucloneacopyofarepositorytoyourlocalmachine,youreceiveacopyoftheentirerepositoryanditshistory.Thismeansyoucanworkontheplane,onthetrain,oranywhereelseyouradventuresfindyou!
BranchesareLightweightandCheap
BranchesareanessentialconceptinGit.
WhenyoucreateanewbranchinGit,youareactuallyjustcreatingapointerthatcorrespondstothemostrecentcommitinalineofwork.Gitkeepsthecommitsforeachbranchseparateuntilyouexplicitlytellittomergethosecommitsintothemainlineofwork.
GitisExplicit
Whichbringsustoourfinalpointfornow;Gitisveryexplicit.Itdoesnotdoanythinguntilyoutellitto.Noauto-savesorauto-syncingwiththeremote,Gitwaitsforyoutotellitwhentotakeasnapshotandwhentosendthatsnapshottotheremote.
ExploringaGitHubRepository
ArepositoryisthemostbasicelementofGitHub.Itiseasiesttoimagineasaproject'sfolder.However,unlikeanordinaryfolderonyourlaptop,aGitHubrepositoryofferssimpleyetpowerfultoolsforcollaboratingwithothers.
Arepositorycontainsalloftheprojectfiles(includingdocumentation),andstoreseachfile'srevisionhistory.Whetheryouarejustcuriousoryouareamajorcontributor,knowingyourwayaroundarepositoryisessential!
GettingStarted
10
UserAccountsvs.OrganizationAccounts
TherearetwoaccounttypesinGitHub,useraccountsandorganizationaccounts.Whiletherearemanydifferencesintheseaccounttypes,oneofthemorenotabledifferencesishowyouhandlepermissions.
UserAccounts
WhenyousignedupforGitHub,youwereautomaticallygivenauseraccount.Permissionsforauseraccountaresimple,youaddpeopleascollaboratorstospecificrepositoriestogivethemfullread-writeaccesstotheproject.
OrganizationAccounts
Organizationaccountsprovidemoregranularcontroloverrepositorypermissions.Inanorganizationaccountyoucreateteamsofpeopleandthengivethoseteamsaccesstospecificrepositories.Permissionscanbeassignedattheteamlevel(e.g,read,write,oradmin).
RepositoryNavigation
Code
Thecodeviewiswhereyouwillfindthefilesincludedintherepository.Thesefilesmaycontaintheprojectcode,documentation,andotherimportantfiles.Wealsocallthisviewtherootoftheproject.AnychangestothesefileswillbetrackedviaGitversioncontrol.
Issues
Issuesareusedtotrackbugsandfeaturerequests.Issuescanbeassignedtospecificteammembersandaredesignedtoencouragediscussionandcollaboration.
GettingStarted
11
PullRequests
APullRequestrepresentsachange,suchasadding,modifying,ordeletingfiles,whichtheauthorwouldliketomaketotherepository.PullRequestshelpyouwritebettersoftwarebyfacilitatingcodereviewandshowingthestatusofanyautomatedtests.
Projects
ProjectsallowyoutovisualizeyourworkwithKanbanstyleboards.Projectscanbecreatedattherepositoryororganizationlevel.
Wiki
WikisinGitHubcanbeusedtocommunicateprojectdetails,displayuserdocumentation,oralmostanythingyourheartdesires.Andofcourse,GitHubhelpsyoukeeptrackoftheeditstoyourWiki!
Pulse
Pulseisyourproject'sdashboard.Itcontainsinformationontheworkthathasbeencompletedandtheworkinprogress.
Graphs
Graphsprovideamoregranularviewintotherepositoryactivity,includingwhohascontributed,whentheworkisbeingdone,andwhohasforkedtherepository.
README.md
TheREADME.mdisaspecialfilethatwerecommendallrepositoriescontain.GitHublooksforthisfileandhelpfullydisplaysitbelowtherepository.TheREADMEshouldexplaintheprojectandpointreaderstohelpfulinformationwithintheproject.
CONTRIBUTING.md
TheCONTRIBUTING.mdisanotherspecialfilethatisusedtodescribetheprocessforcollaboratingontherepository.ThelinktotheCONTRIBUTING.mdfileisshownwhenauserattemptstocreateanewissueorpullrequest.
ISSUE_TEMPLATE.md
TheISSUE_TEMPLATE.md(anditstwinthepullrequesttemplate)areusedtogeneratetemplatedstartertextforyourprojectissues.Anytimesomeoneopensanissue,thecontentinthetemplatewillbepre-populatedintheissuebody.
UsingGitHubIssues
InGitHub,youwilluseissuestorecordanddiscussideas,enhancements,tasks,andbugs.Issuesmakecollaborationeasierby:
Replacingemailforprojectdiscussions,ensuringeveryoneontheteamhasthecompletestory,bothnowandinthefuture.Allowingyoutocross-linktorelatedissuesandpullrequests.Creatingasingle,comprehensiverecordofhowandwhyyoumadecertaindecisions.
GettingStarted
12
Allowingyoutoeasilypulltherightpeopleintoaconversationwith@mentionsandteammentions.
include
UsingMarkdown
GitHubusesasyntaxcalledMarkdowntohelpyouaddbasictextformattingtoIssues,PullRequests,andfileswiththe.mdextension.
CommonlyUsedMarkdownSyntax
#Header
The#indicatesaHeader.#=Header1,##=Header2,etc.
*Listitem
Asingle*or-followedbyaspacewillcreateabulletedlist.
**Bolditem**
Twoasterix**oneithersideofastringwillmakethattextbold.
-[]Checklist
A-followedbyaspaceand[]willcreateahandychecklistinyourissueorpullrequest.
@mention
Whenyou@mentionsomeoneinanissue,theywillreceiveanotification-eveniftheyarenotcurrentlysubscribedtotheissueorwatchingtherepository.
#975
A#followedbythenumberofanissueorpullrequest(withoutaspace)inthesamerepositorywillcreateacross-link.
:smiley:
Toneiseasilylostinwrittencommunication.Tohelp,GitHuballowsyoutodropemojiintoyourcomments.Simplysurroundtheemojiidwith:.
IntroductiontoGitHubPages
GitHubPagesenableyoutohostfree,staticwebpagesdirectlyfromyourGitHubrepositories.SeveraloftheprojectsweuseinclasswilluseGitHubPagesasthedeploymentstrategy.Wewillbarelyscratchthesurfaceinthisclass,butthereareafewthingsyouneedtoknow:
Youcancreatetwotypesofwebsites,auser/organizationsiteoraprojectsite.Wewillbeworkingwithprojectwebsites.Foraprojectsite,GitHubwillonlyservethecontentonaspecificbranch.Dependingonthesettingsforyourrepository,GitHubcanserveyoursitefromamasterorgh-pagesbranch,ora/docsfolderonthemasterbranch.Therenderedsitesforourprojectswillappearatgithubschool.github.io/repo-name.
GettingStarted
13
GettingStarted
14
UnderstandingtheGitHubflowInthissection,wediscussthecollaborativeworkflowenabledbyGitHub.
TheEssentialGitHubWorkflow
TheGitHubflowisalightweightworkflowthatallowsyoutoexperimentwithnewideassafely,withoutfearofcompromisingaproject.
Branchingisakeyconceptyouwillneedtounderstand.EverythinginGitHublivesonabranch.Bydefault,the"blessed"or"canonical"versionofyourprojectlivesonabranchcalledmaster.Thisbranchcanactuallybenamedanything,aswewillseeinafewminutes.
Whenyouarereadytoexperimentwithanewfeatureorfixanissue,youcreateanewbranchoftheproject.Thebranchwilllookexactlylikemasteratfirst,butanychangesyoumakewillonlybereflectedinyourbranch.Suchanewbranchisoftencalleda"feature"branch.
Asyoumakechangestothefileswithintheproject,youwillcommityourchangestothefeaturebranch.
Whenyouarereadytostartadiscussionaboutyourchanges,youwillopenapullrequest.Apullrequestdoesn'tneedtobeaperfectworkofart-itismeanttobeastartingpointthatwillbefurtherrefinedandpolishedthroughtheeffortsoftheprojectteam.
Whenthechangescontainedinthepullrequestareapproved,thefeaturebranchismergedontothemasterbranch.Inthenextsection,youwilllearnhowtoputthisGitHubworkflowintopractice.
Exploring
Herearesomeinterestingthingsyoucancheckoutlater:
guides.github.com/introduction/flow/AninteractivereviewoftheGitHubWorkflow.
GitHubFlow
15
BranchingwithGitThefirststepintheGitHubWorkflowistocreateabranch.Thiswillallowustoexperimentwithnewfeatureswithoutaccidentallyintroducinguntestedchangesonourproductionbranch.
BranchingDefined
Whenyoucreateabranch,youareessentiallycreatinganidenticalcopyoftheprojectatthatpointintime.Thisisn'tthesameascreatingaphysicalcopyondisk.Inthebackground,abranchisjustapointer.
Let'slearnhowyoucancreateanewbranch.
include
Exploring
Herearesomeinterestingthingsyoucancheckoutlater:
https://youtu.be/H5GJfcp3p4QAGitHubTrainingVideoonbranching.
BranchingwithGit
16
LocalGitConfigurationInthissection,wewillprepareyourlocalenvironmenttoworkwithGit.
CheckingYourGitVersion
First,let'sconfirmyourGitInstallation:
$git--version
$gitversion2.11.0
Ifyoudonotseeagitversionlistedorthiscommandreturnsanerror,youmayneedtoinstallGit.
TogetthelatestversionofGit,visitwww.git-scm.com.
GitConfigurationLevels
Gitallowsyoutosetconfigurationoptionsatthreedifferentlevels.
--system
Thesearesystem-wideconfigurations.Theyapplytoallusersonthiscomputer.
--global
LocalGitConfigs
17
Thesearetheuserlevelconfigurations.Theyonlyapplytoyouruseraccount.
--local
Thesearetherepositorylevelconfigurations.Theyonlyapplytothespecificrepositorywheretheyareset.
Thedefaultvalueforgitconfigis--local.
ViewingYourConfigurations
Ifyouwouldliketoseewhichconfigsettingshavebeenaddedautomatically,youcantypegitconfig--list.Thiswillautomaticallyreadfromeachofthethreeconfigfilesandlistthesettingtheycontain.
$gitconfig--list
Youcanalsonarrowthelisttoaspecificconfigurationlevelbyincludingitbeforethelistoption.
$gitconfig--global--list
ConfiguringYourUserNameandEmail
Gitusestheconfigsettingsforyourusernameandemailaddresstogenerateauniquefingerprintforeachofthecommitsyoucreate.Youcan'tcreatecommitswithoutthesesettings:
$gitconfig--globaluser.name"FirstLast"
$gitconfig--globaluser.email"[email protected]"
GitConfigandYourPrivacy
Theinstructionsforthisexerciseusethe--globalflagwhenidentifyingyouruser.nameanduser.emailconfigurationsettings.Ifyouarecurrentlyusingacomputerwithoutaprivate,personalaccount,don'tapplythe--globalflag.Thisway,thesettingswillonlybestoredinourassignmentrepository.Ifyouworkinanotherrepositoryonthissamecomputer,youwillneedtosettheseconfigurationoptionsagain.
Forexample:
gitconfiguser.email"[email protected]"
YournameandemailaddresswillautomaticallybestoredinthecommitsyoumakewithGit.Ifyouwouldlikeyouremailtoremainprivate,GitHuballowsyoutogenerateano-replyemailaddressforyouraccount.ClicktheKeepmyemailaddressprivateintheSettings>Emailssection.Afterenablingthisfeature,youjustneedtoentertheautomaticallygeneratedID+username@users.noreply.github.comwhenconfiguringyouremail.
Forexample:
gitconfig--globaluser.email18249274+githubteacher@users.noreply.github.com
Configuringautocrlf
$//forWindowsusers
$gitconfig--globalcore.autocrlftrue
$//forMacorLinuxusers
$gitconfig--globalcore.autocrlfinput
LocalGitConfigs
18
Differentsystemshandlelineendingsandlinebreaksdifferently.Ifyouopenafilecreatedonanothersystemanddonothavethisconfigoptionset,gitwillthinkyoumadechangestothefilebasedonthewayyoursystemhandlesthistypeoffile.
MemoryTip:autocrlfstandsforautocarriagereturnlinefeed.
LocalGitConfigs
19
WorkingLocallywithGitUsingthecommandline,youcaneasilyintegrateGitintoyourcurrentworkflow.
CreatingaLocalCopyoftherepo
Beforewecanworklocally,wewillneedtocreateacloneoftherepository.
Whenyouclonearepositoryyouarecreatingacopyofeverythinginthatrepository,includingitshistory.ThisisoneofthebenefitsofaDVCSlikegit-ratherthanbeingrequiredtoqueryaslowcentralizedservertoreviewthecommithistory,queriesarerunlocallyandarelightningfast.
Let'sgoaheadandclonetheclassrepositorytoyourlocaldesktop.
1. NavigatetotheCodetaboftheclassrepositoryonGitHub.2. ClickCloneordownload.3. CopythecloneURLtoyourclipboard.4. Openyourcommandlineapplication.5. RetrieveafullcopyoftherepositoryfromGitHub:gitclone<CLONE-URL>6. Oncethecloneiscomplete,cdintothenewdirectorycreatedbythecloneoperation:cd<REPOSITORY-NAME>
OurFavoriteGitcommand:gitstatus
$gitstatus
Onbranchmaster
Yourbranchisup-to-datewith'origin/master'.
nothingtocommit,workingtreeclean
gitstatusisacommandyouwilluseoftentoverifythecurrentstateofyourrepositoryandthefilesitcontains.Rightnow,wecanseethatweareonbranchmaster,everythingisuptodatewithorigin/masterandourworkingtreeisclean.
UsingBrancheslocally
$gitbranch
WorkingLocally
20
Ifyoutypegitbranchyouwillseealistoflocalbranches.
$gitbranch--all
$gitbranch-a
Ifyouwanttoseeallofthebranches,includingtheread-onlycopiesofyourremotebranches,youcanaddthe--alloptionorjust-a.
The--alland-aareactuallysynonymsforthebranchcommand.Gitoftenprovidesaverboseandashortoption.
SwitchingBranches
$gitcheckout<BRANCH-NAME>
Tocheckoutthebranchyoucreatedonline,typegitcheckoutandthenameofyourbranch.Gitwillprovideamessagethatsaysyouhavebeenswitchedtothebranchandithasbeensetuptotrackthesameremotebranchfromorigin.
Youdonotneedtotyperemotes/origininfrontofthebranch-onlythebranchname.Typingremotes/origininfrontofthebranchnamewillputyouinadetachedHEADstate.Wewilllearnmoreaboutthatlater,butfornowjustrememberthisisnotastatewewanttobein.
include
TheTwoStageCommit
Afteryouhavecreatedyourfile,itistimetocreateyourfirstsnapshotoftherepository.Whenworkingfromthecommandline,youwillneedtobefamiliarwiththeideaofthetwostagecommit.
Whenyouworklocally,yourfilesexistinoneoffourstates.Theyareeitheruntracked,modified,staged,orcommitted.
Anuntrackedfileisanewfilethathasneverbeencommitted.
Gittracksthesefiles,andkeepstrackofyourhistorybyorganizingyourfilesandchangesinthreeworkingtrees.TheyareWorking,Staging(alsocalledIndex),andHistory.Whenweareactivelymakingchangestofiles,thisishappeningintheworkingtree.
WorkingLocally
21
Toaddthesefilestoversioncontrol,youwillcreateacollectionoffilesthatrepresentadiscreteunitofwork.Webuildthisunitinthestagingarea.
Whenwearesatisfiedwiththeunitofworkwehaveassembled,wewilltakeasnapshotofeverythinginthestagingarea.Thisiscalledacommit.
WorkingLocally
22
Inordertomakeafilepartoftheversioncontrolleddirectorywewillfirstdoagitaddandthenwewilldoagitcommit.Let'sdoitnow.
1. First,let'scheckthestatusofourworkingtree:gitstatus2. Movethefilefromtheworkingtreetothestagingarea:gitaddmy-file.md3. Let'sseewhathappened:gitstatus4. Nowlet'stakeourfirstsnapshot:gitcommit5. Gitwillopenyourdefaulttexteditortorequestacommitmessage.Simplytypeyourmessageonthetoplineof
thefile.Anylinewithouta#willbeincludedinthecommitmessage.6. Saveandclosethecommitmessage7. Let'stakeanotherlookatourrepositorystatus:gitstatus
Goodcommitmessagesshould:
Beshort.~50charactersisideal.Describethechangeintroducedbythecommit.Tellthestoryofhowyourprojecthasevolved.
WorkingLocally
23
CollaboratingonYourCodeNowthatyouhavemadesomechangesintheprojectlocally,let'slearnhowtopushyourchangesbacktothesharedclassrepositoryforcollaboration.
PushingYourChangestoGitHub
Inthiscase,ourremoteisGitHub.com,butthiscouldalsobeyourcompany'sinternalinstanceofGitHubEnterprise.
TopushyourchangestoGitHub,youwillusethecommand:
$gitpush
Whenyoupush,youwillbeaskedtoenteryourGitHubusernameandpassword.IfyouwouldlikeGittorememberyourcredentialsonthiscomputer,youcancacheyourcredentialsusing:
Windows:gitconfig--globalcredential.helperwincredMac:gitconfig--globalcredential.helperosxkeychain
include
ExploringaPullRequest
NowthatwehavecreatedaPullRequest,let'sexploreafewofthefeaturesthatmakePullRequeststhecenterofcollaboration:
Conversationview
CollaboratingonCode
24
SimilartothediscussionthreadonanIssue,aPullRequestcontainsadiscussionaboutthechangesbeingmadetotherepository.ThisdiscussionisfoundintheConversationtabandalsoincludesarecordofallofthecommitsmadeonthebranchaswellasassignments,labelsandreviewsthathavebeenappliedtothepullrequest.
Commitsview
Thecommitsviewcontainsmoredetailedinformationaboutwhohasmadechangestothefiles.ClickingeachcommitIDwillallowyoutoseethechangesappliedinthatspecificcommit.
Fileschangedview
TheFileschangedviewallowsyoutoseecumulativeeffectofallthechangesmadeonthebranch.Wecallthisthediff.Ourdiffisn'tveryinterestingyet,butaswemakechangesyourdiffwillbecomeverycolorful.
CodeReviewinPullRequests
Toprovidefeedbackonproposedchanges,GitHuboffersthreelevelsofcommenting:
GeneralConversation
YoucanprovidegeneralcommentsonthePullRequestwithintheConversationtab.
LineComments
Inthefileschangedview,youcanhoveroveralinetoseeablue+icon.Clickingthisiconwillallowyoutoenteracommentonaspecificline.Theselinelevelcommentsareagreatwaytogiveadditionalcontextonrecommendedchanges.Theywillalsobedisplayedintheconversationview.
Review
Whenyouaremakinglinecomments,youcanalsochoosetoStartaReview.Whenyoucreateareview,youcangroupmanylinecommentstogetherwithageneralmessage:Comments,Approve,orRequestChanges.ReviewshavespecialpowerinGitHubwhenusedinconjunctionwithprotectedbranches.
Activity:CodeReview
OneofthebestwaystoensurecodequalityistomakepeerreviewsapartofeveryPullRequest.Let'sreviewyourpartner'scodenow:
1. ClickthePullRequesttab.2. UsetheAuthordropdowntolocateyourpartner'spullrequest.3. ClicktheFilesChangedtab.4. Hoveroverasinglelineinthefiletoseetheblue+.Clickthe+toaddalinecomment.5. CommentonthelineandclickStartareview.6. Addadditionallinecommentstothepullrequest.7. ClickReviewchangesinthetoprightcorner.8. ChoosewhethertoApproveorRequestchanges9. Enterageneralcommentforthereview.10. ClickSubmitreview11. ClicktheConversationviewtocheckoutyourcompletedreview.
CollaboratingonCode
25
CollaboratingonCode
26
EditingFilesonGitHubSinceyoucreatedthepullrequest,youwillbenotifiedwhensomeoneaddsacommentorareview.Sometimes,thereviewerwillaskyoutomakeachangetothefileyoujustcreated.Let'sseehowGitHubmakesthiseasy.
EditingaFileonGitHub
Toeditapullrequestfile,youwillneedtoaccesstheFilesChangedview.
1. ClickthepenciliconinthetoprightcornerofthedifftoeditthefileusingtheGitHubfileeditor.2. Makechangestothefilebasedonthecommentsfromyourrevieweroryourpersonalperspective.
CommittingChangesonGitHub
Onceyouhavemadesomechangestoyourfile,youwillneedtocreateanewcommit.
1. ScrolltothebottomofthepagetofindtheCommitchangesdialogbox.2. TypeaCommitmessage.3. ChoosetheoptiontoCommitdirectlytoyourbranch.4. ClickCommitchanges.
Activity:EditingFilesinPullRequests
GobacktoyourPullRequestandmaketheeditsrequestedbyyourcollaborators.
EditingonGitHub
27
MergingPullRequestsNowthatyouhavemadetherequestedchanges,yourpullrequestshouldbereadytomerge.
MergeExplained
Whenyoumergeyourbranch,youaretakingthecontentandhistoryfromyourfeaturebranchandaddingittothecontentandhistoryofthemasterbranch.
Manyprojectteamshaveestablishedrulesaboutwhoshouldmergeapullrequest.
Somesayitshouldbethepersonwhocreatedthepullrequestsincetheywillbetheonestodealwithanyissuesresultingfromthemerge.Otherssayitshouldbeasinglepersonwithintheprojectteamtoensureconsistency.Stillotherssayitcanbeanyoneotherthanthepersonwhocreatedthepullrequesttoensureatleastonereviewhastakenplace.
Thisisadiscussionyoushouldhavewiththeothermembersofyourteam.
MergingYourPullRequest
Let'stakealookathowyoucanmergethepullrequest.
1. NavigatetoyourPullRequest(HINT:UsetheAuthororAssigneedropdownstofindyourPullRequestquickly)2. ClickConversation3. ScrolltothebottomofthePullRequestandclicktheMergepullrequestbutton4. ClickConfirmmerge5. ClickDeletebranch6. ClickIssuesandconfirmyouroriginalissuehasbeenclosed
GitHuboffersthreedifferentmergestrategiesforPullRequests:
Createamergecommit:Thisisthetraditionaloptionthatwillperformastandardrecursivemerge.Anewcommitwillbeaddedthatshowsthepointwhenthetwobranchesweremergedtogether.Squashandmerge:Thisoptionwilltakeallofthecommitsonyourbranchandcompressthemintoasinglecommit.Thecommitmessageswillbepreservedintheextendedcommitmessageforthecommit,buttheindividualcommitswillbelost.Rebaseandmerge:Thisoptionwilltakeallofthecommitsandreplaythemasiftheyjusthappened.ThisallowsGitHubtoperformafastforwardmerge(andavoidstheadditionofthemergecommit).
UpdatingYourLocalRepository
MergingPullRequests
28
WhenyoumergedyourPullRequest,youdeletedthebranchonGitHub,butthiswillnotautomaticallyupdateyourlocalcopyoftherepository.Let'sgobacktoourcommandlineapplicationandgeteverythinginsync.
First,weneedtogetthechangeswemadeonGitHubintoourlocalcopyoftherepository:
1. Startbyswitchingbacktoyourdefaultbranch:gitcheckoutmaster2. RetrieveallofthechangesfromGitHub:gitpull
gitpullisacombinationcommandthatretrievesallofthechangesfromGitHubandthenupdatesthebranchyouarecurrentlyontoincludethechangesfromtheremote.Thetwoseparatecommandsbeingrunaregitfetchandgitmerge
CleaningUptheUnneededBranches
Ifyoutypegitbranch--allyouwillprobablyseethat,eventhoughyoudeletedyourbranchontheremote,itisstilllistedinyourlocalcopyoftherepository,bothasalocalbranchandasaread-onlyremotetrackingbranch.Let'sgetridofthoseextrabranches.
1. Takealookatyourlocalbranches:gitbranch--all2. Let'sseewhichbranchesaresafetodelete:gitbranch--merged3. Deletethelocalbranch:gitbranch-d<branch-name>4. Takeanotherlookatthelist:gitbranch--all5. Yourlocalbranchisgonebuttheremotetrackingbranchisstillthere.Deletetheremotetrackingbranch:git
pull--prune
Addingthe--mergedoptiontothegitbranchcommandallowsyoutoseewhichbranchesdonotcontainuniqueworkwhencomparedtothecheckedoutbranch.Inthiscase,sincewearecheckedouttomaster,wewillusethiscommandtoensureallofthechangesonourfeaturebranchhavebeenmergedtoproductionbeforewedeletethebranch.
Ifyouwouldlikepruningoftheremotetrackingbranchestobesetasyourdefaultbehaviorwhenyoupull,youcanusethefollowingconfigurationoption:gitconfig--globalfetch.prunetrue.
MergingPullRequests
29
ViewingLocalProjectHistoryInthissection,youwilldiscovercommandsforviewingthehistoryofyourproject.
UsingGitLog
Whenyouclonearepository,youreceivethehistoryofallofthecommitsmadeinthatrepository.Thelogcommandallowsustoviewthathistoryonourlocalmachine.
Let'stakealookatsomeoftheoptionswitchesyoucanusetocustomizeyourviewoftheprojecthistory.Youcanfindtheseoptions,andmanymore,ongit-scm.com.(Note:--graphisdefaultonmostGitBashforWindowsterminals.)
$gitlog
$gitlog--oneline
$gitlog--oneline--graph
$gitlog--oneline--graph--decorate
$gitlog--oneline--graph--decorate--all
$gitlog--stat
$gitlog--patch
Usetheupanddownarrowsorpressentertoviewadditionallogentries.Typeqtoquitviewingthelogandreturntothecommandprompt.
LocalHistory
30
StreamliningYourWorkflowwithAliasesSofarwehavelearnedquiteafewcommands.Some,likethelogcommands,canbelongandtedioustotype.Inthissection,youwilllearnhowtocreatecustomshortcutsforGitcommands.
CreatingCustomAliases
Analiasallowsyoutotypeashortenedcommandtorepresentalongstringonthecommandline.
Forexample,let'screateanaliasforthelogcommandwelearnedearlier.
OriginalCommand
$gitlog--oneline--graph--decorate--all
CreatingtheAlias
$gitconfig--globalalias.lol"log--oneline--graph--decorate--all"
UsingtheAlias
$gitlol
ExploreOtherHelpfulAliases
Checkouttheseresourcesforalistofcommonaliases:
git-scm.com/book/en/v2/Git-Basics-Git-AliasesAhelpfuloverviewofsomeofthemostcommongitaliases.
WealsoencourageyoutoreadthroughthesethreeblogpostsbyGitHubdeveloperPhilHack.Histipsarereferencedthroughoutthemanual.
GitHubFlowAliasesGitMigrateGitAliasOpenURL
ProTip#1:Toeditaliasesbyhand,youcanopenthegitconfigfilewithyourdefaulteditor.
gitconfig--globalalias.ec"config--global-e"
ProTip#2:Tocheckouttoanotherbranch,youcanmakeaquickshortcut.
gitconfig--globalalias.ch"checkout"
ProTip#3:Tocheckouttoabrandnewbranch,youcaneasilyextendyourexistingshortcut.
gitconfig--globalalias.cob"checkout-b"
ProTip#4:Youcancreatealiasesthatonlycallonecommand.
gitconfig--globalalias.s"status-s"
StreamlineWorkflowwithAliases
31
ProTip#5:Cleanupbranchesquicklyandeasily.
$gitconfigalias.dlb'!gitcheckout<DEFAULT-BRANCH>&&gitpull--prune&&gitbranch--merged|grep-v"\*
"|xargs-n1gitbranch-d'
StreamlineWorkflowwithAliases
32
Whatisamergeconflict?Whenyouworkwithateam(andevensometimeswhenyouareworkingalone)youwilloccasionallycreatemergeconflicts.Atfirst,mergeconflictscanbeintimidating,butresolvingthemisactuallyquiteeasy.Inthissectionyouwilllearnhow!
Theseexerciseswillfocusonthetechnical"how".Inrealmergeconflicts,it'simportanttoknowwhotoaskincaseyouaren'tsurehowtoresolvetheconflictonyourown.Usuallyit'sagoodideatoaskthepersonwhomadetheconflictingchanges,orsomeonewhoisaCODEOWNERonthefile.
LocalMergeConflicts
Mergeconflictsareanaturalandminorsideeffectofdistributedversioncontrol.Theyonlyhappenunderveryspecificcircumstances.
Changestothesame"hunk"ofthesamefileTwodifferentbranchesChangesonbothbrancheshappenedsincethebrancheshavediverged
Definingamergeconflict
33
ResolvingaMergeConflict
Let'strytocreateamergeconflict,andfixittogether.Youandapartnerwilleachcreateseparatebranches,createafilewiththesamename,andthentrytomerge.Thefirstwillmergecleanly,thesecondwillhaveamergeconflict.Worktogethertoresolvethemergeconflict.
1. Inourclassrepository,createthebranchthatyouwillbeworkingonandnameitsomethingmemorablelikeUSERNAME-conflict.
2. Chooseafilethatbothyouandyourpartnerwilledit.(Oneofyourfilesfromearlierwouldworkwell.)Onyourbranch,editthatfile.Thefilenamemustbethesamefilenamethatyourpartneruses.Makesurethecontentinsideofthefileisdifferent,andthatneitherfileisempty.
3. Createapullrequestintheclassrepositorywithbase:masterandcompare:USERNAME-conflict.4. Youwillseethatthefirstpullrequestcanmergewell.5. Whenyouseethemergeconflictinthesecondpullrequest,worktogethertoresolvethemergeconflict.
i. Workinglocally,mergemasterintothefeaturebranch.ii. Whenyouseethere'saconflict,that'sOK!ThefilesthathaveconflictsarelistedunderUnmergedPaths.
Typegitstatustoverifywhichfilehastheconflict.iii. Openthatfileinyourtexteditor,andlookforthemergeconflictmarkers.(<<<<<<<,=======,>>>>>>>)iv. Bothbranches'versionsofcodearepresent-pickwhichoneyouwanttokeep,andsavethechanges.v. Addandcommitthesavedchangestoresolvethemergeconflict.vi. Pushthefeaturebranchuptotheremote,andseetheresolutioninthepullrequest.
6. Mergethepullrequest.
Whatisamergemessage?Inthisexample,wearedoingarecursivemerge.Arecursivemergecreatesanewcommitthatpermanentlyrecordsthepointintimewhenthesetwobranchesweremergedtogether.WewilltalkmoreaboutGit'smergestrategiesalittlelater.
ResolvingmergeConflicts
34
Project:GitHubGamesInthissection,wewillworkonaprojectrepositorycalledgithub-games.
Agithub-gamesrepositoryhasbeencreatedforyouinthegithubschoolorganization.Youcanaccesstherepositoryathttps://github.com/githubschool/github-games-USERNAME.
Ifyou'reusingtheForkandPullWorkflow,don'tforgettolookintheappendixforamorethoroughexplanation.
WorkflowReview:UpdatingtheREADME.md
NowyouwillpracticetheGitHubFlowfrombeginningtoendbyupdatingthelinkintheREADMEtopointtoyourforkoftherepository.
Remember,yourcopyofthewebsitewillberenderedathttps://githubschool.github.io/github-games-USERNAME.
Thislinkalsoappearsintherepositorydescription.ItisagoodideatoeditthewebsiteURLinthedescriptionsoyoucaneasilyaccessyourgame.
Ifyouclickthelink,youwillseethetextintheREADME.md.Wehaveintentionallybrokenthisrepositorysowecanfixittogether.
Sincethisisareview,wehavewrittenthesestepsatahighlevel.Aswecompletethereview,wewillshowyouafewshortcutsforthecommandsyoulearnedinthepreviousactivity:
1. Cloneyourcopyoftherepository:gitclonehttps://github.com/githubschool/github-games-USERNAME.git2. Createanewbranchcalledreadme-update:gitcheckout-breadme-update3. EdittheURLintheREADME.md.4. Committhechangestoyourbranch.5. PushyourbranchtoGitHub:gitpush-uoriginreadme-update6. CreateaPullRequestinyourrepository(base:master,compare:readme-update)7. MergeyourPullRequest.8. DeletethebranchonGitHub.9. Updateyourlocalcopyoftherepository:gitpull--prune
gitcheckout-breadme-updateisashortcutcommandthatallowsyoutocombinethecreationofthebranch(gitbranchreadme-update)andcheckingouttothatbranch(gitcheckoutreadme-update).The-btellsGittocreateanewbranch.
gitpush-uoriginreadme-updateistheslightlylongerversionofthepushcommandthatshouldbeusedwhenyoupushanewbranchforthefirsttime.
The-uistheshortversionoftheoption--set-upstream.ThisoptiontellsGittocreatearelationshipbetweenourlocalbranchandaremotetrackingbranchofthesamename.\
Youonlyneedtousethislongcommandthefirsttimeyoupushanewbranch.Afterthat,youcansimplyusegitpush.
gitconfig--globalalias.bclean"!f(){branches=$(gitbranch--merged${1-master}|grep-v"${1-master}$");[-
z\"$branches\"]||gitbranch-d$branches;};f"couldbehelpfulhere.Takeapeekintheappendixtolearnhow!
WorkflowReview
35
WorkflowReview
36
ProtectedBranches&CODEOWNERSInsomeworkflows,youwillwanttoprotectcriticalbranchestoensurethecodebeingmergedtothosebrancheshaspassedtherequiredchecksandreceivedappropriatepeerreview.Thereareseveralmethodsforthis,includingProtectedBranchesandCodeOwners.
ProtectedBranches
Repositorymaintainerscanpreventmergestospecificbranchesthathavenotmetpre-definedcriteria.Thiscriteriacanincludepeerreviews,testsrunbyintegrationssuchasaContinuousIntegrationservicesorcodequality,oruntilaspecificcodeownerhasreviewedandapprovedchanges.
Let'senableprotectedbranches:
1. SelecttheSettingstab.2. SelectBranchesfromthemenuontheleftsideofthescreen.3. ClicktheAddrulebuttonnexttoBranchprotectionrules.4. IntheApplyruletotextboxtypethenameofthebranchyouwouldliketoprotect,forexample,master.5. ClicktheCreatebutton.
Withoutcheckinganyotheroptions,basicbranchprotectionpreventsforce-pushesandpreventsitfrombeingdeleted.Tolearnmoreabouttheoptionsavailable,checkoutthedocumentationforthisfeature.
Protip:Youcanusewildcards(*,?)andregularexpressionstomakeabranchprotectionruleapplytomultiplebranches.Checkoutthebranchprotectiondocumentationformoreinformationonhowwildcardsandregularexpressionmatchingwork.
CODEOWNERS
RepositorymaintainerscandefineexactlywhichpeopleandteamsneedtoreviewsetsofchangesbycreatingaCODEOWNERSfile.Forexample,youcoulduseCODEOWNERStoensure:
yourteam'sJavascriptexpertreviewsallfileswitha.jsextensionyourtechnicaldocumentationteamreviewsallchangesinthedocs/folderyoursecurityteamreviewsanynewdependencieslistedinthepackage.jsonfile
Let'screateaCODEOWNERSfile:
1. GoouttotheCodetabofyourrepository.2. ClicktheCreatenewfilebutton.3. IntheNameyourfile...textboxenterCODEOWNERS(noextensionnecessary).Youcanaddthistoa.github/
directoryifdesiredbyentering.github/CODEOWNERS.4. Onthefirstline,type*@YOUR_USERNAME
Thismeansthatyouwillbethedefaultownerforeverythingintherepo,unlessalatermatchtakespreference.
5. Onthenextline,type*.js@GITHUBTEACHEROrderisimportant.Thelastmatchingpatternforagivenchangetakesprecedence.
6. Scrolldown,andtypeacommitmessageintotheCommitnewfiledialogbox.7. ClicktheCommitnewfilebuttontosaveyourchanges.8. NowthatyouhavecreatedaCODEOWNERSfile,gobacktoyourbranchprotectionsettingsandclicktheEdit
buttonnexttomaster.9. UnderRulesettings,selecttheoptiontoRequirepullrequestreviewsbeforemergingandRequirereview
fromCodeOwners.RemembertoclickSavechanges.
ProtectedBranches&CODEOWNERS
37
FormoreinformationonhowtoformattheCODEOWNERSfile,checkoutthedocumentation
ProtectedBranches&CODEOWNERS
38
SearchingforEventsinYourCodeInthissection,wewilllearnhowwecanusegitbisecttofindthecommitthatintroducedabugintoourrepository.
Whatisgitbisect?
Usingabinarysearch,gitbisectcanhelpusdetectspecificeventsinourcode.Forexample,youcouldusebisecttolocatethecommitwhere:
abugwasintroduced.anewfeaturewasadded.abenchmark’sperformanceimproved.
Howitworks
gitbisectworksbycuttingthehistorybetweentwopointsinhalfandthencheckingyououttothatcommit.Youthencheckwhetherthebug/featureexistsatthatpointandtellGittheresult.Fromthere,Gitwilldoanotherdivision,etcuntilyouhavelocatedthedesiredcommit.
Whenyouaredoingabisect,youareessentiallyinadetachedheadstate.ItisimportanttoremembertoendthebisectwithgitbisectresetbeforeattemptingtoperformotheroperationswithGit.
FindingtheBuginOurProject
TheLongWay
1. Initiatethebinarysearch:gitbisectstart.2. Specifythecommitwhereyounoticedthecodewasbroken:gitbisectbad<SHA>.3. Specifythecommitwhereyouknewthingswereworking:gitbisectgood<SHA>.4. Bisectwillcheckyououttothemidpointbetweengoodandbad.5. Runatesttoseeifthegamewouldworkatthispoint.Ourtestistouselstoseeifanindex.htmlfileexists.
GitBisect
39
6. Ifthegameisstillbroken(thereisnoindex.htmlfile),type:gitbisectbad.7. Ifthegameworks(andthereisanindex.htmlfile),type:gitbisectgood.8. Gitwillbisectagainandwaitforyoutotest.ThiswillhappenuntilGithasenoughinformationtopinpointthefirst
badcommit.9. WhenGithasdetectedtheerror,itwillprovideamessagethatSHAisthefirstbadcommit.10. Exitthebisectprocess:gitbisectreset.
TheShortWay
Bisectcanalsorunthetestsonyourcodeautomatically.Let'stryitagainusingashortcutcommandandatest:
1. gitbisectstart<bad-SHA><good-SHA>2. gitbisectrunlsindex.html3. gitbisectreset
GitBisect
40
RevertingCommitsInthissection,wewilllearnaboutcommandsthatre-writehistoryandunderstandwhenyoushouldorshouldn'tusethem.
HowCommitsAreMade
EverycommitinGitisauniquesnapshotoftheprojectatthatpointintime.Itcontainsthefollowinginformation:
PointerstothecurrentobjectsintherepositoryCommitauthorandemail(fromyourconfigsettings)CommitdateandtimeCommitmessage
EachcommitalsocontainsthecommitIDofitsparentcommit.
Imagesource:ProGitv2byScottChacon
SafeOperations
Git'sdatastructuregivesitintegritybutitsdistributednaturealsorequiresustobeawareofhowcertainoperationswillimpactthecommitsthathavealreadybeenshared.
RevertingCommits
41
IfanoperationwillchangeacommitIDthathasbeenpushedtotheremote(alsoknownasapubliccommit),wemustbecarefulinchoosingtheoperationstoperform.
GuidelinesforCommonCommands
Command Cautions
revert Generallysafesinceitcreatesanewcommit.
commit--amend Onlyuseonlocalcommits.
reset Onlyuseonlocalcommits.
cherry-pick Onlyuseonlocalcommits.
rebase Onlyuseonlocalcommits.
RevertingCommits
Togetyourgameworking,youwillneedtoreversethecommitthatincorrectlyrenamesindex.html.
Warning:Beforeyoureversethecommit,itisagoodideatomakesureyouwillnotbeinadvertentlyreversingotherchangesthatwerelumpedintothesamecommit.Toseewhatwaschangedinthecommit,usegitshowSHA.
1. Initializetherevert:gitrevert<SHA>2. Typeacommitmessage.3. PushyourchangestoGitHub.
RevertingCommits
42
HelpfulGitCommandsInthissection,wewillexploresomehelpfulGitcommands.
MovingandRenamingFileswithGit
1. Createanewbranchnamedslow-down.2. Online9oftheindex.htmlfile,changethebackgroundurlto(images/texture.jpg).3. Online78,changethetimingforthegametospeedituporslowitdown.4. Saveyourchanges.5. Seewhatgitistracking:gitstatus6. Createanew,emptydirectory:mkdirimages7. Movethetexturefileintothedirectorywithgit:gitmvtexture.jpgimages/texture.jpg
StagingHunksofChanges
Craftingatomiccommitsisanimportantpartofcreatingareadableandinformativehistoryoftheproject.
1. Seewhatgitistracking:gitstatus.2. Movesomepartsofsomefilestothestagingareawiththe--patchflag:gitadd-p.3. Stagethehunkrelatedtotheimagemove:y4. Leavethehunkrelatedtothespeedchangeintheworkingarea:n
Wonderingwhatallofthoseotheroptionsareforthehunks?Usethe?toseealistofoptionsabovethehunk.
gitconfig--globalalias.cm"!gitadd-A&&gitcommit-m"couldbehelpfulhere.Checkouttheappendixtoseehow!
HelpfulGitCommands
43
ViewingLocalChangesNowthatyouhavesomefilesinthestagingareaandtheworkingdirectory,let'sexplorehowyoucancomparedifferentpointsinyourrepository.
ComparingChangeswithintheRepository
gitdiffallowsyoutoseethedifferencebetweenanytworefsintherepository.Thediagrambelowshowshowyoucancomparethecontentofyourworkingarea,staging,andHEAD(orthemostrecentcommit):
Let'strythesecommandsontherepository:
$gitdiff
$gitdiff--staged
$gitdiffHEAD
$gitdiff--color-words
gitdiffwillalsoallowyoutocomparebetweenbranches,commits,andtagsbysimplytyping:
$gitdiff<REF-1><REF-2>
$gitdiffmasterslow-down
$gitdifforigin/mastermaster
$gitdiff2710b745
Noticethat,justlikemerges,diffsaredirectional.Itiseasiesttothinkofitas"diffbackto<REF-1>startingat<REF-2>"or"seewhatisnotin<REF-1>butisin<REF-2>".Thefinalexampleshowshowtocomparetwocommitsbasedontheircommithashes.Thisexactcommandwillnotworkforeveryonesincethecommitsinyourownrepositorywillhavedifferenthashes.
There'sahelpfulaliasforopeningtheremotedirectlyfromyourcommandline.Checkouttheappendixifyou'dliketoknowmore!
ViewingLocalChanges
44
ViewingLocalChanges
45
TagsandReleasesYoumaywanttoputtagsorreleasesoncertaincommitsinyourcode'shistorytomarkspecificstatesorplacesintime.Todothis,youcoulduseGit'stagfeature,oryoucoulduseGitHub'sreleasefeature.
Tags
Atagisapointerthatpointstoaspecificcommit.Unlikecommits,tagsarenotimmutable.Theycanbemovedandchanged.Let'spracticeabitwithtags.
TagscanbecreatedlocallywithGit,oronGitHub.Whencreatingatagfromthecommandline,it'srecommendedtocreatean"annotated"tag.Thefollowingexamplecreatesanannotatedtagwiththe-aflag,namesthetagv1.0,andconnectsittowhichevercommitSHAisincluded.
gittag-av1.0<SHA>
Toseealltags,typegittag--list.
Anothercaveatwithtagsisthattheyarenotautomaticallypushedupwithcommits.Topushtags,typegitpush--tags.
Youcanalsosetthisasadefaultwithconfigsusinggitconfigpush.followTagstruewhichwillautomaticallypushtagswhentheirassociatedcommitsarepushed.Readmoreaboutthisconfigsetting.
Releases
ReleasesareaGitHubfeaturethatallowyoutoaddanexecutabletothetagforeasieraccessbyvisitorswhojustwanttodownloadandinstallyoursoftware.Releasesaretags,becausetheypointtoaspecificcommitandcanbenamedlikeanyothertag.However,releasescanalsoincludeattachedbinaries.
AddaReleasetoGitHub-Games
1. OnGitHub,navigatetotheCodetaboftherepository.2. Underyourrepositoryname,clickReleases.3. ClickDraftanewrelease.4. Typeanameforthetag.Werecommendyouusesemanticversioning.5. Selectabranchthatcontainstheprojectyouwanttorelease.Usually,you'llwanttoreleaseagainstyourmaster
branch,unlessyou'rereleasingbetasoftware.Youcanalsoselectarecentcommitbychoosingtherecentcommitstab.
6. Typeatitleanddescriptionthatdescribesyourrelease.7. Ifyou'rereadytopublicizeyourrelease,clickPublishrelease.Otherwise,clickSavedrafttoworkonitlater.
Noticethatyoucoulddraganddroporselectfilesmanuallyinthebinariesbox,orselect"Thisisapre-release"tonotifyusersthatit'snotreadyforproduction.
Tags&Releases
46
DiscussionGuide:TeamWorkflowsandBranchingStrategiesNowisagoodtimetodiscussworkflows-whatworksforyouandyourteam,whatmightwork,andwhatyou'vebeendoinginthepast.Herearesometopicsyouwillwanttodiscusswithyourteamasyouestablishyouridealprocess.Haveaconversationeithersynchronouslyorinissuesintheclassrepositoryaboutdifferentworkflows.
1. Whichbranchingstrategywillweuse?2. Whichbranchwillserveasour"master"ordeployedcode?3. Howwillyouprotectyourcode?4. Willweusenamingconventionsforourbranches?5. Howwillweuselabelsandassignees?6. Willweusemilestones?7. WillwehaverequiredelementsofIssuesorPullRequests(e.g.shippingchecklists)?8. Whoisexpectedtoreviewyourwork?Doyouplantoinvolveotherteams?9. Howwillweindicatesign-offonPullRequests?10. Whowillmergepullrequests?11. Howwillyouteachyourworkflowtoyourteam?Ifitalreadyexists,howisittaughttonewhires?12. Whatintegrationswillbeusedindifferentstagesofdevelopment?Willallteamsbeusingthesametools?13. IfusershavequestionsaboutGit,GitHub,ortheirworkflows,whodotheyask?Howdotheyknowwhotoask?
WorkflowDiscussion
47
InitializingaNewLocalRepository
Let'screatealocalrepositorythatwecanusetopracticethenextsetofcommands.
1. Navigatetothedirectorywhereyouwillplaceyourpracticerepo(cd..togetbacktotheparentfolder).2. Createanewdirectoryandinitializeitasagitrepository:gitinitpractice-repo3. CDintoyournewrepository:cdpractice-repo4. CreateanemptynewfilenamedREADME.md:
Bash:touchREADME.mdPowerShell:Out-FileREADME.md
5. AddandcommittheREADME.mdfile.
Sincewewillbeusingthisasourpracticerepository,weneedtogeneratesomefilesandcommits.Herearesomescriptstomakethiseasier:
Bash:
fordin{1..6};dotouch"file${d}.md";gitadd"file${d}.md";gitcommit-m"addingfile${d}";done
PowerShell:
for($d=1;$d-le6;$d++){Out-Filefile$d.md;gitaddfile$d.md;gitcommit-m"addingfile$d.md";}
Youmightseeacommandduringthissection,tree.git.Ifyou'reonamachinewheretree.gitdoesn'twork(probablyaWindowsmachine),trycmd//ctreeinstead.
CreateaLocalRepo
48
FixingCommitMistakesInthisactivity,wewillbegintoexploresomeofthewaysGitandGitHubcanhelpusshapeourprojecthistory.
RevisingYourLastCommit
gitcommit--amendallowsustomakechangestothecommitthatHEADiscurrentlypointingto.Twoofthemostcommonusesare:
Re-writingcommitmessagesAddingfilestothecommit
Let'sseethisinaction:
1. Createanewfile:Bash:touchfile7.mdPowerShell:Out-Filefile7.md
2. Whenyouareaddingfilestothepreviouscommit,theyshouldbeinthestagingarea.Moveyourfiletothestagingarea:gitaddfile7.md
3. gitcommit--amend4. Thetexteditorwillopen,allowingyoutoedityourcommitmessage.
Youcanactuallyamendanydatastoredbythelastcommitsuchascommitauthor,email,etc.
FixingCommitMistakes
49
RewritingHistorywithGitResetWhenyouwanttomakechangestocommitsfurtherbackinhistory,youwillneedtouseamorepowerfulcommand:gitreset.
UnderstandingReset
Sometimesweareworkingonabranchandwedecidethingsaren'tgoingquitelikewehadplanned.Wewanttoresetsome,orevenall,ofourfilestolooklikewhattheywereatadifferentpointinhistory.
Remember,therearethreedifferentsnapshotsofourprojectatanygiventime.Thefirstisthemostrecentcommit(alsoknownasHEAD).Thesecondisthestagingarea(alsocalledtheindex).Thethirdistheworkingdirectorycontaininganynew,deleted,ormodifiedfiles.
Thegitresetcommandhasthreemodes,andtheyallowustochangesomeorallofthesethreesnapshots.
Italsohelpstoknowwhatbranchestechnicallyare:eachisapointer,orreference,tothelatestcommitinalineofwork.Asweaddnewcommits,thecurrentlychecked-outbranch"movesforward,"sothatitalwayspointstothemostrecentcommit.
ResetModes
RewritingHistorywithGitReset
50
Thethreemodesforgitresetare:--soft,--mixed,and--hard.Fortheseexamples,assumethatwehavea"clean"workingdirectory,i.e.therearenouncommitedchanges.
--soft
gitreset--soft<SHA>movesthecurrentbranchtopointatthe<SHA>.However,theworkingdirectoryandstagingarearemainuntouched.Sincethesnapshotthatcurrentbranchpointstonowdiffersfromtheindex'ssnapshot,thiscommandeffectivelystagesalldifferencesbetweenthosesnapshots.Thisisagoodcommandtousewhenyouhavemadealargenumberofsmallcommitsandyouwouldliketoregroupthemintoasinglecommit.
--mixed
gitreset--mixed<SHA>makesthecurrentbranchandthestagingarealooklikethe<SHA>snapshot.Thisisthedefaultmode:ifyoudon'tincludeamodeflag,Gitwillassumeyouwanttodoa--mixedreset.--mixedisusefulifyouwanttokeepallofyourchangesintheworkingdirectory,butchangewhetherandhowyoucommitthosechanges.
--hard
gitreset--hard<SHA>isthemostdrasticoption.Withthis,Gitwillmakeall3snapshots,thecurrentbranch,thestagingarea,andyourworkingdirectory,lookliketheydidat<other-commit>.Thiscanbedangerous!We'veassumedsofarthatourworkingdirectoryisclean.Ifitisnot,andyouhaveuncommittedchanges,gitreset--hardwilldeleteallofthosechanges.Evenwithacleanworkingdirectory,use--hardonlyifyou'resureyouwanttocompletelyundoearlierchanges.
ResetSoft
RewritingHistorywithGitReset
51
Usingthepracticerepositorywecreatedearlier,let'stryareset--soft.
1. Viewthehistoryofourproject:gitlog--oneline--decorate2. IdentifythecurrentlocationofHEAD.3. Gobacktwocommitsinhistory:gitreset--softHEAD~24. Seethetipofourbranch(andHEAD)isnowsittingtwocommitsearlierthanitwasbefore:gitlog--oneline--
decorate
5. Thechangeswemadeinthelasttwocommitsshouldbeinthestagingarea:gitstatus6. Allthefilesstillexistlocally:ls7. Let'sremovetheextrafilewecreatedearlier:gitrm--cachedfile7.md8. Now,we'llre-committhesechangeswithouttheextrafile:gitcommit-m"re-addfile5and6"
Inthisexample,thetildetellsgitwewanttoresettotwocommitsbeforethecurrentlocationofHEAD.YoucanalsousethefirstfewcharactersofthecommitIDtopinpointthelocationwhereyouwouldliketoreset.
ResetMixed
Nextwewilltrythedefaultmodeofreset,reset--mixed:
1. Onceagain,wewillstartbyviewingthehistoryofourproject:gitlog--oneline2. Gobackonecommitinhistory:gitresetHEAD~3. Seewherethetipofthebranchispointing:gitlog--oneline--decorate4. Thechangeswemadeinthelastcommithavebeenmovedbacktotheworkingdirectory:gitstatus5. Allthefilesstillexistlocally:ls6. Movethefilestothestagingareabeforewecancommitthem:gitaddfile5.mdfile6.md7. Re-committhefiles:gitcommit-m"re-addfile5and6"
Noticethatalthoughwehaveessentiallymadetheexactsamecommit(addingfile5and6togetherwiththesameHEADandcommitmessage)westillgetanewcommitID.Thiscanhelpusseewhytheresetcommandshouldneverbeusedoncommitsthathavebeenpushedtotheremote.
ResetHard
Lastbutnotleast,let'stryahardreset.
1. Startbyviewingthehistoryofourprojectwith:gitlog--oneline2. ResettothepointintimewheretheonlyfilethatexistedwastheREADME.md:gitreset--hard<SHA>3. Seethatallofthecommitsaregone:gitlog--oneline4. Noticeyourworkingdirectoryisclean:gitstatus5. SeethattheonlyfilesinyourrepositoryaretheREADME.mdandfile7.md:ls
Warning:Remember,gitreset--hardoverwritesyourworkingdirectory,stagingarea,andhistory.Thismeansthatuncommittedchangesyouhavemadetoyourfileswillbecompletelylost.Don'tuseitunlessyoureallywanttodiscardyourchanges.Anyfilesthatareuntrackedwillremainandbeunchanged.
DoesGoneReallyMeanGone?
Theanswer:Itdepends!
$gitreflog
ThereflogisarecordofeveryplaceHEADhasbeen.Inafewminuteswewillseehowthereflogcanbehelpfulinallowingustorestorepreviouslycommittedchanges.Butfirst,weneedtobeawareofsomeofthereflog'slimitations:
RewritingHistorywithGitReset
52
Thereflogisonlylocal.Itisnotpushedtotheremoteandonlyincludesyourlocalhistory.Inotherwords,youcan'tseethereflogforsomeoneelse'scommitsandtheycan'tseeyours.Thereflogisalimitedtimeoffer.Bydefault,reachablecommitsaredisplayedinthereflogfor90days,butunreachablecommits(meaningcommitsthatarenotattachedtoabranch)areonlydisplayedfor30days.
Sometimes,you'llwanttosaveyourworkinacommitwithouthavingtothinkofacommitmessage,orbeforeyou'rereadytoorganizeyourchanges.Ifthat'sthecase,youcancreatealiasestocreate"savepoints".Seetheappendixwithaliasestolearnhow!
RewritingHistorywithGitReset
53
GettingitBack:gitcherry-pickWejustlearnedhowreflogcanhelpusfindlocalchangesthathavebeendiscarded.Sowhatif:
YouJustWantThatOneCommit
Cherrypickingallowsyoutopickupacommitfromyourreflogoranotherbranchofyourprojectandmoveittoyourcurrentbranch.Rightnow,yourfiledirectoryandlogshouldlooklikethis:
$ls
README.md
$gitlog--oneline
84nqdkqinitializingrepowithREADME
Let'scherrypickthecommitwhereweaddedfile4:
1. FindthecommitIDwhereyouaddedfile4.md:gitreflog2. Cherry-pickthatcommit:gitcherry-pick<SHA>
Nowwhenyouviewyourdirectoryandlog,youshouldsee:
$ls
file4.md
README.md
$gitlog--oneline
eanu482addingfile4
84nqdkqinitializingrepowithREADME
IsthecommitIDthesameastheoneyouusedinthecherrypickcommand?Whyorwhynot?
Remember,whenusinganycommandsthatchangehistory,it'simportanttomakethesechangesbeforepushingtoGitHub.WhenyouchangeacommitIDthathasbeenpushedtotheremote,youriskcreatingproblemsforyourcollaborators.{:.warning}
Oops,IDidn'tMeantoReset
Sometimes,yougitreset--hardalittlefurtherthanintendedandwanttorestorethatwork.Thegoodnewsis,thatgitreset--harddoesn'tjustworkbygoingbackintime,itcanalsogoforward:
1. ViewthehistoryofeverywhereHEADhaspointed:gitreflog2. Resettothepointintimewheretheoriginalfile6.mdwascreated:gitreset--hard<SHA>3. Seeyourrestoredhistory:gitlog--oneline
TakealookatthecommitIDsingitlog--onelinecomparedtogitreflog.Whatdoyounotice?
Whydidn'tthiscommandcauseamergeconflictsincewehadalreadycherry-pickedfile4.Thereasonisthatgitreset--hardisnottryingtomergethetwohistoriestogether,itissimplymovingthebranchtopointtoanewcommit.Inthiscase,thiswaswhatwewanted.Inothercases,thiscouldcauseustoloseanyworkwemayhavedoneaftertheoriginalreset.
Seehowtoavoidtragedywithaconvenientaliasintheappendix.
CherryPicking
54
CherryPicking
55
MergeStrategies:RebaseInthissection,wewilldiscussanotherpopularmergestrategy,rebasing.
UnderstandingGitMergeStrategies
Gitusesthreeprimarymergestrategies:
FastForward
Afastforwardmergeassumesthatnochangeshavebeenmadeonthebasebranchsincethefeaturebranchwascreated.Thismeansthatthebranchpointerforbasecansimplybe"fastforwarded"topointtothesamecommitasthefeaturebranch.
Recursive
Arecursivemergemeansthatchangeshavebeenmadeonboththebasebranchandthefeaturebranchandgitneedstorecursivelycombinethem.Witharecursivemerge,anew"mergecommit"ismadetomarkthepointintimewhenthetwobranchescametogether.Thismergecommitisspecialbecauseithasmorethanoneparent.
Octopus
Amergeof3ormorebranchesisanoctopusmerge.Thiswillalsocreateamergecommitwithmultipleparents.
AboutGitRebase
gitrebaseenablesyoutomodifyyourcommithistoryinavarietyofways.Forexample,youcanuseittoreordercommits,editthem,squashmultiplecommitsintoone,andmuchmore.
Toenableallofthis,rebasecomesinseveralforms.Fortoday'sclass,we'llbeusinginteractiverebase:gitrebase--interactive,orgitrebase-iforshort.
Typically,youwouldusegitrebase-ito:
ReplayonebranchontopofanotherbranchEditpreviouscommitmessagesCombinemultiplecommitsintooneDeleteorrevertcommitsthatarenolongernecessary
CreatingaLinearHistory
Oneofthemostcommonusesofrebaseistoeliminaterecursivemergesandcreateamorelinearhistory.Inthisactivity,wewilllearnhowitisdone.
MergeStrategies
56
SetUp
1. FindtheSHAoftheinitialcommit:gitlog--oneline2. ResettotheSHAoftheinitialcommit:gitreset--hardSHA3. Createanewbranchandcheckouttoit:gitcheckout-brebase-me4. Cherry-pickfiles4-6ontotherebase-mebranchusingthereflog.5. Checkouttomaster:gitcheckoutmaster6. Cherry-pickfiles1-3ontothemasterbranchusingthereflog.7. Lookatyourhistory:gitlog--oneline--graph--decorate--all8. Ifyoumergednow,itwouldbearecursivemerge.
BegintheRebase
1. Checkouttotherebase-mebranch:gitcheckoutrebase-me2. Startthemerge:gitrebase-imaster3. Yourtexteditorwillopen,allowingyoutoseethecommitstoberebased.4. Saveandclosetherebase-todo.5. Watchyourrebasehappenonthecommandline.6. Takeanotherlookatyourhistory:gitlog--oneline--graph--decorate--all7. Ifyoumergednow,itwouldbeafast-forwardmerge.
FinishtheMerge
1. Checkouttomaster,thebranchyouwillmergeinto:gitcheckoutmaster2. Mergeyourchangesintomaster:gitmergerebase-me
Ifyou'dlikesomehelpkeepingeverythingcleanwithanalias,don'tforgettochecktheappendix!
MergeStrategies
57