Git

What is Version Control

A version control system (VCS for short) is a method to store source code and other iterative design materials (webpages, etc) for both collaboration and security. what sets a version control system apart from other systems (backups) is that:

  1. A VCS will keep all file history in easily browsed formats
  2. Collaboration is designed in from the beginning
  3. These systems are made to merge multiple versions of a file together

This adds up to a system that permits operations on a file-based structure

  1. Diffs (seeing the difference between two versions of a file)
  2. History (seeing who changed what when)
  3. Atomic changes to specific files (reverting, changing)

Enter Git

Git is the made for purpose replacement of BitKeeper as source control for the Linux kernel. It was developed from the ground up to support the wide development from thousands of developers simultaneously.

Some quick technicals:

  1. Revisions are stored in the .git folder in the root of the repository
  1. This means that everyone has a full copy of the repo
  1. Git is a distributed VCS (anyone can merge with anyone)
  1. Each person can simultaneously act as a server and a client
  2. Servers are just git repos that everyone syncs with
  1. File syncing is not done over a special protocol
  1. HTTP: Slow, and anyone in the middle can see everything
  2. HTTPS: Slow, but encrypted transfers
  3. SSH: Fast and encrypted. But you must set up SSH keys

VCS Theory - Branching

In the old days, most version controls used a single branch. This is equivalent to using one folder for all code done by every user. This does have drawbacks though which branching hopes to fix. To illustrate this, we will use the example of the development of a video game. A video game could be said to usually have the following components and more:

Core engine

Graphics

Networking

Taking the world of a single branch, each of these teams would make development changes directly to the codebase immediately. This many issues for a large scale project though such as:

  1. How do you freeze the code for a release, but continue dev for the next?
  2. What happens if a dev from the network team breaks the whole environment with a commit? How do the other teams do their part if they can not even build the solution?
  3. Who moderates all of the file changes and how do they know what their team changed?

The answer is branching. Each team member has their own branch, along with each team having their own as well. This solution is surprisingly elegant; assume the following scenario. We have a dev called Bob that is part of the Graphics team. Bob would have the following for his branches:

  1. Bob-dev: A dirty branch that can have errors on it, all development code.
  2. Graphics-dev: A semi-dirty branch that should always be operable. New changes or features are integrated here once they are completed.
  3. Main-dev: A clean branch that will always be operable. This is where each group pushes features once completed.
  4. Main: The release branch. Only stable, tested code makes it here.

A normal day’s workflow

Take our friend Bob again. In the beginning of a dev day, Bob would first pull all changes from others in their group. To do this, they would execute the following commands:

git pull - Grabs all new changesets from the main repo

git merge Graphics-dev - Merges all changes from the group repo with the local repo

At this point they would go through all the dev processes, changing files and such. Then they need to commit the local changes to the repo:

git commit -a -m “commit message”

‘-a’ automatically commits all changed files

‘-m’ sets the message for when it’s committed to the repo

If any new files are added, then this needs to be run instead:

git add -A

Finally, after all the changes are made, Bob must merge this back into the group repo:

git checkout Graphics-dev - Moves the current repo ‘pointer’ to the Graphics-dev branch

git merge Bob-dev - Merges the changes in Bob-dev into Graphics-dev