Distributed Source Code Management with git

An introduction to distributed source code management with git.
created by on 2013-02-15

git Logo

Source Code Management / Version Control

What do you want from source code management systems?

An overview of git

What is git?

A distributed version control (DVC) and source code management (SCM) system

The git command-line

Git is a powerful command-line tool you can use on Linux, Mac OS and Windows:

$ git

Screenshot of the git command line

History of git

Developed by Linus Torvalds for the Linux kernel development in 2005 as an replacement for BitKeeper.

There is a good Google Tech Talk with Linus Torvalds where he talks about the history and motivation behind git:

git today

Screenshot of the Git Contributors Page at github.com

Why the name “git”?

git := British slang meaning “a rotten person”

I’m an egotistical bastard, and I name all my projects after myself. First Linux, now git.”
- Linus Torvals

Key features of git

Distributed Version Control

Being distributed very much means that you do not have one central
location that keeps track of your data. No single place is more
important than any other single place.
- Linus Torvals

Distributed development workflows

git supports all kinds of developement workflows and branching strategries (because of its distributed nature):

Subversion-Style workflow

One central repository where one or more developers pull from and commit to:

Illustration of the Subversion-Style workflow

Integration Manager Workflow

One single person (the “integration manager”) pulls changes from different sources/developers, combines them in his or her repository and pushes the combined commits to a central “blessed” repository:

Illustration of the Integration Manager Workflow

Dictator and Lieutenants Workflow

In this network of trust a “dictator” pulls from the repositories of her or her trusted “lieutenants” which on their side pull from their trusted developers. The dictator integrates the changes from the lieutenants and then pushes to a central blessed repository.

Illustration of the Dictator and Lieutenants Workflow

source: http://git-scm.com/about/distributed

How does git cover the things you expect from a SCM?

Experimenting without loosing changes




No overhead

What distinguishes git from centralized SCMs …

… such as Team Foundation Server or SVN (Apache Subversion):

Why do I think we could benefit from using git ?

With our centralized version control system branching and merging is so painful for us that we hardly do it.

A healthy branching strategy would look something like this:
Illustration of a health branching strategy which utilizes multiple branches

But opposed to that, this is how our unhealthy branching “strategy” looks like … because branching and merging is (considered) hard:
Illustration of an ubhealth development strategy which does not use branching

Other distributed version control systems

There are other distributed SCMs out there, but not that many …







Setting up git on Windows

Installation on Windows

Installation Wizard

For the installation of git goto http://git-scm.com and download the latest version for Windows and execute the installer.

Screenshot of the git installation wizard start screen

Installation Wizard - Components

In the “Select Components” dialog I suggest that you uncheck

Screenshot of the git installation wizard - Adjusting your PATH environment

Installation Wizard - PATH Variable

The installation wizard asks you how it should integrate with your system. Please check “Run Git from the Windows Command Prompt”. This will make the “git.exe” avaiable from everywhere in your system.

Screenshot of the git installation wizard - Select Components

Installation Wizard - Line Ending Conversion

Because git comes from a Unix background, git uses Unix-style instead of Windows-style line-endings.
You should select the “Checkout Windows-style, commit Unix-style line endings” option.

Windows-style line ending

Windows uses a carriage return charachter and a line feed character for its line endings:


Unix-style line ending

Unix just uses a single line feed charachter for indicating new lines:


Screenshot of the git installation wizard - Line Ending Conversion

Scott Hanselman - You’re just another carriage return line feed in the wall

Installation - bin folder

The git intaller installs a bunch of Windows-compatible Linux commands.

Screenshot of the git installation - Bin Folder

Installation - cmd folder

The cmd-folder contains the git.exe and a script which sets the PATH to the bin folder and then launches a new command prompt.

Screenshot of the git installation - Bin Folder

Testing the installation

When the installation was successful when you can execute “git.exe” from all locations on your system:

Screenshot of the git installation - Command Prompt


Configuration: Username and Email

Global Config File (.gitconfig)

The global git configuration is located in a file called .gitconfig in your home directory

> %UserProfile%\.gitconfig

Set Username and Email

In order to set your Username and Email adress for future commits you can either edit the “%UserProfile%.gitconfig” file in an editor of your choice or use git config command with the --global flag:

> git config --global user.name "Your Name"
> git config --global user.email "[email protected]"

Screenshot set username and email - Set Username and Email with git

Configuration: Merge and Diff Tool

By default git does not ship with much GUI tools and everything is handled in the command-line:

