GIT – Part 1

      1 Comment on GIT – Part 1

GIT is a distributed version control system (DVCS) that has gained huge popularity. One reason of its popularity is from GitHub.

GitHub is a web-based Git repository hosting service that hosts open source software projects and private repositories. It provides a web-based interface for those repositories, along with feature requests and bug tracking.

GIT is also popular because it’s very fast and can be used on many platforms. On windows it can be accessed through the command line with Powershell for example, or from a GUI program such as an IDE (Integrated Development Environment) plugin/extension, like Git Extensions that can run inside Visual Studio.

Instead of the check-in check-out model (used with SourceSafe and some versions of TFS) that prevented changing the files until the original person who checked out the files, checked the files back in to release the lock, Git allows multiple developers to work on/make changes to the same files. Then when the dev’s land those changes back to the master branch of the repository, an auto and/or manual merge takes place.

Git records the changes to files (in its repository), and allows specific versions of the file to be viewed at any time. It also can be used to compare changes between versions and to revert to a previous version. It keeps track of the username and datetime it the file was modified.

A Master repository or branch contains latest version of all the files. A copy (mirror of the full repository with complete history) can be downloaded (pulled) from the server to the client for local editing. After an item has been modified, it can be merged back into the Master branch. Then when another developer gets the latest code from the Master branch, those changes are included. If and when files are lost on the local machine, or an updated version is wanted, the files can be retrieved from the server.

Why was Git created?

It was created for the Linux Kernel open source project. By 2005 there was a need for another repository system, since the BitKeeper software they were using was no longer free. So Linus Torvalds and other kernel developers created Git.

The name Git was created by Linus, and he said it had different meanings depending on a person’s mood. It could even be an insulting term: See Alternative meanings of Git.
Or mis-pronunciation of “get”
Or Global Information Tracker?

Git is so fast because many operations in Git only need local files and resources. This also means that you could work offline until it’s necessary to connect again to the server.

Each file in the Git repository is uniquely identified with a 40-character checksum hash. It is a SHA-1 hash that can be used to retrieve a file. So Git is basically a key,value data store. The key is the hash, and the value is the file content.

Here is an example of an SHA-1 hash: 8ae03dc9f9e25d7c6fadde96e2081fb0d2f6b19g

The collision probability would be p = (n(n-1)/2) * (1/2^b)). Where b = 160 (bits).

While SHA-1 is no longer considered secure as a cryptographic hash function, it is sufficient for avoiding hash collisions.

The odds of a collision are after generating 2^80 or 1,208,925,819,614,629,174,706,176 hashes. So it’s pretty good odds for Git file hashes to never have a collision.

So Git stores everything in a repository not by filename but by the hash value of its contents.

Let’s download and install GIT.

First, install GIT for Windows as known as msysgit.
That site also has other Windows download options such as Git for Windows Portable.

This version supports all Git operations and provides a BASH emulation that is used to run Git from the command line and also has Git GUI offering a graphical version to use instead of using the command line functions and provides a visual diff tool.

However, for a Git GUI version that I can use inside Visual Studio I use Git Extensions. More about Git Extensions in Git – Part 2.

After installing, open Powershell and type Git. This will display all the Git commands operations available.

In Windows, Git reads the .gitconfig file in the users directory such as C:\Users\[your login name]

The first thing to do after installing Git is to set your username and email. Configure Git with this command:

git config --global -e.

This opens the global config in your default editor. Or

git config --global "John Doe"
git config --global

Then to see that the settings were saved

Git config --global --list

You may want to use a different text editor such as Notepad++. You will need to download first.

git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' -multiInst -nosession"

You could also set Another Editor.

Now you are ready to create a Git repository. Create a folder where the repository will live and initializing it with the init command. This will create a hidden folder called .git where all the Git meta data for this repository is kept.

Git Init

Git Init

Then start to add files to that folder that can be later added to source control master branch.
For example, let’s add two files called:

‘test file.txt’ and another ‘test file.txt’.
and add text in the files and save.

If we use the git status command or gst command for short, (to get a list of all the changes we have made) we will see Git knows about two untracked files in the directory.

At this point, it’s good to know that Git has three main states that files can be in. They are modified, staged or committed. Modified means that there have been changes to the file and it has not been committed to the repository. When files are staged, this means that they have been modified and added, and will be included in the next commit. When files are committed, this means that the file is safely stored in the repository.

Git Status

Git Status

Now we will stage them by using the Add command to let Git know that there are files ready to be committed by using the git add . command. This will add all existing files to the index.

Git commit

Git Commit

You will notice the branch text and color is in cyan.

Cyan indicates that the branch matches the remote branch.

Green means the branch is ahead of its remote and is ready to push.

Red means that the branch is behind its remote branch.

Yellow means that the branch is both ahead and behind of its remote branch.

A branch could also be a combination of these colors.

These colors can be changed to one of the following colors: normal, black, red, green, yellow, blue, cyan, magenta, white
By using the command:

git config --global color.status.changed "blue normal bold"

By using the standard colors, this could make things easier to support others and for pair programming, to have everyone on the same page as to the color statuses.

Now that the initial source code has been committed to the master branch in Git, let’s see how to make changes going forward on that source code.

