Working with a Git Repository

This guide provides instructions for using git for CS lab and project work both with and without partners. It includes setup instructions for using git repos hosted on Swarthmore’s GitHub Enterprise server, available to all Swarthmore students and faculty. It also covers git commands and tools, troubleshooting errors, and links to other git resources.

This guide assumes that you have already followed the first time setup instructions. Read and complete the steps on that page first.

Using GitHub to Clone a Repository

Most assignments start with cloning a remote repository from Github Enterprise.

Cloning a remote repo makes a local repo that is a linked copy of the one on GitHub. You can then make modifications to the local copy and eventually propogate the changes back to the remote repo.

Initially, each remote assignment repository contains a copy of the starter code. To complete an assignment, you must clone the remote repository, make changes to your local copy, and send them back to the remote version. The instructor will then pull your lab solution from the remote repo at the due date of the assignment.

The following sections step through cloning a remote repo for an assignment.

Accessing Remote Course Repos

For repositories created by professor for CS labs, we use organizations within GitHub. Organizations allow faculty/staff to control elements of the course including standard permissions for each repo. The organization to use will have a name like CS<num>-<semester>, e.g., CS35-S25 for the Spring 2025 semester of CS35.

From here on, we will follow an example CS-Example-F26 organization and a lab-example assignment repository.

From the main GitHub page, select the organization you want to use.

github select org
github org dropdown

You can also jump directly to the organization URL. For CS-Example-F26, the link looks like https://github.swarthmore.edu/CS-Example-F26. Your instructor should provide a link to your course org from the course or lab assignment webpages.

On the organization page, you’ll 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. Normally, repos are named by assignment number and will contain your user ID and the IDs of any of your partners. Suppose a student named Grace Hopper is trying to find her lab-example assignment repository. When Grace accesses the organization, she would see the following repository:

  • lab-example-ghopper1: This is the remote remote repository for Grace’s lab-example solution that only she can access.

Cloning a Local Copy of the Repository

You (and your partner, if you have one) will create a private local copy, or clone, of your remote main repo. You can then view and edit the files locally.

Let’s walk through the steps to clone a repo using an example lab-example repository.

  1. On GitHub, click on your lab repository, and it’ll take you to a page that lists its contents (and many other useful things). On the right hand side, you’ll see a buttone labeled "Code". Click on the button and click the "SSH" link to list the link you will use to clone.

    github code link
    github ssh clone link
  2. On the CS machine, open a terminal window. If you don’t already have a directory to store your classwork and local repos in, create one. E.g., if you are taking CS31, then make sure you have a cs31/labs directory to put your lab repositories in. For this example, we will use cs-example/labs.

    Information on creating and navigating directories can be found at this link.
  3. cd into your lab work directory:

    [~]$ cd
    [~]$ cd cs-example/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 Hopper might run the following command to clone her lab-example repo:

    [labs]$ git clone git@github.swarthmore.edu:CS-example-F26/lab-example-ghopper1.git
  4. Then cd into your local repo directory and access the files there. Note, you will have to use the correct name of the repo you just cloned (you are not ghopper1!)

    [labs]$ cd lab-example-ghopper1
    [lab2]$ ls
    README.md name_year.txt

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

You now have a private local copy of a git repo. All changes, additions, and deletions will initially only happen to the local repo. You can send changes to the remote repo with git commands covered in the next section.

Be sure to send changes to GitHub before the lab due date. The copy on GitHub is the only copy graders/staff can see.

Add-Commit-Push

git has a lot of commands and a lot of features. But to submit assignments, we’ll learn three basic commands for recording changes and submitting your work to the GitHub server: add, commit, push.

How Git Tracks Changes

In a repo, git tracks the history of a project with commits.

A commit is a particular version of the code that a developer has saved and can refer back to using various git commands.

To submit work on a CS assignment, you will need to make (many) commits on your local repo, and then send them back to the remote repo on GitHub.

git add

Following the lab-example example, suppose you have a file name_year.txt that you edited to complete part of your assignment. In order to submit this file to the GitHub server, the first step is to run the command:

git add name_year.txt

The git add command informs git that you wish for changes to this file to be recorded in the next commit. You will need to use git add to submit newly created files as well as files that you previously commited but then modified.

Adding Multiple Files

It is possible to add multiple files at once. Here are some examples:

git add foo.c blah.c  # add two specified files

git add *.c           # add all files with .c suffix

git add -u            # add all files that have been updated

git add .             # add all files except those in the .gitignore (be
                      # careful about adding secret files like auth tokens!)

git commit

The git commit command records all the changes to recently git add ed files to a local copy of your git history. When making a commit you must provide a descriptive message about the changes since the last commit.