Screenshot of the gits command-line based diff viewer

But you can configure git to use other diff and merge tools (but this isn’t that easy on Windows if you don’t use tools which are supported out of the box).

Configuring KDiff3 on Windows

I couldn’t get my perferred merging tool WinMerge to work with git on Windows, but KDiff3 is also quite nice and can be easily configured to work with git.

Step 1 - Download and install KDiff3


Step 2 - Extend your .gitconfig

    tool = kdiff3

    prompt = false

[mergetool "kdiff3"]
    prompt = false
    path = c:/Program Files (x86)/KDiff3/kdiff3.exe

    tool = kdiff3
    guitool = kdiff3

    prompt = false

[difftool "kdiff3"]
    path = c:/Program Files (x86)/KDiff3/kdiff3.exe

Screenshot of the KDiff3 as the diff and merge tool for git

It is supposed to be easy to integrate any other merge tool with git. And it is - at least on Unix based systems. But on Windows I haven’t found a way yet.

Working with git

Typical workflows with git

Using the built-in help

Git comes with a comprehensive help documentation which ships with every installation.

Display an help overview

> git help

Get a detailed list of all git commands

> git help -a

Help about a specific git command

> git help <command>

Screenshot of the git help command result

Creating a repository - git init

You can initialize a repository in any directory by using the init command:

> git init

The init command then creates a hidden subdirectory named “.git” that contains all necessary repository meta-data.

The .git metadata folder

The .git folder is where all you commits, branches and tags will be stored, but for now you don’t need to bother with the contents of this folder:

Screenshot of the content of a .git metadata folder

Checking the status of your repository with git status

You can quickly check which the status of files in your repository/index by using the status command:

> git status

Using git status to check the index of a repository

Adding files to the index

Once you have initialized a repository you can create, modify files and add the new files to the index / staging area.

Add one or more files to the index

> git add <filename1> <filename2>

> git add .
Add all files (in the current directory) to the index

Index / Staging Area

The index aka “staging area” is a file that contains the files that will go into your next commit.

Screenshot of a git repository where a new README.txt file has been added to the Index aka Staging Area

Removing files from the index

You can remove files from the staging area if you have added it accidentally. This means will will not go in your next commit, but the file itself will remain untouched in the folder.

> git rm --cached <filename>

Screenshot removing a file from the staging area

Commiting changes

By commiting you can save all staged files to your (local) repository.

> git commit -m "A first commit"

Screenshot of a first commit

Once you have executed the commit, all changes are recorded to your repository.

Viewing the commit history

Every commit to a repository is recording and the global history of a repository can be viewed with the “log” command.

> git log

Screenshot of results of git log

If you only want to see latest n-commits you can use the -n flag for the log command:

Show only the latest 3 commits
<!– language: lang-sh –>

> git log -n 3

Results of git log -n 3 as a screenshot

Or you can use gitk to a view a graphical representation of your commit history:

Using gitk to view the local commit history

Undoing your last local commit

If you have accidentally committed a change you can undo your change by using the “reset” command:

On Windows:
<!– language: lang-sh –>

> git reset --soft HEAD~1

On Linux:
<!– language: lang-sh –>

> git reset --soft HEAD^

Note: this does not work for your first commit 😉

more details

Correcting a commit message

If you want to change the message of your last commit you can simply type:

> git commit --amend

This command opens up a text editor in which you can simple change the text of your last commit message. Or you can use the -m parameter to enter the message directly:

> git commit --amend -m "Your new commit message text"

Note: Changing the commit message will change the hash of your commit. Therefor you should use this technique carefully if you already pushed your repository to a remote location that is used by other developers.

more details

Reverting a public commit

If you want to take back a commit which has already been pushed to another location can cannot simply “undo” it, because public history cannot be changed. But you can add a commit which reverts another commit.

> git revert <hash of the commit to revert>

git revert applies the inverse of a given commit.

Screenshot of the text editor window that is displayed when a revert is being performed

Result of git revert

Comparing commits

In order to visualize the changes between two commits you can use the diff command:

> git diff <commit-A> <commit-B>

The command will display the differences between the two commits directly in the command line:

Screenshot of git diff in action

If you prefer a nice visualization of the differences between two commits you can use the difftool command instead. The command will open the diff tool you have configured in your .gitconfig.

Screenshot of git diff in action

Git ignore files

If you want to make sure certain files are never added to your index and therefor never commited you can list these files in a file called “.gitignore”.

Example: Ignoring .html files


