“Any organization that designs a system will produce a design whose structure is a copy of
the organization's communication structure.” — Melvin Conway, 1967
A Human Version Control System!
That just walked out the door...
Tracking history
Who changed the code and when?
Resolving conflicts
What if 2 people edit the same file?
Change visibility
Who's code is "live" and when?
This is tricky, frustrating, and expensive work for a human!!
Tracking History
Make a sequence of changes to a program
Discover it is broken
Figure out which change broke it
How do we go back to a previous version?
Simple History Solution
Regularily make a copy (backup) of all the files
Restore the backups 1 by 1 until the problem is gone
Problems with this soution
How often do you backup? Every 5 minutes? (Lots of storage!)
How long will it take you to find the problem (Hundreds of backups a day!)
Will you be diligent, or will you get bored/forget? (Defeats the purpose!)
Resolving Conflicts
Tilly edits and saves file1.cpp
Cowboy edits and saves file1.cpp
Tilly's changes are lost!
Simple Resolve Conflict Solution
Email the team when you're editing
Subject: I'm editing file1.cpp! ← When you start
Subject: I'm done with file1.cpp! ← When you're done
Problems with this solution
Someone doesn't read the email
2 people send a file1.cpp email at the same time
The team is 150 engineers Your inbox is now just "I'm editing" emails!
We need a Version Control System
Tracks Revision History
Can rewind the codebase to an earlier point in time and show who changed what
Resolves Conflicts
Can identify and handle multiple users editing the same file
Controls Change Visibility
Allows users to control when their changes become visible to others
In this course we use git!
Global Repository, Local Copies
The key idea
Code is stored in a remote repository
Users use git commands to
make a local working copy when they want to make changes
send or receive changes to the remote repository when they're ready
Revision History
Revision History : git log
Listing changes
Revision History : git show/diff
Examining Changes
Revision History: git revert
Undoing Changes
Revision History : Takeaways
Doesn't this take up lots of storage?
No! git only stores changes
Even with a million line codebase each change is (usually) small
How often should I commit?
Often! Commits are cheap!
Suggestion:
Commit every time you make a working change towards your goal
Warning:
Always compile and run before every commit!
Treat each commit like a "save point" you can return to
Resolving Conflicts
There are two basic approaches
Lock-Based
Like our email idea, but enforced by a program
You lock a file before editing, preventing others from editing
Used by some legacy systems (rcs, vcs)
Merge-Based
Users have working copies of the same file
Conflicts are resolved when users choose to
see other users changes
git pull
make their changes visible to others
git push
Resolving Conflicts
Different Files
Resolving Conflicts
Different Files
Resolving Conflicts
Same File, Different Lines
Resolving Conflicts
Same File, Same Lines
Resolving Conflicts
Same File, Same Lines - Editing the conflicted file
Resolved version
Resolving Conflicts
Same File, Same Lines - Marking the conflict resolved
Change Visibility
Remote Repos, Local Repos, and Working Copies
git clone makes local copy of remote repo and an editable working copy
git commit creates new revision in local repo from working copy edits
git pull gets revisions from remote repo applies changes to local copy
git push sends local revisions to remote repo
The Development Loop
git pull -r to ensure your repo is up to date
Fix a bug, add a feature, improve tests
Build
Test
git commit
git pull -r to ensure your repo is up to date
Resolve conflicts (if any)
git push to publish your changes
Branching
A Motivating Example for an Optional Advanced Version Control Feature
Tilly is just wrapping up Milestone 1
Mostly working, just adding polish and fixing minor bugs
Cowboy wants to get a head start on Milestone 2
Milestone 1 submission is soon!
Code needs to stay stable, working, with all tests passing
Half finished Milestone 2 features could mess up live demo
Solution?
Make a branch!
Branching
What is a ref?
A human readable, named pointer to a revision, instead of a hash like 3ad5e6f
What is a branch?
A ref that always points to the latest revision (the tip)
Updated by git commit
What is the default branch?
Most important branch, usually master or main
What you get when you git clone
HEAD
A special ref that points to the current branch
Branching
Creating the branch
Both Tilly and Cowboy start on master
Tilly runs git checkout -b milestone1
A new branch ref is created
Tilly's HEAD changes
Cowboy stays on master, working on the future
Branching
Working independently
Cowboy's commits go to master
Tilly's commits go to milestone1
They work independently
Branching
Merging in changes
Tilly's polish and bugfixes should end up in master
git checkout master - switch local branch
git pull -r - bring master up to date with Cowboy's work
git merge milestone1 - creates new commit joining both histories, with changes from both
Branching
Rebase vs merge
merge joins two histories
We can avoid branches in the history by rebasing
Replays commits one at a time, like git pull -r
Keeps the history linear and easier to understand
Can make conflict resolution very painful
Branches
Use Cases
Master/Main/Trunk
The latest tested and working version of your code
Only completed working features allowed
Feature Branches
For adding a specific new feature
Develop, test, commit, repeat...
git pull -r origin master often to avoid merge conflicts
Merge to Master when done
Release Branches
Matches a specific version (eg. on the app store)
Before release: for stabilization and testing (no new features!)
After release: for emergency bugfixes to the live app
Summary
Version Control Systems solve three problems: history, conflicts, visibility
History: Every commit is a save point
git commit to save
git log/show/diff to inspect
git revert to undo
Visibility and Conflicts: Integrating changes
git pull -r to get other's changes
git push to publish your own changes
git add, git rebase --continue to resolve conflicts
Branches: Working independently
git checkout -b branchname to start
git checkout master, git merge branchname to finish
The loop: pull → change → build → test → commit → pull → push