Introduction to Git

This introduction has been written for the ‘Operating Systems’ lecture held at the KIT in winter term 2009/2010 and uses the default paths and additional documentation used there. That means if you want to use it for another purpose you may do so but you probably have to adjust the paths to your local environment.

This tutorial assumes that you are working with a partner and you both have accounts for the ATIS computer pool. If you want to work on your own computer you should use Linux, Mac OS or another *NIX operating system (Windows users can use a VM with Linux on top), should have a SSH client installed and know how you can log into your ATIS account via SSH (have a look at the ATIS documentation).

Please note that if you use Git submitting your solution differs from the procedure described in Assignment 1.

To make it easier to explain we will call the persons involved Alice and Bob.

Setup

Step 1: Set up your environment

If you want to use the ATIS machines (which come with pre-compiled cross-compiler toolchain and ready to use Git) you can skip this step an go directly to step 2.

If you want to work on your own computer (Linux, Mac OS and other *NIXes only) you have to compile the cross-compiler toolchain and install System/161 as described in the howto (please note the patches mentioned in the Forum). Also if you don't already have Git installed you have to do so using your package manager (preferred) or getting it directly from the Git website. For example if you use Ubuntu then open a command line and type sudo apt-get install git-core git-doc git-gui gitk

Step 2: Set up your ATIS accounts

If you want to work on the ATIS machines you have to set up your ATIS account as described in section 1 ‘Introduction’ of Assignment 0.

Step 3: Configure Git

Every change you make on the repository will mention your name and email address therefore it's a good idea to tell Git what they are

git config --global user.name "Alice Smith"
git config --global user.email alice@example.com

Also you might want to use a different text editor than the default (vi in most cases), it should be a non-GUI one though. Personally I prefer nano because it's rather intuitive:

git config --global core.editor nano

If you want to use git gui which provides a graphical front end for the tasks most used you will notice that the German translation is not very helpful and just causes confusion. To switch to the English language you can define an alias gg (short for Git Gui) which you can use everywhere you'd normally use git gui

  1. Find out how your current LANG variable is set

    echo $LANG

  2. This should give you something like de_DE.UTF-8 (it can be a little bit different though). Now you replace the lower case "de" by "en" and the upper case "DE" by "US" and add it to your ~/.bashrc file

    echo "alias gg='LANG=en_US.UTF-8 git gui'" >> ~/.bashrc

The following steps have to be done for every assignment therefore all folders have been named ‘asstX-src’ or similar, you have to replace X by the current assignment number.

Step 4: The first repository

