OpenVPN/git crash course

From Secure Computing Wiki
Revision as of 13:51, 1 March 2010 by Dazo (Talk | contribs) (Saving changes: Enhanced section about commit --author)

Jump to: navigation, search

Cloning a git repository

What this means is that you actually download the complete code repository to your own hard drive. This is different from centralised VCS/SCMs, which only have a copy of the files you checked out. With git you get a complete copy of the complete history, locally. This is one of the reasons why git can be very quick.

git clone {repository} [{local name}]

The {repository} string can point at a git:// URL, http[s]:// URL or a local file URL. When the cloning is completed, you will automatically have checked out the 'master' branch.

Introducing yourself

Git should know who you are, as that will be important for the git commit logs. So please enter a directory created by git clone and do:

git config 'Your name'
git config ''

This will only set these variables locally in this repository. I would probably recommend you to make these changes globally as well, as this can be easy to forget if your do another git clone.

git config --global 'Your name'
git config --global ''

Some might only need to do the latter one, but some might want to use different e-mail addresses for their commits for different projects.

Other neat features to enable - making git colourful

This is highly recommended, as it is easier to read commit logs and patches via the git commands this way.

git config --global color.branch auto
git config --global color.diff auto
git config --global color.log auto
git config --global color.interactive auto
git config --global color.status auto
git config --global color.pager true

Notice that we here force colours when using the pager. This might mean you need to add one more change as well:

git config --global core.pager 'less -X -R -F'

Now do this:

cat ~/.gitconfig
cat .git/config

As you can see, the configuration files are not that hard to read. These files may be edited manually if you want to as well.

Checking the status of the project

git status

This command gives you an overview over all files which have been modified and all new and unregistered files. The output of git status should be pretty obvious.

Checking your changes

git diff [{filename}]

This will list all local changes which has not been committed.

Saving changes

All files new files will need to be added to an index to be prepared for a commit. Consider this as a "pre stage" which needs to be done. This is also different from other VCS/SCMs. But it has it's advantages as well. So if you add or modifies files, you need to do this to add files to the index when you want to commit your changes:

git add {filename/directory}

If you have a long list of files under the git status section called Changed but not updated:, you can do:

git add -u

This adds all these files into the index. If you now try to do a git diff', you'll see that nothing turns up. And if you modifies one of the files and do git diff' again, you'll find that only your last changes is shown. This is normal behaviour. git compares to what's in saved the index and what the local file looks like.

If you want to see the changes from what's in your index and the previously committed version, you'll need to do:

git diff --cached

Please also try:

git status

Notice the change of the message for the files which you have added. Now, let's commit!

git commit -s

Now an editor should turn up, you can enter your commit statement and exit. Notice the -s argument. That means sign-off'. That adds an 'Signed-off-by: ' signature at the end of the commit log. Please do it a habit to always sign-off your commits. That simply means you approve the commit. And this is especially important if you commit work for others.

To change the author of some code in the commit log, you can do that via the commit as well:

git commit -s --author "Authors name <>"

This is important to remember if you apply patches from others. This way it is possible to track from whom the different code parts came from.

Look at the commit log

git log

This is the most basic usage. Other nice usages is to follow a files commit log, and not the complete project's commit history:

git log --follow {filename}

If you also add -p, you can also see the diff.

There's also a feature called git show. This shows the contents of a commit or other git objects. If you just do

git show

it will show the last git commit. But you can give it a commit ID which you can find in the git log. If you give it a branch name or a tag name, you will see the git commit of the branch point or at the commit where the tag points at.

git show 684790552dde0475745015a76762ecc5a11eedab     (commit ID)
git show 684790552dd                                  (partial commit ID)
git show origin/allmerged                             (remote branch)
git show v2.1.1                                       (tag name)

Creating patch files

When you have done some commits, you probably want to share them. Say you want to pick out the last commit.

git format-patch HEAD^1

This notation might look odd. HEAD is a keyword, which means head of the commit log. It's where the last commit happened. It's because git format-patch takes ranges. This notation means, from HEAD - 1 commit and to the last commit. If you do just HEAD, the range "distance" will be 0, and no patch file will be created. It's like saying from A to A. But you really want to say, from A to B. To explain that, you can do:

git format-patch HEAD^1..HEAD

So, what happens if you change HEAD^1 to HEAD^3 ... well, you get the 3 top-most commits as patch files. git format-patch will report the file names it generates on-the-fly.

git format-patch can also take commit ID's which you find in the commit log, in addition to branch names and tag names. So if you want to have all commits from OpenVPN 2.1_rc15 to OpenVPN 2.1_rc22 ... you can do:

git format-patch v2.1_rc15..v2.1_rc22

You can also do this with git log.


If you wonder where 'v2.1_rc15' came from in the example above, that's a tag name. And tags can be found by doing:

git tag -l

A tag is just a name of a particular commit ID. Commit ID's can be tricky to remember, and then you can insert tag names which are a bit more descriptive.


Branches are almost the same as tags, but with one difference - you can commit to them. You can also quickly create your own branch to test out things, without being worried about your former commits.

First, let's look at some branches: git branch

This will list all your local branches. But we also have some remote branches. git branch -r

Notice the difference between them, where remote branches are prefixed with origin/. This is because git tracks remote branches separately from your local branches. So you can have a master branch which is different from origin/master. Another thing, to be able to do commits on remote branches, you must check them out as a local branch before you can do commit.

You can also add more remote repositories, and will then have different remote names. origin is just a remote name, which is the default name for the remote where you did your initial clone. We will not dig into this here.

Checkout a branch

In OpenVPN, there's a branch called allmerged. So to checkout that branch locally, we do:

git checkout -b allmerged origin/allmerged

That's it :) Now you can do commits to your own copy of the allmerged branch.

If you find out that you want to do some experimental stuff, to see how it works out, just do:

git checkout -b my_test_branch

And it will create a new branch, enter it, from the latest commit where you where. You can now even commit into this branch.

Merge branches

If you find out that one branch has some stuff you want to test out with your own stuff in your own branch, it's quite easy.

git merge {branch to merge into your branch}

If there are some conflicts, just do a git diff to see what they are. You need to solve these issues before you then can continue. The conflict blocks are pretty visible and you will hopefully understand what to leave in the file and what to remove. When that's done, it's the same procedure as before - git add and git commit.

If there were no conflicts, a merge commit is done automatically for you.