BillJellesmaCoding

AboutBotPalsQuick Tip Tweets

Git a Good Process

by Bill Jellesma
2019-02-14 23:00:00
Git a Good Process

An important feature that I've come across in coding is being able to version your software. The idea of versioning my software was easy to follow for a kid who spent the majority of his childhood playing RPGs on Playstation. Using version tracking software is like saving your game so that when you eventually wander down the wrong path, you're able to go back to your last save point. But version tracking software can even be more powerful than a simple save point, one is able to create an entirely new game from that save point. If you decide to keep the good parts of your new saved game, say you got a better weapon from a boss, you can even take those good parts of your new game and use it in your main game file!

GIT history

Analogies aside, version control software is not a new concept and has been around since the 70s when they were first created for UNIX systems. The early version control software, Source Code Control System (SCCS) and Revision Control System (RCS) most notably, only tracked changes in single source code files and not in the entire project. This software was also meant for single users as it only existed on the local file system. Local is fine for solo developers but doesn't work out well when you have full teams working on the project.

In the 80s is when software version control went from being to a client server model so that developers could collaborate; this meant that code was stored in central repository that developers could use and contribute. This model was heavily used during the .com era and enabled the early open source projects such as Mozilla. You may have heard of Concurrent Versions System (CVS). In addition to CVS not being the drug store down the street, it was the first version control software to have that central repository, but was still limited to only tracking files and not the entire project.

It wasn't until Subversion was officially released in 2004 that developers were not able to track entire directory structures. Tracking directories was attained by being able to track non text files; a directory is, after all, just another file. Subversion is developed by the Apache Software Foundation which is very well known in the open source community. It's small wonder why Subversion is still actively developed and in use today.

2005 saw a change to the current model of a centralized repository with two widely used systems, Git and Mercurial. Both Git and Mercurial are Distributed Version Control Systems meaning that users have their own individual repositories to track changes and can then share their changes with a centralized server. Git users also have the option to use Github to share their projects publicly in open source fashion. Mercurial is also very widely used and provides the ability to write custom extensions.

Git Setup

The software that I am most familiar with and see used most around the internet is Git. To get started, download Git.

The remainder of this setup applies to using the powerful git bash, but there are GUIs available for Windows here. These GUI clients are all third party and may or may not be free and distributable. If you follow along with installing the git bash, you will also have the option to launch a basic GUI but they're not as powerful as these GUI clients.

When you run the installer for git, you are greeted with a few more options that your normal installer gives you.

Sidenote: the following screens are presented when install Git for windows. Install Git for linux was simply done through sudo apt-get install git and similarly brew install git for Mac OSX

The first page presents you with the GNU General Public licencing information. The second page will ask you to select the components that you'd like; the defaults should be fine unless you want to select On the Desktop unter Addition Icons

Git Components

Next, you are asked the editor that you would like to use with Git. This is the editor that you'll use with commit messages, merge conflicts, etc. By default, VIM is select as the default editor. VIM is the most widely available command line editor but, in my opinion, a huge inducer of headaches. You can use Nano, which is also a command line editor and much more friendly. You will also have the option to use any editor installed on your system, which may seem like a great option since your editor is so familiar and extensible, but an instance of it will also need to be opened every time git uses it causing slower workflow. Let's choose Nano as it seems to have the best of both worlds

Git Editor

Up next are options to use Git from other consoles other than the Git Bash. I find this useful when working on Windows so that I can use Git from the command prompt and powershell as well as the Git Bash. I've also found, however, that I usually open Git Bash whenever I need command line access anyway.

Git Path

Next up are choosing to use openssl for https connections and choosing how line control character are interpreted. Both screens can be left with default selections. Line breaks are written differently on Windows VS Unix. When storing files in a repository, it is best to store the files with the Unix LF (Line Feed) as it's more universal to systems that may use the repository. Since we are on a Windows Machine, Checkout Windows-style, commit Unix-style line endings is the recommended setting.

Git OpenSSL

Git Line Breaks

The next option is very important for the true bash look and feel, Use MinTTY will enable you to properly reside bash windows and display characters, common limitations that command prompt (at least before Windows 10) had.

Git terminal

The final options are for performance, authentication, and symbolic links. As with previous screens, the default options will be fine. If you have a file that is a symlink on your file system, this data will be stored as well if you select this option.