git commit -m "Add name and class year to name_year.txt"

The -m "message" can contain any message you want, but a short descriptive message is best. Note that in the git commit command, there is no mention of what files to commit; files are chosen by the git add step.

git will only commit files that have been added with git add since the last commit.

git push

The git commit command only records your changes locally. To share your code with your partner, instructor, or grader, you must send your changes to the GitHub server. This is done with the command:

git push

The push command will transfer all local commits that are not already on the GitHub server. You must run git add, git commit, and git push at least once per lab assignment (preferably more), otherwise the instructor(s) and grader(s) will not have access to your work.

git status

If you ever lose track of where you are in the add, commit, push process, you can check the status of your repository with the following command:

git status

This command will display:

  • What files have been modified, but not added

  • Files that have been added, but not commited (called "staged")

  • Whether or not the latest commits have been pushed

For more details, see Understanding Git Status.

General Workflow

After cloning a remote main repo, you will work in your own local private copie of the repo. You can add and commit changes to your private copy as you go, and choose when to push your changes to the remote main repo.

A figure showing a computer labeled "CS Network(local)" connected to the GitHub logo labeled "GitHub Enterprise (remote)".
Figure 1. git operations on local/remote repos

If you make changes to a file later and wish to publish those changes, repeat the add, commit, push loop again to publish another commit to the GitHub server. In general, we will only look at the most recently pushed commit, but git maintains a history of all commits, making it possible to review past versions of the code.

You should add, commit, and push often; do so at least every time you sit down to work on your project. There is no penalty to having many commits, and referring to previous project versions is often helpful.
Sample workflow of git commands
# from within your local private git repo
$ cd ~/cs-example/labs/lab-example-ghopper1/

# check the status of your repo
$ git status

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

# add a new file to the repo on the next commit:
$ touch foo.cpp
$ git add foo.cpp
# or add new changes to an existing repo file to the next commit:
$ code name_year.txt      # edit with your favorite editor
$ git add name_year.txt

# commit your changes (adds and deletes) to your local repository:
$ git commit -m "my commit message"

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

Summary

  • git add adds files to your next local commit.

  • git commit records changes to recently added/removed/modified files to the git history with a commit message. Using descriptive messages makes it easier for you, your partner, or your instructor to understand recent progress and changes.

  • git push pushes changes from your local repo into the remote main repo, usually on the GitHub server. A push pushes only files that have been added and committed to your local repo.

  • git status provides hints on what files have been recently modified, if you have unpushed commits, or if you have conflicts. It is highly recommended that you use git status to determine if all the changes you want to share have been pushed to GitHub.

Using Git with a Partner

If you are working on an assignment with a partner or in a group, you will typically have a single remote repository that you and your partner(s) commit changes to. Changes pushed to the remote repository are not automatically sent down to local copies, but git has commands for retrieving changes from a remote repository to a local copy.

Setting Up

Both you and your partner(s) should individually clone copies of your remote repository, following the same steps as above.

git pull

In order to see changes that your partner has pushed, you must pull the changes from the remote repository.

git pull

The git pull command will fetch any commits from the remote repo that your local repo is missing and then update your local code to the version in the latest commit.

A figure showing a multiple local repositories connected a single remmote repository".
Figure 2. git operations with multiple local repos

Merging and Conflicts

When multiple people are sending and receiving changes from one remote repo, their changed must be merged together. Normally git can do this automatically, however git expects you and your partner(s) to follow a certain pattern of pushing and pulling.

Typically, only one partner should push their changes to a repository at a time. If you try to push changes to a remote repo that has more recent changes, you will get an error messge instructing you to pull the latest changes first.

Additionally, whenever you sit down to work, before you start editing files, you should always use git pull to get any changes that your partner has made.

Alternate File Versions

Uncommitted Changes

If you have local uncommitted changes to a file that has a more recent commit on the remote repo (e.g., you are locally editing foo.cpp, but your partner has just pushed a change to foo.cpp), git will ask you to either discard or commit the changes. There are many ways to resolve this, but it is best to make a backup of the file first. Then you can always safely discard your local changes and restore them later.

Already Committed Changes

