Git To It
February 10, 2015 Aaron Bartell
Note: The code accompanying this article is available for download here.
In my last article we learned about Ruby methods and encapsulation. During the various exercises there were many code changes made and we didn’t really have a simple way to keep track of how the code changed from one version to the next. That’s where source change management (SCM) tools like git come into play and is what we will be diving into today.
The git Website says: “Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.
Git is easy to learn and has a tiny footprint with lightning fast performance. It outclasses SCM tools like Subversion, CVS, Perforce, and ClearCase with features like cheap local branching, convenient staging areas, and multiple workflows.”
My history with SCM tools is Aldon for RPG, Subversion for Java, and a number of home-grown efforts. All served their purpose and I was glad to have them, but git has some very useful things that allow me to operate similar to how my workday flows (i.e., work on three different project and multiple versions within each of those projects at any given time). There are many ways and scenarios to use git, and for this article we will be focusing on setting it up on IBM i and maintaining a small local repository with an eventual goal of sharing it with other developers.
As we learned in the aforementioned description, git is a “distributed version control system” (DVCS for short). You can learn the benefits of DVCS by reading the git docs, and also it would be good to read the Git Basics page as they describe it quite well.
The main point to understand is that each developer has an entire copy of the repository in their environment. This means they can continue work and create “commits” even while not connected to the central repository. Then at a later time they can choose to sync back up with the server. This is also an advantage on the front of redundancy because the code exists in each developer’s environment. Not only that but the ability to do local commits of code, completely disconnected from a server, means you aren’t waiting to download and upload code–you do it on your schedule.
With that said, I don’t like to get too far behind the shared repository (usually GitHub.com or Bitbucket.com) because I get nervous the more source merges there are. And finally, probably the biggest advantage of git is conveyed in a future article where I show how to place your code in a GitHub repository where it can be shared with others in the open source community.
For the purposes of this article our development environment will be a directory in the IFS. This means your IBM i is actually the client in this scenario. The first step is to install git and the simplest way to do that is to obtain the free PowerRuby from PowerRuby.com. Git is also available here on the YiPs Website.
Once git is installed you will need to start up a shell session via ssh or CALL QP2TERM, where most git interaction takes place. One of the first things you need to do is configure your git profile by entering the following two commands in PASE; make sure to replace with your pertinent information. These settings will be used to signify your changes vs. those of other developers.
$ git config --global user.email "firstname.lastname@example.org" $ git config --global user.name "My Full Name"
Next create a directory structure where the Ruby code will be stored. I like to create a directory named git with a sub-directory of each repository I am working with, itjungle_4_git in this case.
$ mkdir -p /home/aaron/git/itjungle_4_git
Now cd to the new directory and run the git init command to initialize this directory as a git repository.
$ cd /home/aaron/git/itjungle_4_git $ git init
Running command ls -la will show that you have a new .git directory.
This is where everything pertaining to this git repository is stored. Everything within, and including, the current directory is now part of this git repository. That means git will keep track of changes and additions made to files. To test this let’s use the echo command to direct some content to a file named README.md. Note, .md extensions stand for “mark down” and is a very common file to have in the root of your git repository to describe the purpose of the files contained within.
$ echo "Some text" >> README.md
Now we can run the git status command to learn the repository status.
As you can see it recognized a new file was added and it is telling us to use git add to track it. Now run the following command to add README.md to the git repository.
$ git add README.md
Now if we run git status again we can see the file is being tracked and is ready to commit. A commit is a unit of work that marks a point in history of your repository. In a typical RPG scenario you might have changed an RPG module, added a copybook, etc. Each changed file would have the git add command invoked against it. It is also worth noting you don’t have to include all files you’ve changed. Sometimes I want to logically break things up based on the changes I’ve made and I use commits to accomplish that.
Now we are ready to commit this to the local repository (i.e., the .git directory) with the following command and corresponding message.
$ git commit -m 'Initial commit with README'
Running git status again shows us the following. Notice the 29293ec value. This is the commit hash that is computed based on the contents of all files. This gives us an exact representation of what all source files looked like at a certain point in history. This is a hugely beneficial feature, especially when application changes are coupled with database changes, to learn about all parts of an application that changed in a single commit.
Now that the git repository is set up, it is time to work through the motions of what we originally set out to do: Create a history of the previous article’s Ruby code so we can see how it changed over time. To accomplish this I went through the motions of creating IFS files, changing them, and doing git add and git commit commands repeatedly. You can see the full shell history here and the commit history here (which was produced with the git log command). There are many ways to edit IFS files: RDi, RPGNextGen, EDTF, joe, or create a network mapped drive and use your favorite PC editor. You pick what works best for you.
You have now had your first exposure to git and I hope you can see some of the advantages of this technology. It’s worth noting we’ve only touched the tip of the iceberg of how git and its corresponding tools can be used to aid in your source change management. Let me bait the hook by stating you can also use git for your RPG source code. Stay tuned for more on this topic in future articles!
I want to leave you with some resources you can check out.
Aaron Bartell is director of IBM i Innovation at Krengel Technology, Inc. Aaron facilitates adoption of Ruby On Rails on IBM i through professional services, staff training, speaking engagements, and the authoring of best practices within industry publications. With an additional strong background in RPG application development, Aaron also covers topics that enable IBM i shops to embrace today’s leading open source technologies, like using Git for RPG source change management or RSpec for unit testing RPG. Aaron is a passionate advocate of Ruby on Rails and the corresponding benefits available for today’s modern application developers. Connect with Aaron via email at email@example.com. Aaron lives with his wife and five children in Southern Minnesota. He enjoys the vast amounts of laughter having a young family brings, along with camping and music. He believes there’s no greater purpose than to give of our life and time to help others.