Git is an open-source version control system. It was designed and developed by Linus Torvalds (creator of the Linux kernel) and is the most popular version control system to date.
There are several reasons to use Git (or version control in general). We will just list a few reasons:
Grace already has Git installed. If you want Git on your local machine, you can always Google how to do so. ☺
The first thing you'll want to do is to configure your name and email on Git. Git needs your identity to document the contributor whenever there is a change to the code. The two commands are as follows:
$ git config --global user.name "Billy Programmer"
$ git config --global user.email "bprogrammer123@terpmail.umd.edu"
To turn a project into a Git repository, go inside the project folder and type the command
$ git init
to create a new Git repository. A folder to track history will be created, although there will be no other changes to your repository. If you want to clone an existing Git repository and you know the location of the respository, you can easily make a copy of the repository into your current directory:
$ git clone bprogrammer@linux.grace.umd.edu:~/216/project1
So if we wanted to do Project 1 under version control, we would want to simply convert it into a Git repository after copying over the files.
$ cp -r ~/216public/projects/project1 ~/216
$ cd ~/216/project1
$ git init
In a Git repository, changes to your code are marked by commits, snapshots of the changes to your code since your previous commit. You need to manually specify which files will have their changes marked in the next commit. This is known as staging your files. Continuing off the Project 1 example, all of the test files are not tracked yet. If we wanted to stage all of them we could do the following command
$ git add -A
to stage all of the relevant files. To commit the changes, we do
$ git commit
and type in a message to go along with the commit, documenting the changes made for the current commit. You can also stage files one by one by adding the file as an argument when staging. Committing has an option to quickly write a commit message when making the commit.
$ nano grades.c
...
$ git add grades.c
$ git commit -m "created grades.c file"
In a normal Git workflow, you want to stage any files that you have made changes to (git add
) and then commit the changes when you reach a small milestone (git commit
). Remember to commit early and often. Commits are inexpensive to make and are an excellent example of incremental code development. If you make commits that track small, isolated changes, fixing bugs can be easier since you have a good reference to locate possible bug locations.
Git has a feature called branching where you can have a version of your code diverge from your main code in order to try out new features or experiment with your project without the risk of breaking functionality in the main code. If you like the changes made to the divergent branch, you can always merge the two branches back together. In order to support good incremental code development, you should create a new branch for every new feature, and code on the respective branch. Once you have verified that the branch has working code, you merge it back to the master branch. That way, your main code branch will always have clean, working code.
If we wanted to create a feature in the grades calculator that calculates the mean and standard deviation, we might want to create a branch called "statistics." To create that branch we want the command
$ git branch statistics
to generate the branch with the name "statistics." To move into that branch, we use the command
$ git checkout statistics
and continue coding normally. One we are done implementing and verifying the feature, we move back to our master branch and merge the branches.
$ git checkout master
$ git merge statistics
After the merge, any changes you made in the statistics branch will be present in your master branch.
If you want to check with files have been changed since the last commit, or if you want to see new files or files staged for commit, you can use
$ git status
to check the status of your repository.
To check the line-by-line changes you've made since your last commit, use the following command:
$ git diff
To check the commit history use
$ git log
To create a commit that undos the changes of the latest commit you can revert a commit.
$ git revert HEAD
You can specify how many commits to reverting by including the hash or some sort of identification of the commit to which you want to revert. For example, the following command makes a commit that undos the changes of the previous two commits:
$ git revert HEAD^
To reset your repository to its state when you made your latest commit, you can do the following:
$ git reset --hard HEAD
If you want to reset only a single file to its state since the last commit without touching other modified files, you can specify the specific as an argument. The following example resets grades.c
to its state since the last commit.
$ git reset grades.c
If you accidentally git add
ed a file that you do not want to be staged for commit, you can easily unstage it. Note that this does not change the contents of the file. All it does it exclude it from being included in your next commit. This command is essentially the opposite of git add
. In the next example, grades.c
is unstaged, so when you commit, any changes made to that file will not be recorded.
$ reset grades.c
You may have heard of GitHub before and are wondering about its relation to Git. GitHub is an online hosting service for Git repositories. GitHub keeps the code it hosts open for the public to see, which is why this tutorial did not cover GitHub and remote repositories. However, if you are interested in working on your own projects outside of class, GitHub is a great resource use with your project.