Monday, February 17, 2014

First Time Playing With Version Control (Git)

Version control. Not typically covered in beginner programming courses. I'm not sure if it's ever really covered unless you get a programming job with a team where you're forced to use some method of sharing and distributing your work, and even then I've run into stories where startups come up with some organically grown in-house methods of avoiding proper version control.

What is version control? It's more or less as the name implies. Version control applications allow you to save different versions of your application source so you can roll back changes to different points in time. Screw up a new set of patches? Roll it back. Want to experiment with an experimental feature? Branch the source to create a parallel version of your application. If it works, you can merge that branch with the "known good" version. Or if it's a one off, you can create the new function and roll everything back if you change your mind (although the branching method is preferred.) Version control makes it simple to track your progress and the history of your application development.

Since I was playing with Go starting from scratch it may be a good time to at least try to expose myself to the basics of Git. The Raspbian install already had Git installed from repo, probably as a requirement for another package. The Git site has instructions for installation on your platform of choice (although if you're running Linux, I'd suggest a Google search for installing Git on your distribution of choice.)

Actually using version control is a little irritating in that it adds more steps, but isn't horribly cumbersome. Once I had created a source code file, I ran:

git init

...from the root of the directory I am creating my source code in. This creates a local Git repo in a hidden (on Linux and Unix systems) .git directory. Every change you commit is placed into a structure under the .git directory, making it really convenient to back up or start your version control from scratch if you decide to do so for some reason.

Then you tell Git that you want to add files to the local repo.

git add .

That tells it to just add everything, folders and files and all. You can add specific files by changing the period to a filename. You can get a status using

git status

...which in my case replied with:

# On branch master
#
# Initial commit
#
# Changes to be committed: # (use "git rm --cached <file>..." to unstage)
#
# new file: hello_world.go
#


This tells me I'm working on the branch called master and it's ready to add the file hello_world.go to the local repo. It hasn't done it yet, though. First, I configure a couple of items that get added to my commit metadata:

git config --global user.email "me@me.com"
git config --global user.net "My Name"
git commit

The commit command tells git to actually put the files in to the version control system. Git opens a simple text editor and at the top I enter a line to describe my first commit message. When I exit, the console replies with:

[master (root-commit) ac7121a] Created first hello world source file
1 file changed, 9 insertions(+)
create mode 100644 hello_world.go



The comment is at the top of the commit; "Created first hello world source file." Now I make a few alterations (experimenting with the workspace of a Go project, figuring out the directory structure), necessitating telling Git I added a few items.

git add .
git commit -m "Changed directory tree structure"

The "-m" adds the comment in the command line rather than bringing up a text editor. I'm not entirely sure that the "add ." does anything significant when I just created some directories since Git only replies with,

[master 708b35d] Changed directory tree structure
1 file changed, 9 insertions(+)
create mode 100644 src/hello_world.go

I made a few more changes while experimenting with my first Go program. Then I went back to the root of my project tree and ran a few Git commands.

cd ..
git add .
git status


# On branch master
# Changes not staged for commit: # (use "git add/rm <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# deleted: hello_world.go
#
no changes added to commit (use "git add" and/or "git commit -a")

git commit -m "Added a bin directory to tree"

At this point nothing seemed to be logged as a change. Using the command 

git log

...seemed to verify this. I theorize that if you alter directories, it doesn't seem to care. If you actually alter files, then Git notices and adds it to the repo. Maybe someone with more experience could validate that this is Git's behavior. 

I then go ahead and create a binary of my Go application then tell Git to commit the latest set of changes. I back out of my binary folder in my workspace and give Git some commands:

cd ..
git add .
git commit -m "Built the binary"

[master 3aeb831] Built the binary
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100755 src/hello_world

git log


commit 3aeb8311138035b4e46b75f9b2251a2c526b39a4
Author: My Name me@me.com
Date: Sun Feb 2 13:14:59 2014 -0500
Built the binary
commit 708b35d1e716feaf0562e8adbcc2e26c53292bb0
Author: My Name me@me.com
Date: Sun Feb 2 12:57:17 2014 -0500
Changed directory tree structure
commit ac7121a7b8a95a08d95a4e421f0dd87fec0a11af
Author: My Name me@me.com
Date: Sun Feb 2 12:41:26 2014 -0500
Created first hello world source file
...here you see that "git log" tells you the history of commits, with the comment, date, and person who made the changes.

This covered the basics of creating a local version repo, committing your changes, and getting a status of your commits. Not too hard; if you're using the command line, it usually means having to remember periodically commit with a quick note of what changes you had made.

Git has several other functions available and this only covered the basics of starting with Git. I haven't played with branching, and nothing here displayed how to roll back changes. A near future blog entry will review another feature of Git, but for now this is enough to absorb into the "what am I doing" part of the brain.

No comments:

Post a Comment