Main sponsor Git Luca Milanesio Android programming Sang Shin The Productive Programmer Neal Ford The Power of Retrospection Linda Rising Introduction to Scala Hubert Plociniczak
Agenda • SCM and Git Concepts • Git quick start • Branching and merging • Resolving conflicts • Reverting changes • Working with tags • Git remotes • Git on the server • Git peer-to-peer • Git democracy
Who’s that guy ? Luca MilanesioLMIT Limited – Director / co-founder of GitEnterprise.com • Jenkins (formerly Hudson) contributor since 2007founder of hudson-mobi.com • Over 18 years of experience in Software and Services Development and Application Lifecycle • Worked for major UK, EU and US Customers • Banking, Retailers, Industry, Finance, Telecoms, Utilities, Government • Git enthusiast since 2009 and innovator in Vodafone Group Services Ltd
About SCM … remember ? • SCM = Source Code Management • Multiple revisions of files • Commit and rollback changes • Define change-sets • Tag important releases • Manage branches of development • Integrate the work of multiple teams together • … and much more Picture courtesyofglobalnerdy.com - Allrightskindlyreserved
Brief history of OpenSourceSCMs Local SCMs (versions kept on local filesystem) • SCCS (1972) … I was not yet born, don’t remember • RCS (1982) the most widely used on Unix Server-based SCMs (central repository server) • CVS (1990) first widely used SCM server • Subversion (2000) first widely Internet SCM … and then let’s to go distributed … • DCVS (2002) who has ever used it ? • Mercurial and Git (2005)
Centralised vs. distributed ? How many of you are using central repositories ? • CVS-boys … raise your hands ! • SVN-guys … it’s your turn ! How many are for distributed repositories ? • Mercurial-scientists ... raise your hands ! • Git-explorers … brave men !
Who’s right ? Central SCM • Unique “source of truth” • Central back-up • Seamless alignment for all developers • Security and access control Distributed SCM • Community code-base • No single-point-of-failure • Peer-to-peer alignment • Continuous branching and merging
Why GIT ? It’s all about BitKeeper fault: they broke up with LinusTorvalds … and I’m not kidding Story: • Linux Kernel SCM: BitKeeper • Apr 2005 – Linus writes PERL scripts for Linux Kernel SCM • Jul 2005 … Git 0.99 is out ! Git principles: • Allow the BitKeeper SCM workflow • Use CVS as the “not-to-do” example • Check and prevent corruption • Make it FFF … FAST FAST FAST !
Git installation (Ver. >=1.6) • Linux (Gitfavourite of course !) • Ubuntu: sudo apt-get install git-core • other Linux ? … best from source codehttp://git-scm.com/ • Mac OSX • http://code.google.com/p/git-osx-installer/ • Windows • http://code.google.com/p/msysgit/(sucks … but it’s your fault not using Unix) • CygwinHIGHLY RECOMMENDED (mandatory IMHO)
Step 1 – Git repository • create project • cd into project • $ git init
Step 2 – Git identity • Define your full name • Define your e-mail • Everything stored in .git/config
Step 3 – Add some files and commit • Create some files • Add to GIT (default = recursive) • Commit
Step 4 – Inspect GIT log • Get GIT history of commits • Display changes
Too simple ? … let’s add some states • Three states of Git files 1. Unstaged 2. Staged 3. Clean git add git commit Picture courtesyofProGit.org
State 1. unstaged • Create a new file • Change an existing file • Check status
State 2. staged • Add the two files to staging area • Check status
State 3. work directory clean • Commit the staging area • Check status
Display Git lifecycle • Add another file and make some changes • $ gitgui
Stage with gitgui • Select files and chose “Stage to commit”
Commit with gitgui • Enter commit message and click “commit”
Git stores the whole file • Git is different from SVN: no diffs, just whole files • Git stores changed files between snapshots(BitKeeperdocet) Picture courtesyofProGit.org
Git object types: blobs • Git stores all files (and their versions) as objects (blobs) • Each object has a SHA-1 160-bit identifier • SHA-1 provides: • Unique Global ID • Integrity check • Example: • File content: “You're GIT too” • SHA-1: bbecf72783dfba9e0243e13dbb5fb04ed39ed4e4 (Hex) • Track content (not files) • Automatically detect renames … cool !
SHA-1 ? WTF … • Why LinusTorvalds has chosen SHA-1 hashing ? • Need for track content globally • SHA-1 collision probability is 1/251 • What happens if two files have same SHA-1 ? • BOOM ! • What is the probability of it ? • World’s population (7 BN people)sharing files of 10 times Linux Kernel • Possible ? More likely to be hit by a 15 KM asteroid NOW !!!
Git object types: commits and trees • Git tree identifies a snapshot (set of files) • Git commit identifies • Author / Committer • Commit message • Timestamp • Tree Picture courtesyofProGit.org
Git history: graph of commits • Every commit points to its predecessor • Series of commits make Git repository history Picture courtesyofProGit.org
Where are Git objects ? • Git objects are in .git/objects • SHA-1 identify directory / file
Curious about Git objects ? • Git objects are compressed • Use git show to display content
Getting lost ? • How to remember SHA-1 hashing codes ? • How Git stores the “pointers” to Commit graph ? • Git references are the solution ! • Head of the Git history • Intermediate tags • Branch points • Relative points
Git references • References: “labels” for Git SHA-1 commit IDs • Stored as files under .git/refs • Reference types: • Tags • Heads (branches) • HEAD is a special ref:always points tohead of currentbranch.
How Git commits graph looks like ? Reference Commit Tree Picture courtesyofProGit.org
What is a branch for Git ? • Git named branch = reference to a commit ID (head of branch) • Git supports “network” of commits, with named and unnamed branches … don’t know why Git reminds me some “underground” branches
Real-life Git branches Think I’m exaggerating ? Look at this example (it’s real, swear !)
Let’s practice on Git branches !
Wear “life jacket” first • Get Git bash extensions source git/contrib/completion/git-completion.bash • Redefine promptexport PS1='\W$(__git_ps1 " (%s)") \$ ’ ... and your current branch is visible on your prompt: you will not get lost
Creating branches • Create branch create a new ref to current commit
Switching branch • Use git checkout to switch branch • Current displayed branch changed to experimental • Note that HEAD points to experimental
Commit on branch • Add a new commit to experimental branch • See the new branch graph (gitk)
Merge • When experiments are completed … merge back ! • Checkout master • Merge experimental
Git graph after merge Let’s have a look on the result with gitk • Merge-type applied: Fast-forward (move refs in history) • Branch has been “flattened” • Experimental just another ref to master
Git recursive-merge • Let’s create some divergence • Changes on both master and experimental • Fast-forward merge = move branch ref to another commit ID
Git diverging branches • Use gitk --all to display all branchesNOTE: no args displays just current branch • experimental is really diverging from master
Git recursive merge • Let’s merge again with master • This is a real merge folks ! NOTE: Merge is a Git commit: you can associate a comment, or revert it later ! Don’t be scared by Git-managed merge
Merge alternatives: rebase Picture courtesyofProGit.org
Git rebase in action Let’s diverge again between master and experimental Magic ! … rebase flattens the branching history
Git graph after rebase Experimental is no more a diverging branch NOTE: Marconi’s test is on “unnamed branch” and experimental branch history has changed !
Merge alternatives: squash origin C6 C1 C2 C3 C4 C5 C1 C3 C4 C3 C4 C3’+C4’ C2 mywork origin mywork