Only Alice has to do this step.

  1. Download and unpack the source code for the current assignment as described in section 2.1 of Assignment 0 (if you've already configured compiled or even changed the source that doesn't harm much).

  2. Download the .gitignore file from my website into your asstX-src directory (it makes sure that the compiled binaries aren't included in the repository)

    cd ~/os/asstX-src/
    wget http://os-tut.nhng.de/git-intro/.gitignore

    Don't worry if you can't see the file, files starting with a dot are hidden files in *NIX

  3. Git thinks empty folders are unimportant and just ignores them. Unfortunately the config script of OS/161 has a different opinion. We work around this by creating a placebo file:

    echo "# This file is here to make sure Git does keep track of this directory" > ~/os/asstX-src/kern/compile/.empty

  4. Now we can initialize the repository:

    cd ~/os/asstX-src/
    git init

  5. At this point we have the repository but Git doesn't keep track of the files in the directory yet, we tell it to do that by executing

    git add .
    git commit

    Then the editor you specified will open and you have to enter your first commit message (a commit message describes the changes you have done between the previous and the current commit) which could be something like ‘Import asstX sources’

    After you saved the commit message and closed the editor the git status command should say ‘nothing to commit (working directory clean)’

This is it, the repository is ready to go but unfortunately Bob can't access it so we have to publish it.

Step 5: Publish the repository

Only Alice has to do this step.

  1. Clone a bare version (containing only the internal data structures used by Git) of your repository into another folder:

    cd ~/os/
    git clone --bare asstX-src asstX.git

  2. Make a new directory on your ATIS account to contain the shared Git repositories and set the right permissions so your partner can access it (this only has to be done once).

    Unfortunately this also means that every other student with an ATIS account can read your repository but they can't write to it and they can't read other directories or files in your home directory. To make sure there are no other files or directories which inadvertently have read or even write permissions for other students you should execute chmod -R go-rwx ~/

    mkdir ~/git/
    chmod g+X ~/ ~/git/

  3. Now move the cloned copy of your repository to this directory:

    • If you're working on a ATIS machine you can do this by executing mv ~/os/asstX.git ~/git/

    • If you're working on your own computer upload it using scp -r ~/os/asstX.git s_alice@i08fs1.ira.uka.de:git/

  4. We then need to set the proper permissions to the repository on your ATIS account

    chmod -R o=,g-w,g+rX ~/git/asstX.git/

  5. To make sure group permissions are set for new objects created if you push to that repository, download a prepared hook script from my website to your ATIS account

    wget http://os-tut.nhng.de/git-intro/post-update -O ~/git/asstX.git/hooks/post-update
    chmod u+x ~/git/asstX.git/hooks/post-update

  6. Next we tell our local repository to push to the shared one by default

    • If you work on the ATIS machines execute

      cd ~/os/asstX-src/
      git remote add origin $HOME/git/asstX.git/

    • If you work on your own computer execute

      cd ~/os/asstX-src/
      git remote add origin ssh://s_alice@i08fs1.ira.uka.de/~/git/asstX.git/

    In both cases execute

    cd ~/os/asstX-src/
    git config branch.master.remote origin
    git config branch.master.merge refs/heads/master

Step 6: Clone the repository

Only Bob has to do this step.

  1. Make a new directory on your ATIS account to contain the shared Git repositories and set the right permissions so your partner can access it (this only has to be done once).

    Unfortunately this also means that every other student with an ATIS account can read your repository but they can't write to it and they can't read other directories or files in your home directory. To make sure there are no other files or directories which inadvertently have read or even write permissions for other students you should execute chmod -R go-rwx ~/

    mkdir ~/git/
    chmod g+X ~/ ~/git/

  2. Clone Alice's published repository into this folder on your ATIS account

    cd ~/git/
    git clone --bare /home/stud/s_alice/git/asstX.git/ asstX.git

  3. We then need to set the proper permissions to the repository on your ATIS account

    chmod -R o=,g-w,g+rX ~/git/asstX.git/

  4. To make sure group permissions are set for new objects created if you push to that repository, download a prepared hook script from my website to your ATIS account

    wget http://os-tut.nhng.de/git-intro/post-update -O ~/git/asstX.git/hooks/post-update
    chmod u+x ~/git/asstX.git/hooks/post-update

  5. If you already have unpacked or even configured, compiled or changed the source code for assignment X move it to a new directory for backup (if you didn't change anything you might also just delete it)

    mv ~/os/asstX-src ~/os/asstX-src.old

  6. Now clone your published repository to the machine you want to work on

    • If you work on the ATIS machines

      cd ~/os/
      git clone ~/git/asstX.git/ asstX-src

    • If you work on your own computer

      cd ~/os/
      git clone ssh://s_bob@i08fs1.ira.uka.de/~/git/asstX.git/ asstX-src

Step 7: Introduce your repositories to each other

To make things more convenient we assign a name to each others repository. Alice will add a short hand for Bob's repository and Bob will add a short hand for Alice's repository

Bob has to do the same but he replaces alice with bob and vice versa.

Step 8: Configure & Compile

Finally Alice and Bob can both configure and compile the source code as described from step 2.2 on in Assignment 0


Workflow

Now I'll describe a basic workflow which should fit quite well for the programming assignments but you'll probably adjust it to your own style and thinking. On the Git documentation site you can find ideas how you could do that. Apart from the git manual pages which you can view using git help <command name> this is also the place where you can find out how to do more complex things than mentioned here.

I will always describe the steps for the command line and the Git GUI which you can run executing git gui or if you have added the alias in step 3 of the setup gg in your source directory (~/os/asstX-src/).

I personally use a mix of GUI and command line because the GUI is good when making commits and reviewing the history but push, pull etc. are somewhat to many steps if you only want to use the default options (which will do in most cases).

Make changes to the source

You change the source code in an editor and when you think you've completed a logical step you commit your changes to the repository. Commiting means that the repository checks which files have changed and saves those changes in its internal data structures. The basic rule is "commit often" although each commit should contain a logical change like "fix bug 42", "synchronize access to foo" or "rough implementation of bar()".

The first difference you will notice if you've already used another VCS like SVN, CVS or Mercurial is that Git has a little step between changing the sources and commiting the changes called staging. Git doesn't just commit any changes you've made to any file but you have to specify which changes you want to include in the commit.

Command Line
  1. Make your changes using a text editor (or Eclipse or something else)
  2. Review the changes you've made
    git status
  3. Stage the changes in the files you want to commit using
    git add <files>
    If you want to stage all files in a directory you can simply specify that directory instead of the files
  4. Commit the staged changes (attention, if you change files after you stage them you have to stage them again to include those changes)
    git commit
    Now a text editor will open where you have to specify a commit message which describes the changes in a short sentence (if you want to be more verbose give a summary on the first line then a blank line and a more detailed description on the following lines). When you finished editing save the commit message and exit the editor then your changes will be committed.
GUI
  1. Make your changes using a text editor (or Eclipse or something else)
  2. Open Git GUI (if it's already opened you may have to refresh it pressing F5)
  3. On the top left you will see files that have unstaged changes and if you click on the name you will see the changes
  4. Stage the changes you want to commit either clicking the icon in front of the file name (which stages all changes in the file) or doing a right click on the change you want to add in the top right area and selecting "Stage Hunk For Commit"
  5. Write your commit message into the bottom right area. The commit message should describe the changes in a short sentence (if you want to be more verbose give a summary on the first line then a blank line and a more detailed description on the following lines)
  6. Click on the "Commit" button

Publish your changes

After you've made some commits you probably want to share the changes you've made with your partner. This is done by transferring the commits to your published repository

Command Line

git push

GUI
  1. Click the "Push" button
  2. Check that "origin" is selected under the section "Destination Repository" (this should be the default)
  3. Click "Push"

Import published changes

Once your partner has published some commits you probably want to import them to your repository. In most cases those changes can be imported without problems but sometimes (e. g. when you both changed the same function) Git can't do the work automatically then you have to sort it out manually.

Command Line
  1. git pull <partner> (e. g. git pull bob)
  2. If Git prints the message "Automatic merge failed; fix conflicts and then commit the result." it couldn't do an automatic merge and you have to do the following steps if it doesn't everything is all right and you're done.
  3. Execute git status to see which files are unmerged
  4. Git will leave markers in the files it couldn't merge which look something like this
    <<<<<<< HEAD:Test
    foo
    =======
    bar
    >>>>>>> 74331873efa41766812731d6361659017658cac2:Test

    With the upper section containing the contents of your repository and the lower one the contents of the repository you tried to import from. Modify the file with your editor so it contains the desired form and remove the markers
  5. Use git add <file> to tell Git you've resolved the merge conflict
  6. Repeat the previous three steps until git status doesn't show unmerged files any more
  7. Commit the merge using git commit. Git will craft a commit message for you, normally this should be sufficient so no need to edit it just save and close the editor.
GUI
  1. Get the commits from your partner selecting "Remote → Fetch from → <partner>" from the menu
  2. Now we do have the commits but Git didn't merge them yet. In order to do that select "Merge → Local Merge…" in the opened dialogue select "<partner>/master" from the list and click "Merge"
  3. If the bar on the bottom of the dialogue now appearing turns green everything is all right and you're done, if it turns red Git couldn't do an automatic merge and you have to do the following steps
  4. Git GUI will show the files which contain conflicts and are therefore unmerged in the upper left area. Git will leave markers in the files it couldn't merge which look something like this
    <<<<<<< HEAD:Test
    foo
    =======
    bar
    >>>>>>> 74331873efa41766812731d6361659017658cac2:Test

    With the upper section containing the contents of your repository and the lower one the contents of the repository you tried to import from. Modify the file with your editor so it contains the desired form and remove the markers
  5. Press F5 to refresh the GUI and click on the icon in front of the file you just edited to tell Git you resolved the conflicts in it.
  6. Repeat the previous two steps until there are no more files with conflicts in it (the upper left area is empty)
  7. Git has crafted a commit message which you can see in the bottom right area. Normally it's okay so just click "Commit"

Submit your solution

Once you're satisfied with your solution (or you're under deadline pressure) you have to create a tarball. If you follow the instructions on section 10 of Assignment 1 the whole repository including the whole history of changes will be included (which will be huge), fortunately Git provides a solution for this.

  1. Commit your latest changes, uncommitted changes will not be included in the tarball
  2. Import changes from your partner, changes not imported will not be included in the tarball
  3. Execute
    cd ~/os/asstX-src/
    git archive HEAD | gzip > ~/os/asstX-solution.tar.gz
  4. Maybe you want to verify the tarball
    1. Unpack it to a new directory
      mkdir ~/os/asstX-solution
      cd ~/os/asstX-solution
      tar -xzf ~/os/asstX-solution.tar.gz
    2. Configure and build it as described in section 5 of Assignment 1 (except that you replace ~/os/asstX-src with ~/os/asstX-solution)
    3. Test if it works the way you want it to work
  5. Submit the tarball as described in section 10.1 of Assignment 1

Valid XHTML 1.0 Strict