Version Control
Programming Environment
COP-3402
Table of Contents
Version control
Records changes to code (or any file)
Why use version control?
- Large, complicated code base
- Many developers working together
- Tracking causes of bugs
- Rewind history to prior versions
- Log who made code changes
Bank account balance
TOTAL | $31 |
Says nothing about how you got there. Why do I only have $31?
- Did I spend too much this week?
- Did I not get paid?
Bank account transactions
Description | Amount |
---|---|
Income | $42 |
Gas | -$15 |
Food | -$6 |
Reimbursement | $10 |
TOTAL | $31 |
Transactions are (generally) append-only. You only add transactions.
You can always reconstruct the total from your transactions.
Version Control Systems
- Record each version to a log
- Document developer descriptions of change
diff
diff old_file.c new_file.c > change.patch
Displays only
- lines added
- lines removed
A diff is like a bank transaction. It only contains what has changed in the new files (lines added or removed).
Examples:
- diff oldhello.c newhello.c
- git diff …
patch
cp old_file.c file.c cat file.c patch file.c change.patch cat file.c
patch
is a companion tool that takes diff files and applies them to the oldfile to get the new file.
patch -R file.c change.patch
Version history
Sequence of diffs
Diagram
Conceptually, can think of version history as a sequence of diffs, with metadata, like a description, author, date, etc. Additionally, the diff points to the previous version.
Just like a bank balance equals a sequence of transactions, the sequence of diffs applied in order equals the current version.
git
- Manages sequence of versions
- Repository (repo): database of version history
Additional features
- Distributed
- Syncing with other people's repos
- Create "branches" of histories
- Merge multiple divergent (branched) histories
Distributed version control
https://git-scm.com/book/en/v2/Getting-Started-About-Version-Control
Full repository copies on each machine
Branching
https://git-scm.com/book/en/v2/Getting-Started-About-Version-Control
Red boxes are branches, which are effectively just (named) pointers to a commit.
Commits container a pointer to (the hash of) the previous committed version, so the entire history of the branch can be accessed.
Branches share a history with other branches, but split the history after some point.
Merging
https://git-scm.com/book/en/v2/Getting-Started-About-Version-Control
You can merge branches to combine their histories.
This creates a special commit that points to both histories.
Any conflicts in the branches need to be resolved by the developers, though git will attempt to automatically merge when the commits touch different parts of the source.
Note there are other ways to combine histories (fast-forwarding and rebasing). See the Pro Git book for more info.
Configuring git
After logging into eustis:
git config --global user.name "John Doe" git config --global user.email johndoe@example.com git config --global core.editor emacs
Set your name, email, and editor
https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup
git
Basics
Create a example repo
git clone gitolite3@eustis3.eecs.ucf.edu:cop3402/NID/examplerepo
Check the state of the repo
git status
Will report the repo has no commits yet.
Adding (staging) new files
echo "examplerepo" > README git add README
View the state of the repo
git status
README is marked as to be committed
Create a new commit (version)
git commit
will add a new version to the repository.
The commit requires entering a message describing the commit.
git commit README
Your editor will pop-up.
Commit messages
Write a simple summary line, e.g., "Add a README", then save and quit.
git status
Status shows nothing more to commit
In practice, you should describe the what and why of the change to keep a useful record of changes for other developers (and yourself when you inevitably forget!)
See Google's guide to this: https://google.github.io/eng-practices/review/developer/
Viewing the log of changes
git log
This will show the metadata associated with the committed version.
Each commit is assigned a commit ID (a hash).
View the contents of a commit
One way is to use the commit ID (which you can see in the log)
git show cea1e0a8 # your commit ID will be different
Or use HEAD
to refer to the latest commit
git show HEAD
Only need the unique prefix of the hash, not the whole thing.
git show
with no arguments defaults to showing the HEAD
git
States
git allows very fine-grained control over your repository and managing remote repositories.
There are lots of commands that, to a new user, may seem similar.
I'll explain the git design from the user point of view.
Then show you how common commands work with repositories.
I don't expect you to completely get every aspect of git.
I'll give you a basic workflow that you can use for projects, which will have a very simple version control architecture.
Sections of a git
project
Section | Description | State of a Change |
---|---|---|
Working directory | A copy of one version | Modified |
Staging area | Collects changes | Staged |
Repository | Stores all versions | Committed |
- This is where you edit source files
- This the
.git
subdirectory in your working directory
Sections of a git
project
https://git-scm.com/book/en/v2/Getting-Started-What-is-Git%3F
- Committed means the changes are logged in the repository
- Staged means specific changes have been marked for commit
- Modified means the files in your working directory (where you edit your files) differ compared to the last version in the repository
Changing state
Operation | Description | Where |
---|---|---|
git add | Stage a file | Staging area |
git rm | Remove a file | Staging area |
emacs/vim | Modify a file | Working directory |
git commit | Commit a change | Repository |
How operations change state
Commiting new changes
Make edits
emacs README
Compare versions
Compare the working directory to most recent committed version:
git diff
Compare the last two committed versions:
git diff HEAD~..HEAD
- HEAD points to the last committed version (in your current branch).
- HEAD~ points to the second to last committed version.
- HEAD~~ points to the third to last committed version.
Syncing your changes
- Your hello project has two repositories
- Your local repo on eustis
- The remote repo on gitolite3@eustis3
- Project submission is just syncing these two
Diagram
Remote branches
https://git-scm.com/book/en/v2/Getting-Started-About-Version-Control
Branches are named pointers to a commit. Cloning (and pushing and pulling) synchronize the history of commits.
When there is no difference, the branches point to the same commit.
Diverging repositories
https://git-scm.com/book/en/v2/Getting-Started-About-Version-Control
Adding commits to your local repo causes the remote and local repos to diverge.
Commits added to the remote repo cause your view of where the remote repo is pointing to change, and there may be new commits you haven't yet received.
Updating the remote repo
git push
Defaults to where the branch was originally pulled from or the dev will set the name of the corresponding remote branch.
Updating your local repo
git pull
git pull runs two steps, git fetch (to receive updates) and git merge (to incorporate those changes into your local copy of the branch).
For this class
- We won't do any sophisticated distribution
- Only two repos (your local, and gitolite3 remote)
- No one else will modify the remote, we pull from it for grading
- Stick to modifying only your one local repo on eustis
- No merge conflicts possible in this scenario
Basic project workflow
Once your repo is created and you've already added files, here is a common, simple workflow that will make sure your remote repo is up-to-date.
# starting with an unmodified working tree git status # shows no modifications or stagings emacs file.c # edit make # build # test your project git diff # check your modifications git commit file.c # add a commit message # better yet, use magit, fugitive, git commit -p, or git add -i git status # double-check you've comitted everything git push # sync your local changes with the gitolite3 server # repeat as needed!