Post-Image

Git For Network Engineers

What is Git?

git-logo

Git is a source control manager (SCM), also known as revision control. It manages changes to documents, computer programs and large websites. Arbitrarily it can manage versioning for collections of information.

Why is it important to network engineering? Well, currently we stick the config files in a directory and forget about them. Version control can be very regimented with commit comments and other markers, which helps to identify information. More importantly, as we move towards DevOps with open arms, we have to think about managing what we do in different ways. Just because something has been done a certain way, doesn’t mean it’s good to continue with that modus operandi.

Fear not – just because something is hidden away in a repository, doesn’t mean you can’t diff files etc.

Also you don’t have to have just local git repositories, you can have them on remote servers as well as the likes of github.com.

Before we start, be warned that this is a very simple example. You can use this for managing all sorts of configurations like core routers, firewall access-list entries, hell, even change control data. Be mindful of what you push and commit!!! Ensure that you secure your .git repository well.

Info! Turns out it is git’s 10th birthday the week this article was intended to be published. Happy birthday you old Git! 😀

Installing Git

Git is really simple to install. Most operating systems have pre-made packages/binaries available so use those unless there is a burning desire to build from source.

Debian

apt-get install git

Fedora

yum install git

Windows

http://git-scm.com/download/win

OSX

http://git-scm.com/download/mac

So how can I use it and why do people bang on about it?

Git is a version control system. Simple. It allows you to check in and check out files in to branches. These branches can then be later merged in to another branch or master pending change review (normally code sign off on something like Gerrit – not covered here for simplicity and brevity).

If you can get in to the habit of using git, your life will be easier when you start mingling with the DevOps community who use this stuff day in day out amongst other tools.

Creating a repository – also known as a repo

You create a repo by issuing the below in a directory of your choosing. Here is an example on OSX. You can do this on Windows and Linux using the same workflow (maybe not using the exact same bash sequence or syntax!)

Davids-MacBook-Pro-2:TESTGIT davidgee$ pwd
/Users/davidgee/TESTGIT

Davids-MacBook-Pro-2:TESTGIT davidgee$ git init
Initialized empty Git repository in /Users/davidgee/TESTGIT/.git/

Adding files to the repo Let’s create a simple text file and add it to the repo.

Davids-MacBook-Pro-2:TESTGIT davidgee$ touch hostname.txt

Davids-MacBook-Pro-2:TESTGIT davidgee$ echo "HOSTNAME=IPENGINEER" > hostname.txt

Davids-MacBook-Pro-2:TESTGIT davidgee$ cat hostname.txt 
HOSTNAME=IPENGINEER

For instance I have just created a directory, initialized a git repo and placed the text ‘HOSTNAME=IPENGINEER’ in to a text file called ‘hostname.txt’.

Next, lets add the file to the repo

git add hostname.txt

We can check the status of the git repo to make sure the file has been added:

Davids-MacBook-Pro-2:TESTGIT davidgee$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached ..." to unstage)

	new file:   hostname.txt

At this point we have a file added to the repo, but we haven’t committed it to the project history. This means it’s kind of cached and git knows about it, but it’s not actually checked in until it’s committed. We therefore add it to be committed and then commit it.

Davids-MacBook-Pro-2:TESTGIT davidgee$ git commit -a -m "Initial commit"
[master (root-commit) 7a684a2] Initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 hostname.txt

The -a switch means ‘all’ modified files and the -m switch adds a message to the commit.

Let’s take a look at the status of the repo now we have added a file to it:

Davids-MacBook-Pro-2:TESTGIT davidgee$ git status
On branch master
nothing to commit, working directory clean

Using the standard git tooling, we can also take a look at the files in git along with the information around the commit. Be warned, sometimes this can be a lot! The –abbrev-commit switch allows us to see a shorter version of of the commit ID that in this case is: 3dc5449 instead of the 40 byte hexadecimal monster.

Davids-MacBook-Pro-2:TESTGIT davidgee$ git ls-files
hostname.txt

Davids-MacBook-Pro-2:TESTGIT davidgee$ git show --abbrev-commit
commit 7a684a2
Author: DavidJohnGee 
Date:   Tue Apr 7 17:52:58 2015 +0100

    Initial commit

diff --git a/hostname.txt b/hostname.txt
new file mode 100644
index 0000000..ef07d9e
--- /dev/null
+++ b/hostname.txt
@@ -0,0 +1 @@
+HOSTNAME=IPENGINEER

Note the bottom line? ‘+HOSTNAME=IPENGINEER’.

Now we’re cooking!

Branches

So what is a branch? A branch is a checked out version of the repo. You can create a branch called ‘shonky’ for example and checkout the current master repo content in to it. You could add all sorts of rubbish to the branch without it affecting anything else. At this point, we only have the one branch, which is the master. To check what branch you’re on do this:

Davids-MacBook-Pro-2:TESTGIT davidgee$ git branch
* master

To create a branch, you use the same ‘git branch’ input, however place a name after the branch part.

Davids-MacBook-Pro-2:TESTGIT davidgee$ git branch shonky

Davids-MacBook-Pro-2:TESTGIT davidgee$ git branch
* master
  shonky

So now, let’s practice switching to the branch using ‘checkout’ which checks out something in to the directory. We’ll also modify the content of the hostname.txt file but not commit it.

Davids-MacBook-Pro-2:TESTGIT davidgee$ git checkout shonky
Switched to branch 'shonky'

Davids-MacBook-Pro-2:TESTGIT davidgee$ git branch
  master
* shonky

Davids-MacBook-Pro-2:TESTGIT davidgee$ git status
On branch shonky
nothing to commit, working directory clean

Davids-MacBook-Pro-2:TESTGIT davidgee$ cat hostname.txt 
HOSTNAME=IPENGINEER

Davids-MacBook-Pro-2:TESTGIT davidgee$ echo "HOSTNAME=SHONKY" > hostname.txt 

Davids-MacBook-Pro-2:TESTGIT davidgee$ cat hostname.txt 
HOSTNAME=SHONKY

Davids-MacBook-Pro-2:TESTGIT davidgee$ git commit -a -m "Changed hostname to SHONKY"
[shonky d25bec7] Changed hostname to SHONKY
 1 file changed, 1 insertion(+), 1 deletion(-)

Davids-MacBook-Pro-2:TESTGIT davidgee$ git show
commit d25bec7f98e11b1a5692c587d1c219aee46343f7
Author: DavidJohnGee 
Date:   Tue Apr 7 17:55:58 2015 +0100

    Changed hostname to SHONKY

diff --git a/hostname.txt b/hostname.txt
index ef07d9e..f16ecde 100644
--- a/hostname.txt
+++ b/hostname.txt
@@ -1 +1 @@
-HOSTNAME=IPENGINEER
+HOSTNAME=SHONKY

At this point we have a new branch and we have committed our changes to it. Does that mean it’s overwritten the main branch? No!

Davids-MacBook-Pro-2:TESTGIT davidgee$ git checkout master
Switched to branch 'master'

Davids-MacBook-Pro-2:TESTGIT davidgee$ git branch
* master
  shonky

Davids-MacBook-Pro-2:TESTGIT davidgee$ cat hostname.txt 
HOSTNAME=IPENGINEER

See the difference? We can switch between two versions of our file, as it resides in two different workspaces, called branches! If we want to merge the changes to the master branch we can do that using the ‘merge’ feature, or we can just override the master and commit the branch in it’s entirety to the project history.

In this instance, let’s merge.

Davids-MacBook-Pro-2:TESTGIT davidgee$ git merge shonky
Updating 7a684a2..d25bec7
Fast-forward
 hostname.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Davids-MacBook-Pro-2:

TESTGIT davidgee$ cat hostname.txt 
HOSTNAME=SHONKY

Now we can delete the branch and move on.

Davids-MacBook-Pro-2:TESTGIT davidgee$ git branch -d shonky
Deleted branch shonky (was d25bec7).

We have made a horrific mistake!!!

Oh dear god/s, we have made a terrible mistake and the world is going to end. We need to revert back the code prior to the hostname change.

We have two ways of achieving this. A heart stopping method versus a safer method.

Before we do this, we need to isolate the version we require by looking at the commits to the project history.

Davids-MacBook-Pro-2:TESTGIT davidgee$ git checkout -b restore
Switched to a new branch 'restore'

Davids-MacBook-Pro-2:TESTGIT davidgee$ git rev-list --all --pretty --abbrev-commit
commit d25bec7
Author: DavidJohnGee 
Date:   Tue Apr 7 17:55:58 2015 +0100

    Changed hostname to SHONKY

commit 7a684a2
Author: DavidJohnGee 
Date:   Tue Apr 7 17:52:58 2015 +0100

    Initial commit

Method a) RESET < The scary one

This one involves resetting the current directory and resetting the head position (the current position of the git tracking mechanism) to our chosen restore point.

Davids-MacBook-Pro-2:TESTGIT davidgee$ git reset --hard 7a684a2
HEAD is now at 7a684a2 Initial commit

Davids-MacBook-Pro-2:TESTGIT davidgee$ cat hostname.txt 
HOSTNAME=IPENGINEER

Davids-MacBook-Pro-2:TESTGIT davidgee$ git branch
* master

Method b) Branch and merge < the less scary one