First, create a branch to work on. A branch has a name meaningful to you and the feature/fix you are working on. They are the place to do the work. To create a branch type:

git checkout –b hotfixUpdateTextInAnotherTestFile

New Branch

Create Branch

Now let’s open and edit one of the files.
For example edit some text in the ‘another test file.txt’ and save. If we use the gst command, we will see that this change has not yet been staged.

Git Status

Git Status

Then use the add command and the commit command:

Type: git add .
And: git commit –m “change to another test file”

Git Commit

Git Add & Commit

Git also allows modified and staged changes to be stashed. This is like putting the changes on a shelf, doing some other work now, and then getting them later. Then that original work can be reapplied / merged together. (Note: You could also make a new branch and do some work there, push the changes, and come back to the previous branch, pull the latest and merge, but a stash bypasses the push and pull to merge).

Let’s do a stash. We will simulate some work done by modifying a file in the directory.

Edit some text in the ‘test file.txt’ file. Save. Then use the gst command. You will see the modification in git.

Branch Stash

Git Status

Now enter git stash. This will set the branch back to this original state before the modifications. (Note: git add . before git stash is not necessary).

branch git statsh

Git Stash

Then you can do other work on this branch with the previous changes safely stored on the stack.

We can see the stash we made by using the command:

git stash list

(if you get end ‘[End]’ just press ‘Q’ to quit).

branch git stash list

Git Stash List

To retrieve the stashed modifications, use the command:

git stash apply

This puts the file back to its modified state.

branch git stash apply

Git Stash Apply

You can also specifically apply a stash by its specific number (0 in this example):
git stash apply stash@{0}
git stash apply stash@"{0}"

(Note: Windows for PowerShell will sometimes eat the brackets so if you type stash@{0} Git will only see stash@0 and will throw this error: ‘fatal: ambiguous argument ‘stash@’: unknown revision or path not in the working tree.’. Therefore, add double quotes around the brackets like this: Git stash apply stash@"{0}")

branch git stash apply zero

Git Stash Apply Stash Zero

You can also remove a stash by its specific number (0 in this example) with the command:

git stash drop stash@"{0}"

Also git stash clear will drop all stashes.

There is also the git commit -–amend command that lets staged changes to be added to the previous commit instead of committing as a new commit.

Other useful commands are: git show to show all the code in the current commit. An optional commit sha1 can be added behind that command.

Also to just see the filenames in a commit, use the command git show --name-only. An optional commit sha1 can be added behind that command.

The git log –- [filename] shows the commit history of the particular file.
To see details of what changed in the file in its history you could use gitk [filename]. This will display a GUI window of the file changes.
To see the changes between files in Powershell, use the git diff [filename].

If many commits of code were made on the branch, its possible to combine the work into a single commit with the following command:

git rebase –i

After the changes are complete it time to commit these changes to the master branch. After doing any more changes to the files, and adding and committing if needed, then run the following commands:

git checkout master
git merge hotfixUpdateTextInAnotherTestFile

git merge

Git Merge

The git checkout master switches the branch to the master branch and the git merge hotfixUpdateTextInAnotherTestFile merges the code from the hotfixUpdateTextInAnotherTestFile into the master branch. When the merge command is run you will notice that Git reports that it was a ‘Fast-forward’ merge. This means that Git simply moved the pointer forward to point master to the latest commit that was in the hotfixUpdateTextInAnotherTestFile branch. (Note: Since there was no other divergent work to merge together and it remained in the same state since creating the hotfix branch, Git did a fast-forward merge).

After the code is landed you can delete the hotfix branch since it’s no longer needed as the master branch contains the same code (master branch points to the same place). Delete the branch using this command:

git branch -d hotfixUpdateTextInAnotherTestFile

branch delete

Delete Branch

Of course code reviews before landing are the norm and highly recommended. However, since this example shows merging back to a local repository and was for showing Git commands, a code review might not make sense in this scenario.

Also, you may not have permission to directly update the master branch if it’s on a server. In addition code reviewers / maintainers will probably want to review your code before landing.

To facilitate this, many Git hosting sites support forking. When the branch is ready for code review, click the “Fork” button. Forking makes a copy of the repository and allows code changes without affecting the original project.

After making the fork, apply the code in the local branch (hotfixUpdateTextInAnotherTestFile) to the fork (the upstream or copy of the original repository) by the following commands:

git remote add hotFixfork RemoteBranchURL
git push -u hotFixfork hotfixUpdateTextInAnotherTestFile

For a full setup guide to fork and clone and keeping the fork up-to-date with master please see this guide.

After the work has been pushed, notify the maintainer/ project owner / code reviewer. Use a pull request and email the output of the following command to the code reviewer. There are other tools to use for code for review, such as Phabricator.

As an example you could use this command:

git request-pull master hotfixUpdateTextInAnotherTestFile

The output contains information where to pull the work from, where the work was originally branched from and a summary of the commit. If the code reviewer accepts the code changes, they would pull the changes into the original repository. This link has many more scenarios regarding contributing to a Git project.

In Git – Part 2 we will see Git in action with Visual Studio and Git extensions.

1 thought on “GIT – Part 1

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.