CSE 451-oriented git tutorial

git is a modern version control system for managing the sharing and versioning of your source code. git is a "distributed" version control system, as opposed to classical systems such as CVS and Subversion which are based on a single central repository. While distributed version control is very powerful, this tutorial will teach you to use git in a "client-server" fashion that mimics the classical version control systems that you may already be used to.

This tutorial assumes that you are using Linux, and assumes that your git repository is in the shared project directory that has been created for your group.

Tip

git has many, many more advanced features than are presented in this tutorial. If you'd like to learn about them, git has a comprehensive set of man pages (man 1 git or git --help <command>), as well as the online Git Community Book. Try these references first if you get unexpected output or error messages from git commands.

Committing to the repository

The commit and update process in git differs slightly from that of other version control systems that you may have used. To illustrate how it works, we'll make a minor change to one file and create a new file. Run the following commands from the top level of your repository (i.e. ~/cse451/os161/):

$ echo Hello >> CHANGES
$ echo newfile >> newfile

Now run the git status command and observe its output:

$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   CHANGES
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       newfile
no changes added to commit (use "git add" and/or "git commit -a")

This output shows two things: first, you must explicitly add new ("untracked") files to the repository before they can be committed (as is true in other version control systems), and second, you must explicitly stage your changes before they will be committed (unlike subversion, which will automatically commit all of your changes if you just run svn commit). To further illustrate this, run the git commit command:

$ git commit -m "Test commit."

This command will be a no-op: you should see the same output as from the git status command, ending in the same message: 'no changes added to commit (use "git add" and/or "git commit -a")'. To add your changes to the commit set, you must use the git add command on the changed files (whether they are new files or files already in the repository!):

$ git CHANGES
$ git add newfile
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   CHANGES
#       new file:   newfile

You can see that the change to the CHANGES file and the addition of newfile have now been staged for the commit. To commit all of the changes that you have staged, run git commit:

$ git commit -m "Test commit"
[master 41a5c0d] Test commit
2 files changed, 2 insertions(+), 0 deletions(-)
create mode 100644 newfile

Details

The -m argument to git commit is used to provide a commit message; if you forget to use it, then git will open a text editor for you to enter a commit message.

To make git behave more like subversion and automatically commit all of the changes you have made to files already in the repository (automatically commit all unstaged changes), use the -a flag with git commit. You may find, however, that the process of staging / unstaging changes is one of the most useful features of git: it allows you to make lots of changes to lots of files, but only commit the changes you want while leaving other files with in-progress changes uncommitted.

If you get a message like "file.c: needs merge" when you try to commit, then you have a conflict from a previous git pull that has not been resolved. See the Updating your local repository section below for more information about resolving conflicts.

However, at this point you have committed some changes, but your commit is not yet visible to the other users of the repository. git separates the notion of committing changes from the notion of "pushing" your update to the central repository. This can be useful for an individual developer that wants to make many changes to the code in many small logical commits before pushing all of them to the central repository, but for your CSE 451 projects you will probably just want to push after every commit.

To push your commits to the central repository, simply run git push:

$ git push
...
To /projects/instr/14sp/cse451/groups/X/os161/
   b482242..41a5c0d  master -> master

Note

If your push fails, it may be because you need to run a git pull to update your repository first (and potentially resolve conflicts) before pushing your new commit. See Updating your local repository below.

Details

If you ever run the git status command and see the output "Your branch is ahead of 'origin/master' by N commits", then this means that you have local commits that have not been pushed to the repository yet.

Reminder

Remember to push your commits! If you are not used to using git, then this may be the hardest thing to get used to. Try not to forget to do this, or your group members will wonder why it seems like you're not doing any work.

Updating your local repository

To update your local copy of the repository with commits that other members of your group have made, simply use the git pull command:

$ git pull
...
CHANGES               |    1 +
newfile               |    1 +
2 files changed, 2 insertions(+), 0 deletions(-)
create mode 100644 newfile

Note

git will not allow you to pull updates into your repository while you have unstaged changes. Therefore, you must stage (git add) and commit all of your changes before pulling. If you have changes that you don't want to make visible to your group yet (because they cause the build to break, for instance) but you still want to update your local repository, you can just commit your changes, do not push them yet, and pull the updates. Then, when your changes are ready, you can commit again and then push to the central repository.

As with any version control system, pulling updates from the central repository may cause conflicts with changes that you have committed locally. Pay attention to the output from your pull command for instructions to resolve conflicts; generally, resolving a conflict entails opening up the conflicted file(s) in your editor, finding the conflicts (surrounded by the text markers <<<<<<<, =======, and >>>>>>>), fixing the conflicting code, staging the changes (git add) and committing and pushing again. For more information about resolving conflicts, the github user manual has a useful webpage.


If you find any bugs in this tutorial, please e-mail them to the CSE 451 TAs. If you have any problems while using git that are not covered in this tutorial, try the man pages (man 1 git and git --help <command>) and the Git Community Book, and then contact the TAs. If you find any useful features of git that aren't mentioned here, post them to the class discussion board.

Author: Peter Hornyack (pjh@cs)

Edited by: Sunjay Cauligi (sunjayc@cs)