Using git

git is version control software. It is useful for managing code projects, particularly projects with partners (for lone projects rcs may be sufficient).

This guide provides instructions for using git for CS lab and project work with partners. It includes setup instructions for CS31 and CS35 students using git repos hosted on Swarthmore's GitHub server, and also setup instructions for students in upper-level classes who want to create their own git repos on the CS system. It also covers git commands and tools, troubleshooting errors, some advanced features, and links to other git resources.

Contents:

Git Overview
You will either use an existing remote master git repository (repo) or create a remote master repository on our system for your project. You and your partner(s) each checkout (clone) a private local copy of the remote master repo. You then each add and commit changes to your local private cloned copies. Local changes can be shared with your partner by pushing them to the master repo. Your partner will then pull your pushed changes from the remote master into their local repo. Git automatically merges changes pulled from the master into the local repo's files. Any changes committed to a git repo can be recovered, and a version of files from any commit in the commit history can be recovered: commit often as you work on a project (and to push fairly often too).
Setup for using repos on Swarthmore GitHub Enterprise
These are instructions for using git repos hosted on Swarthmore's GitHub Enterpreise server. Students in CS31 and CS35 should follow these steps to clone their lab git repos.

Note: if you haven't already done so, make sure you complete the one time config steps for using the Swarthmore GitHub before proceeding: one-time Swarthmore github configuration steps

Accessing Swarthmore GitHub

The web address is https://github.swarthmore.edu. You should be able to log in with your typical Swarthmore credentials (the same username / password you use for email). Upon logging in, you should see a welcome page that lists the repositories you currently own.