The checkout method involves checking out the revision we require into a branch.

Ok – so our commit ID prior to the hostname change to ‘shonky’ was 7a684a2. Let’s check that out from the repo.

Davids-MacBook-Pro-2:TESTGIT davidgee$ git checkout -b restore
Switched to a new branch 'restore'
Davids-MacBook-Pro-2:TESTGIT davidgee$ git branch
  master
* restore

Davids-MacBook-Pro-2:TESTGIT davidgee$ git checkout 7a684a2
Note: checking out '7a684a2'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at 7a684a2... Initial commit
Davids-MacBook-Pro-2:TESTGIT davidgee$ cat hostname.txt 
HOSTNAME=IPENGINEER

Ok – that worked, but that isn’t master, however we’re good for now and we have our file content back the way it should be. When I say “good for now”, I mean we’re not going to get murdered for this change! Checkout this to a branch like

git checkout -b potential_restore_point

and commit it. We are not however on the master branch. We can merge to make this happen like we did before. I won’t do this, but will leave it to your curiosity.

Cloning from a public repo

Ok – so you have located a project you want a copy of. How does that work? Well, you clone it using git like this:

git clone https://github.com/blah/blah

Once this has been done, you will need to change in to the directory that git has cloned the repo in to.

How about pulling?

Git can be used to fetch and pull remote repositories.

git fetch

will pull any new work and

git pull

will fetch and merge a remote branch into your current branch.

Keep a track of what branch you are in at all times else face potential disaster!!!

Davids-MacBook-Pro-2:TESTGIT davidgee$ git clone https://github.com/davidjohngee/ipngnc
Cloning into 'ipngnc'...
remote: Counting objects: 100, done.
remote: Total 100 (delta 0), reused 0 (delta 0), pack-reused 100
Receiving objects: 100% (100/100), 150.02 KiB | 0 bytes/s, done.
Resolving deltas: 100% (41/41), done.
Checking connectivity... done.

Davids-MacBook-Pro-2:TESTGIT davidgee$ cd 
.git/         hostname.txt  ipngnc/    

Davids-MacBook-Pro-2:TESTGIT davidgee$ cd ipngnc/

Davids-MacBook-Pro-2:ipngnc davidgee$ ls -la
total 32
drwxr-xr-x  10 davidgee  staff   340  7 Apr 18:56 .
drwxr-xr-x   5 davidgee  staff   170  7 Apr 18:56 ..
drwxr-xr-x  13 davidgee  staff   442  7 Apr 18:56 .git
-rw-r--r--   1 davidgee  staff   360  7 Apr 18:56 .project
-rw-r--r--   1 davidgee  staff   423  7 Apr 18:56 .pydevproject
drwxr-xr-x   3 davidgee  staff   102  7 Apr 18:56 dist
drwxr-xr-x  14 davidgee  staff   476  7 Apr 18:56 ipngnc
drwxr-xr-x   6 davidgee  staff   204  7 Apr 18:56 ipngnc.egg-info
-rw-r--r--   1 davidgee  staff    42  7 Apr 18:56 requirements.txt
-rw-r--r--   1 davidgee  staff  2273  7 Apr 18:56 setup.py

With regards to working with remote repo’s, there is a link at the bottom of this article that explains things much better than I!

You seem to add a lot of switches in to the git commands…where do you get those from?

Good question. Git has a great –help system built right in. If you try

git --help

you get the common commands. If you then try a common command and –help again, you effectively get a man page. That’s the way to navigate git. There aren’t any secrets.

What about working with github or a remote repo?

It goes without saying you can push to Github or a remote git repo. The way to do this is:

git remote add remoterepo https://xxxxxxxxx
git remote -v
git push  

This post does not go into detail on this specific part of git and you should research carefully to ensure it’s what you actually want to do! The second line

git remote -v

outputs the repository you’ve just setup. Bare in mind your username and password will also be required for the remote repo. FINAL WARNING – ensure that you do not push accidentally any sensitive information to the public domain.

Where does the magic happen?

All of the magic happens with the git client, which interacts with the contents of the .git directory. The .git directory is created when you initialize git in your chosen directory and is updated when you perform actions like add and commit. If you delete the .git directory, not only do you lose git capabilities including the history, but also you’re stuck with the files you have in the branch you were in before deletion.

http://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging

http://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes

http://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks

Check my github repo github repo out which contains a hook for working with Golang

If all of the stuff around pushing to GitHub scares you, then you can use a GUI client, which is available for OSX and Windows

https://mac.github.com https://windows.github.com

Finally, a great git book with an unfortunate name of “Pro Git” 🙂

http://git-scm.com/book/en/v2 which is a free guide.

Dave
  • Tags: Git
  • Categories: Git