If you have already committed local changes that are different from a commit on the remote repo (e.g., both you and your partner committed changes to foo.cpp before pulling one anothers' versions), you may get a merge conflict. This occurs when git is unable to combine two different versions of a file from different commits.

For information on fixing merge conflicts, see Git Merge Conflict Resolution.

Summary

  • git pull pulls changes from the remote main repo into your local repo. Git will try to automatically merge changes into your files. If there are conflicts you will need to fix them and run git pull again.

  • Typically, only one partner should add, commit, and push at a time.

  • Always git pull when you start working for the day to get the latest changes.

  • You can only push changes if there are no unmerged changes on the GitHub server. If you get an error message when trying to push, check if you need to pull new changes first.

  • If you are unsure if a pull will overwrite your changes, first make a local backup with cp!

.gitignore

It is useful to add a .gitignore file to your repo. Your instructor will typically provide a template for this file as part of the starting code. The .gitignore file tells git to automatically ignore adding certain files or file types to the repo, such as .o files, executable files, and editor backup files, like vim .swp files. This way, if you do a git add, git doesn’t try to add files created by the build process instead of by a human.

A file or directory that starts with a period (like .gitignore) is "hidden". Use ls -a at the command line to see hidden files and directories.

Here is an example .gitignore file for a C program that builds an executable file named myprog:

*.o
myprog
*.swp

# OSX, vim, emacs goofiness
.DS_STORE
.DS_STORE?
*~
*#
.#*
.nfs*
.*.sw?

You add a .gitignore file to a git repo just like you add any other file:

git add .gitignore
git commit -m "ignore .o files"
git push

Common Git Commands

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

Troubleshooting

  • git commit fails: sometimes the very first git commit fails and tells you to run git config commands that will create entries in the .gitconfig file in your home directory. Just run these commands (filling in your info, of course), and try git commit again and it should work:

    git config --global user.email "you@cs.swarthmore.edu"
    git config --global user.name  "Your Name"
  • git commit puts me in some crazy editor I don’t know (jove?). You can set your default editor by running this (set to vim or emacs or whatever you want to use):

    git config --global core.editor "vim"
  • First git push fails with an error. If this happens, try specifying the remote and branch name in the push command, like this:

    git push -u origin main

    subsequent calls to git push should work (that is, you should not need to include -u origin main after this first time).

  • git pull fails and warns about uncommitted changes: Make a backup of your local changes to a directory outside of the repo using cp. Then you can safely discard the changes in the repo and pull. Restore from the backup if necessary.

  • git push: fails if your partner pushed changes to the remote that you have not yet pulled into your local. Do a git pull first. Resolve any merge conflicts. Compile and test your code with these newly pulled changes. Then do a git add, git commit and git push.

  • git pull reports merge errors: this problem occurs when changes to the remote repo that you are pulling from conflict in a way that git cannot resolve. You must fix the conflicts manually in your favorite editor, then inform git of the fixes. In files with merge conflicts, git copies in the remote version, the common ancestor, and the local version of the modified code that it cannot merge automatically. These three versions are in the file with the following syntax:

    <<<<<<<
    my local version changes
    ||||||
    common ancestor version
    ======
    remote version changes that I'm trying to pull into mine
    >>>>>>

    In your editor, search for these symbols and fix the code by hand. Then add and commit your fixed version and run git pull again.

    See the Git Merge Conflict Resolution guide for more detailed examples of how to resolve different types of merge conflicts.

  • git help: git’s help interface to view git manual pages related to specific git commands and functionality.

    See the git user’s manual and/or git man pages (man git-clone, for example) for more commands.

History and Restoring Files

One of the most important features of git is that it maintains the history of a project, and allows developers to restore previous versions.

Refer to Using Git History for information on viewing the history of a repo, and how to restore old files, undo commits, and resetting to old versions.

Branching and Tagging

In real-world production repos, it’s useful to keep track of different versions of a project and to separate developing new features from the currently released version of the code.

Refer to Advanced Git Features for information on branching and tagging, tools used for managing software versions.

What Happens to My Repos when I Graduate?

ITS will delete your userid during the summer after you graduate. Once that happens you will lose access to your SwatGitHub repos.

You can, of course, just clone your repos to your home computer/laptop, but a better solution might be to migrate the repos over to github.com.

If you put code on github.com, make sure you create private repos, so you aren’t sharing solutions with current/future SwatCS students.

If you want to migrate your repos, here’s one way to do that:

  • create a github.com account using a non-swarthmore email

  • add your swarthmore ssh-key to github.com to make the transfer a little easier

For each repo you want to save:

  • create a new repo on github.com

  • make sure it is private

  • Use the ssh-url to push the contents from swat to github.com (see below)

Since origin is the default name for most of our repos, you should probably pick a different name than origin for the remote when doing the transfer. For example:

git remote add personal git@github.com:username/reponame.git
git push -u personal main

Here we replaced origin with personal, but any name will do. This only pushes one branch, which usually suffices.

External git Resources

  • GitHub’s guide to more git resources

  • The git book — sections 1 and 2 in particular are very useful

  • git reference — for quick look up of specific git commands.

  • Look at man pages of git commands (man git-clone, for example)

  • git cheat sheet — a short reference of common git commands

References