For repositories created by your professor for CS labs, we'll be using a feature of GitHub called "organizations", which allows us to control everything for the course. The organization to use will have a name something like CSnum-semester, for example use the one named CS31-f15 for the Fall'15 semester of CS31. From the main GitHub page, select the organization you want to use. (or you can jump directly to the organization link, whose url looks something like https://github.swarthmore.edu/CS31-f15)

On the organization page, you see a list of repositories that you can access. The repositories will be named according to what they contain and which users can access them. For example, suppose two teammates (Grace Hopper, ghopper1, and Alan Turing, aturnin1) are working together. When Grace accesses the organization, she would expect to see:

Cloning a local copy of the repository

You and your partner will both create a private local copy ("clone") of your shared remote master repo (ex. Lab2-ghopper1-aturing1). You each will edit and commit changes locally and push and pull changes back to the remote repo on GitHub to share them with each other.
  1. On GitHub, click on your and your partner's lab repository, and it'll take you to a page that lists its contents (and many other useful things). One the lower right hand side, you'll see some text that says "You can clone with HTTPS, SSH, or Subversion". Click the "SSH" link to list the link you will use to clone.
  2. On the CS machine, first cd into your cs31/labs subdirectory:
      cd
      cd cs31/labs
    
    then run git clone [URL] to locally clone the repository, where [URL] is the SSH URL given to you by GitHub. For example, Grace might run the following command to clone her and Alan's lab2 repo:
      git clone git@github.swarthmore.edu:CS31-f15/Lab2-ghopper1-aturing1.git
    
  3. Then cd into your local repo directory and access the files there
      cd Lab2-ghopper1-aturing1
      ls
      Makefile  README.md lab2.c
    

If you get authentication errors, make sure you've uploaded an SSH key to your GitHub account. (See: one-time configuration steps)

Using your shared repo

You now have a private local copy of a git repo. All changes, additions, deletions, to this project can be done with git commands that will push and pull changes from the remote master. Commands for using a git repo

Setup for creating and using your own master repo on our system
These are directions for creating your own git repo on the CS system. This is useful for students in upper-level CS courses. You can alternatively create a new repo on the Swarthmore GitHub Enterprise server. If you do this, make sure to create a private repo that only you and your partner can share; select a "make this repo private" option to do so.

In setting up a repo on our stystem, the first step is for one of you to create a bare master repo for your shared project, setting ACLs so that you both can read and write to it. You and your partner(s) can then clone local copies into your private subdirectories. Follow the detailed directions for doing this on this page:
Creating and cloning a remote master repo on the CS system

Commands for using a git repo
After cloning a remote master repo, you and your partner will each work in your own local private copies of the repo. You can add and commit changes to your private copy as you go, and choose when to push your change to the remote master repo that your partner can then pull from the remote master into their copy.

An example of a sequence of common git commands:

 # from within your local private git repo
 cd ~/private/cs31/labs/lab01-me-partner/

 # check the status of your repo
 $ git status

 # see the changes to the file (compared to your last local commit):
 $ git diff blah.c

 # add a new file to the repo on the next commit:
 $ cp ~/private/foo.c .
 $ git add foo.c
 # or add new changes to an existing repo file to the next commit:  
 $ vi blah.c      # edit with your favorite editor
 $ git add blah.c  

 # commit your changes (adds and deletes) to your local repository:
 $ git commit

 # push committed changes from your local to the remote master repository
 #  note: the first time you push, you may need to do:
 #        git push origin master
 $ git push

 # your partner can now pull your changes from the remote into their local:
 $ git pull

Some notes about these commands:

.gitignore

It is useful to add a .gitignore file to your repo. It tells git automatically ignore adding certain files or file types to the repo, such as .o and executable files and editor backup files (like vim .swp files). This way if you do a git add git doesn't try to add all kinds of kooky files to the repo. Here is an example .gitignore file for a C program that build an executable file named myprog:
*.o
myprog
*.swp
You add a .gitignore file to a git repo just like you add any other file:
git add .gitignore
git commit
git push

Common git commands and git tools

Common commands:

git help    # list common git commands  git help --all lists all commands
git add     # add changes or new files to the next commit 
git rm      # remove a file at the next commit
git commit  # commit your changes to your local repository
git push    # push your committed changes to the remote master repository
            # (note: the first time you may have to do: push origin master
git pull    # pull changes pushed to remote master into your local copy 
            # (git will try to merge changes into your copy)
git mv      # move a repo file
git diff    # see a diff between a file(s) and latest commit (local repo)
git diff master origin/master  # diff between your copy and master's
git status  # see what has changed between your copy and the master version
git branch -a # see all the branches (likely only master)

git tools:


Troubleshooting


Advanced git Features

git Branches

For CS course projects it is likely sufficient for you and your partner(s) to clone versions of a single master repository and then push and pull changes to it. For larger and longer existing projects, you may want to use git's support for creating separate branches of your repository. For example, different branches could be associated with different users or with different features, and users can push, pull, and merge changes from branch to branch.

Here are some basics for useing branches, see professor Danner's git wiki with more detailed information and help

# create a new branch named mybranch and push it to the master repo:
git checkout -b mybranch
git push -u origin:mybranch

# list the current branch of your copy of the repo:
git branch

# switch to different branch: git checkout branchname
git checkout master
git checkout mybranch


# to merge changes from mybranch into the master branch
git checkout master
git merge mybranch

# if merge conflicts
git add   any files that needed to be fixed up from the merge conflict
git commit

# if you want to push your new version of master that is merged
# with mybranch to the remote:
git push 
# if git push fails try 
git push origin master   

# if you want to undo a merge  
# (and best to undo before making local changes, commits, pushes, etc.)
git reset --merge ORIG_HEAD

git tags

You likely won't need to use tags for course projects, but they are handy for long-lived projects, particularly for code that you may want to release. A tag is a way to name a snapshot of the repository. It is often useful for code releases and for tagging big version changes to code. A tag is like a static branch (you cannot update the tag'ed version, but you can check it out just like any branch).

Here are some tag commands:

# list all current tags associated with a repo
git tag -l

# create a new tag named v1.0 with a tag message (optional)
# and share a tag: push the tag to the origin to share it:
git tag -a v1.0 -m "initial version"
git push origin v1.0

# checking out a specific tagged version of the code
# (checkout v1.0 of code into a local repo named version1)"
git checkout -b version1 v1.0

# to list other data along with the commit for a specific tag
# (this will show the commit number, date and who created the tag):
git show v1.0