Git 100

Git has become a must-know tool these days. Not only for programmers, but for any would be dev/sys/sec ops types. With the rise of configuration management and infrastructure as code, Git is no longer optional for someone in my line of work.

So What Is Git?

Git is a version control system. Git at its core keeps track of changes. It creates versions of files and allows us to compare versions and see what has changed between them. It also allows for a systematic way to review change history and revert to older versions. It lets us clone other people’s files(repositories), modify them on our own, and later commit the changes we made. These are the big features of Git.

History of Git

The original version control system was SCCS Source Code Control System and was used primarily on the UNIX OS. Next came RCS Revision Control System this was the first cross platform VCS. The next big VCS was Apache Subversion(SVN). Its uniqueness was that it was not just tracking files. Subversion was watching the files in a directory taking snapshots of directories. Transactions committed the entire set of changes to a directory at one time. Finally, Bitkeeper was the most commonly used VCS in the years preceding the creation of Git. The community edition was the main VCS for the Linux kernel. In 2005, Git was created, many say, because Bitkeeper discontinued the community edition. Git was created in 2005 as an open source project and is the most successfull VCS of all time.

Distributed Version Control

Git is a distributed version control system as an alternative to traditional VCS which had one central repo for tracking versions of files. Distributed version control tracks changes as their own entity and can be applied to multiple repositories. There is not one master repository that all other repositories are behind. There can be multiple repositories with multiple change sets. For example:

Repository 1: A, B

Repository 2: A, B, C

Repository 3: A, B, C, D

Repository 2 and 3 are not “behind” repository 1 the way you may think. Distributed repositories allow us to update each repository individually apart from the other. For example, we could update repository 1 with D from repository 3 without issue. But be aware that, by convention, people often have a master repository which everyone commits to, even if it’s not required by Git.

Benefits of distributed version control include no single point of failure, you don’t have to have network access, you can work independently and then later submit changes for review. Git allows the idea of forking a repository. All repositories are considered equal.

How to Install

This link provides instructions on how to install Git on Windows, OSX or Linux. Note: when installing on Windows make sure to choose “Checkout Windows-style, commit Unix-style line endings” when the installer ask about how to deal with line ending conversions.

Initial Git configuration:

System level:

apply to every user of the computer

User level(Global):

apply to the current user

Project level(local):

apply only to the local repository

The syntax for configuration is git config followed by a flag that identifies at which level you want to set the configuration.

  • System
    • git config --system
  • User
    • git config --global
  • Project
    • git config

Keep in mind that the settings at the lowest level take priority. For example, settings at the user level take priority over the system level setting.

Config File Locations

Location can be found on Windows machines with

git config --list --show-origin

More easily on *nix based systems, the system configuration is at /etc/gitconfig, the user level is at ~/.gitconfig and the project location is at project/.git/config.

Example Time

Note how after Git config we are setting the level of configuration using the –global flags. Also note how the commands are updating the configuration file. The green arrows point to the command first, then to the locations in the configuration file where the modification was made. We could actually edit ~/.gitconfig for example with [user]/name instead of using –global


Git Help (Not a Pun)

git help

 will list the most common Git commands.

git help command

 will give you detailed help on the command.

Git 101 coming soon!

Proxy Variables

While setting up squid proxy on my pfSense home lab gateway, I had trouble getting apt-get update to work on my Ubuntu/snort box which was behind the proxy. After some quick Googling, I tried the first response (because the first response is always the best right 😉 ), and the first response failed. After reading a few more blogs, I noticed there were many different ways to setup a proxy properly. Here’s what I found.

Setting up a proxy on the command line starts by declaring the proxy environment variable. Applicable variable options are:


Next, check if you currently have a proxy already set.

$ env | grep -i proxy 

If you get nothing from the command above, you know you don’t have a proxy yet. If you only want http and ftp to go through your proxy, export those variables instead of some of the other options above.

$ export {http,ftp}_proxy="http://proxy_name_or_ip:port_number"

This will only export the variable for the current session. If you log out or reset the computer, you will lose the proxy setting. If you need to make it permanent, use /etc/environment which is Ubuntu’s system-wide location for environment variables. You could also put it in /etc/profile.d as a file since this directory is ultimately read by /etc/profile. It’s not best practice to set it in /etc/bash.bashrc because variables in this file are specific to shells. Finally, if you want only a specific user to receive the proxy, you should set it at ~/.bashrc

If you want to read more about proper placement of environment variables, read this Ubuntu Environment Variables.

Now add your settings to /etc/environment

 echo "http_proxy=http://proxy_name_or_ip:port_number" >> /etc/environment;\
 echo "ftp_proxy=http://proxy_name_or_ip:port_number" >> /etc/environment 

If your proxy requires a username and password, the following format is often used:

echo "http_proxy=http://username:password@proxy_name_or_ip:port_number" >> /etc/environment

Most of the time you would be done at this point. But I had an issue with APT where I had to set the proxy in the APT configuration file.

I had to edit /etc/apt/apt.conf and add

Acquire::http::proxy "http://proxy_name_or_ip:port_number";

If you are curious about how to configure YUM similar to APT, you need to edit /etc/yum.conf

Once the file is open, add these lines to the section [main]


While we’re talking about proxies, CNTLM is another proxy that you install locally and point your proxy variable to localhost. It is a middle-man proxy that sits between you and a proxy that requires NTLM authentication. I have found this incredibly helpful when using Linux in a Windows environment. It’s a really cool piece of software and really easy to setup.

It’s in the Ubuntu repositories.

apt-get install cntlm

Its configuration file is found at /etc/cntlm.conf

Add the following:

Username        jamey
Proxy           proxy_ip:proxy_port

Next we create password hashes.

cntlm -H

The output should look like this

PassLM          ACF337F47B2E22ED552C4BCA4AEBFB11
PassNT          2A22CC95E275BE3150326D0C1E86A58E
PassNTLMv2      F001B46C503A3A01611D2859EBEA8762    # Only for user 'jamey', domain ''   

Copy/paste your output to /etc/cntlm.conf

Finally configure the local proxy variable as we did above to point to localhost instead of an external proxy.

export http_proxy=