Getting by with Git

Contents

  1. Set up a Repository
    1. Global Settings
    2. Making a Repository
  2. Basic Usage
    1. Check out Code
    2. Check in Code
    3. Misc File Operations
  3. Working with Others
  4. A Note on Commit Messages

For this document, assume $proj is defined as something like:

proj=my_awesome_project
host=grencez@myserver.net

The following instructions show how to set up a git repository ${host}:~/repo/${proj}.git and use a local copy on your own machine ~/code/${proj}.

1. Set up a Repository

1.1. Global Settings

It is important for people to know who you are when committing changes. Create a file ~/.gitconfig (by typing gedit ~/.gitconfig in a terminal) which contains appropriate lines:

[user]
  name = Alex Klinkhamer
  email = grencez@youknowthedomain.edu
[push]
  default = matching

1.2. Making a Repository

Code shouldn't just be stored on one machine because the hard drive may crash or we may have multiple work machines. Therefore, we should make a repository on a server that all of our machines can access.

ssh $host
mkdir -p ~/repo/${proj}.git
cd ~/repo/${proj}.git

Private. If this is a project just for you, then all we need to do is initialize the repository.

git init --bare

Public. If this is a project should be shared with everyone, we must allow people to get to the repository and make it readable and writable by everyone.

chmod a+x ~/ ~/repo
git init --bare --shared=0666

Shared with Group. Usually a public repository isn't the greatest idea because anyone on the machine can mess with your code. If you have the luxury of having a group containing all members, we can restrict access to the group. Let it be defined as group=my_group.

chmod a+x ~/ ~/repo
chgrp $group .
chmod g+rwxs .
git --bare init --shared=group

2. Basic Usage

This section describes the minimal amount of knowledge you need to use git. Note that some commands (git pull and git push) assume some default values which were set by git clone.

2.1. Check out Code

Back on your own machine, get a copy of the repository using git clone.

mkdir -p ~/code
cd ~/code
git clone ${host}:~/repo/${proj}.git
cd $proj

If you're a member of someone else's project (say, friend=alex), the clone command will need to reference their home directory on the server:

git clone ${host}:~${friend}/repo/${proj}.git

After this initial clone, it is simple to pull changes other people have made.

git pull

2.2. Check in Code

To add a new file to version control:

git add $file

To see what files have been added, modified, or are not tracked by git, use the status command.

git status

To commit all of your changes:

git commit -a

This will open an editor so you can explain your changes in a commit message. The editor is determined by the $EDITOR environment variable, which is probably nano by default... pretty easy to use. If you only have a short message and don't want to work in an editor, the message may be specified directly.

git commit -a -m 'Fix size_t comparison warnings'

One can also change the most recent commit or its message ( ONLY DO THIS IF THE COMMIT HAS NOT BEEN PUSHED).

git commit -a --amend

Finally, push your changes to the repository, otherwise nobody will see them!

git push origin master

If you're not pushing to an empty repository, the following shorthand does the same thing.

git push

If you still need arguments, you can set the defaults manually with git-config.

 git config branch.master.merge refs/heads/master
 git config branch.master.remote origin

To see other options:

 git config -l

To edit other options:

 git config -e

2.3. Misc File Operations

Add file, remove file, move file, or discard changes.

git add new-file.c
git rm unwanted-file.c
git mv old-file.c new-file.c
git checkout HEAD file-with-changes.c

If you previously added a file and want to remove it, you must be rather forceful.

git rm -f --cached unwanted-file.c

See previous commit messages.

git log

3. Working with Others

The above instructions are fine for working by yourself, but what about when others are making changes concurrently?

If git push complains about your copy not being up to date, you'll need to do a git pull. However, there could be conflicts! ( TODO: I don't have enough experience to give advice here.)

If you have uncommitted changes and wish to pull new changes from a teammate, first stash your changes, then have them automatically merged. (Merges don't always go cleanly though, so copy your changes elsewhere just in case.)

git stash save
git pull
git stash pop

4. A Note on Commit Messages

Most commits do warrant some description. Imagine if your changes broke something, and someone else (or ``future you'') is tasked with fixing it. Without a meaningful commit message to read, that person doesn't know your intent in making those original changes, and their change may break something else! (Side note: Use tests to protect your code from others.)

A commit message should be formatted with the first line being a short description (cut off at 50 characters), followed by an empty line, and then more detailed explanation. For example, this is one of mine:

Add normal mapping to raytracer

1. In the raytraced version, one can now specify a normal map in
   object coordinates to give the illusion of a more complex surface.
  a. material.c/h  map_normal_texture()
  a. wavefront-file.c  readin_wavefront()
  a. raytrace.c  fill_pixel()
     - This function is getting too complicated...

2. When determining the normal of the track's surface, be sure the damn
   thing is normalized! This only affects tracks without vertex normals.
  b. motion.c  apply_track_gravity()

3. Clean up some parse code with the addition of a new macro.
  a. util.h  AccepTok()
  c. wavefront-file.c
    + readin_wavefront()
    + readin_materials()
  c. dynamic-setup.c  readin_Track()

This is just my style, but I describe changes in order of priority and hierarchically by: intent (number prefix), file (letter prefix), function or class (`+' prefix, or on same line if there's room), and extra description (`-' prefix). The letter prefixes signify the type of change: c means change code, b means bug fix, a means add code (new functionality), r means remove code, and d means comment/documentation changes (if the file also contains code). This format works pretty well, though the letters may be a bit pedantic (former colleagues used a `*' prefix instead).