Git Final

You can now install the software! For those that prefer to use a GUI, you can launch a basic GUI with the following

git gui

Git init

Now that we have Git Bash downloaded, we can create our first repository and get (no pun intended) a good development process rolling.

Open Git bash and navigate using cd (change directory) to a directory for our new project. We can create the project directory with mkdir. Finally, we can initialize a repository on the file with git init.

cd path/to/project/dir
mkdir git-test
cd git-test
git init

Your output should look like the following:

Initialized empty Git repository in path/to/project/dir/git-test/.git/

We can see that a repository is made (if we are using git bash) because a (master) will appear next to our prompt in bash.

We will create one file, a readme, so that we can see how the staging area and commits work.

# create readme.md file
touch readme.md
# Use git status to see any new files since your last commit
git status
# We see that readme.md is a new file so we will add it to the staging area
git add readme.md
# Commit the new changes to our repo
git commit -m "add readme.md"

We will see that the commit was created with a strange id (yours will be different)

[master (root-commit) f92c7c5] Add readme.md
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 readme.md

Let's make a second commit to add two new files, numbers.txt and letters.txt

# create two new files
touch numbers.txt letters.text
# to add all untracked files, use a .
git add .
# Commit the new changes to our repo
git commit -m "add new files"

Now that we have more than one commit, we can use the following command to see all of our commits on the master branch

git log

You will see output similar to the following, IDs will differ:

commit 3d7001fcf664cc9fd424ce160bfd18d681d3cc7c
Author: test user
Date:   Wed Feb 13 23:32:27 2019 -0500

    Add new files

commit f92c7c56d9dc0698c1e477e4980469b336b11f6b
Author: test user
Date:   Wed Feb 13 23:26:47 2019 -0500

    Add readme.md

We now realize that we don't actually want the numbers or letters file. We could just delete both files, but what if those files had code in it and we only wanted some of that code gone? What if we added code, deleted the code, and decided we wanted it back? Can you remember what code to delete and what code to add? I sure can't. Luckily, we can just go back to our previous commit using the checkout command along with the ID of the commit.

git checkout f92c7

Notice that we don't need the entire commit ID, just enough for git to recognize what we mean.

Our output is the following

Note: checking out 'f92c7'.

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 f92c7... Add readme

Detached HEAD state means that we are just looking at this commit. The branch's HEAD is still at the commit with numbers and letters. You can see this as the ID of the commit is now in place of (master) on your prompt.

Once we are positive that it was a mistake adding those two files, we can use reset to move the HEAD to our readme commit.

#move back to the head of our branch
git checkout master
# reset HEAD to the readme commit
git reset f92c7

Now that we have an idea about how git can benefit us with save points, let's look at improving our development process with branches. When I begin working on new projects, I like to create two branches, development and production. Remember that we need to make initial commits on the branches. To make branches off of the current commit, we can use checkout with the -b argument

# Create dev branch
git checkout -b development
# Create file and commit it to dev
touch sample.txt
git add .
git commit -m "Create Development branch and add sample.txt"

# Create Production Branch
git checkout -b production
# Remove file and commit it to prod
rm -r -f sample.txt
git add .
git commit -m "Create Production branch and remove sample.txt"
# Make sure that we are at the head of the development branch for any future changes
git checkout development

Now, whenever creating new features that we may want to revert from in the future, such as creating numbers and letters file, we will make commits to the development branch in the project. When we're finally happy with the work that we have in development, we take all of that work on development and copy it onto our production branch

# move to production to ensure this code is ready to be merged with
git checkout production
# merge our development changes
git merge development

Merge Conflicts

It is very possible when you merge files from the development branch, you may a difference in that same file on your production branch. This results in a merge conflict. If a merge conflict occurs, that text editor that you chose will open up and you will see both versions of the file presented in the editor. Fixing merge conflicts is very dependent on your code but, in my experience with only having two branches, I simply want to keep all of the development versions of the files since they are newer.

# abort current merge so that the merge conflict goes back to the unmerged branches
git reset --hard HEAD
# merge development and keep all files from development in the case of merge conflicts
git merge -X theirs development

References

SCCS Wiki Page Lynda.com Learning Software Version Control Course CVS Wiki Page Subversion Git