Screenshot of an git ignore file

An ignore file for .NET projects

The content of an ingore file for .NET projects typically looks something like this:


All files which match the patterns specified here will not be added to the index when using “git add .”

more details

Show a list of local branches

The default branch in git is called “master”. To display a list of all branches in your current repository use the “branch” command:

> git branch

Show local branches

The branch that is marked with an asterisk (*) is the branch you are currently on.

Show al list of all branches

To display a complete list of all local and remote branches you can use the -a flag.

> git branch -a

Show all branches

Creating a branch

To create a new branch use the “branch” command with the name of your new branch:

> git branch <branch-name>

Create a new branch

Switching between branches

To switch your current repository context to another branch you can use the “checkout” command:

> git checkout <branch-name>

Switching a branch

Merging branches without no conflicts

To merge a branch into another use the “merge” command:

> git merge <branch-name>

Switching a branch

If the merge can be performed without conflicts you will see the commits from the merged branch in your current branch.

Merging branches with conflicts

If git cannot decide on how to merge changes you will get a merge conflict which needs to be resolved and committed:

> git merge <branch-name>
CONFLICT (content): Merge conflict in ...
Automatic merge failed; fix conflicts and then commit the result

Screenshot of a merge with results in a conflict

You can resolve the conflict with the “mergetool” command:

> git mergetool

Screenshot of the mergetool resolving a conflict

After you have resolved the conflict, you need to stage the changes and commit them:

> git add <file-with-conflict>
> git commit -m "Merged with branch xy"

Results of a branch merge with conflicts after the conflict has been resovled

Deleting a local branch

Local branches can be easily deleted:

> git branch -d <name-of-the-branch>

Deleting a local branch with git branch -d branchname

Deleting a remote branch

In order to delete a branch which has been pushed to a remote location you need to use a different command:

> git push origin --delete <branchName>


> git push origin :<branchName>

Deleting a remote branch with git push origin --delete branchname

more details

Cloning a repository

In order to retrieve a copy of an existing repository you can use the clone command:

> git clone <Path-or-URL>

This will clone the repository behind the specified URL or path into a new directory in the current location.

For example you can clone the repository of this presentation from github:

> git clone https://github.com/andreaskoch/Introduction-to-Distributed-Source-Code-Management-with-git.git

Cloning a repository from github

Pulling from another repository

Instead of cloning another repository you can also pull from it into your existing repository.

> mkdir NewRepo
> cd NewRepo
> git init
> git pull <Path-or-URL>

Pulling changes into an existing repository

Pushing changes to a remote repository

If you want to publish your changes to a remote repository you can use the push command:

> git push <name of the remote> <branchname>

Remote := A remote is a version of a project that is located at another location.

Display a list of all remotes

> git remote -v

List all remotes of a repository

Adding a remote

> git remote add <name of the remote> <Path-or-URL-of-the-Repository>

Adding a remote repository

Pulling changes from a remote location

> git pull <name of the remote> <branchname>

Fetching changes from a remote location

git pull will downlaod all changes from the remote respository and merge them with your current branch. If you only want to download the changes without merging them you can use fetch instead of pull:

> git fetch <name of the remote> <branchname>

Cleaning up a repository

If you want to delete all files from your current repository which are not part of your repository and have not been added to the index / stating area you can use the clean command:

> git clean -df

Screenshot of git clean in action

Changing the author info of one or more commits

Sometimes you commit changes with the wrong username or email address configured.

If you want to correct this mistake you can use the “filter-branch” command in a “small” shell script to replace the author info of all commits with the wrong email address with a new email address:


git filter-branch --env-filter '


if [ "$GIT_COMMITTER_EMAIL" = "[email protected]" ]
    cn="Andreas Koch"
    cm="[email protected]"
if [ "$GIT_AUTHOR_EMAIL" = "[email protected]" ]
    an="Andreas Koch"
    am="[email protected]"

export GIT_AUTHOR_NAME="$an"
export GIT_AUTHOR_EMAIL="$am"

Warning: This will be a bit of a problem if you already shared your repository with others - because the SHA1 hashes will change.



Useful Resources

Official git website

Official git website at git-scm.com

Interactive Online Tutorial

Github has created a fun online course for learning git:


Screenshot of githubs interactive git course website

Pro Git eBook

The “Pro Git” eBook is available for free on the git website.

Pro Git Online / Pro Git PDF

Screenshot of the online version of the Pro Git eBook


Other Resources

Fork allmark on GitHub