CS 70

Git and GitHub

GitHub is a host for git repositories—a way to share access to collections of code or other materials. Git itself is a version-control system. Version-control systems keep track of changes to files, and make it easier for people to collaborate on big projects. You’ll only collaborate with one partner at a time in CS 70, and you’ll always work together, but you’ll still be able to take advantage of some of the great things that come from using version control.

Repositories

Each of your assignments will be distributed as a repository—is a collection of files that share things like their record of changes and list of people who can access them. For example, for Homework 0, we created a repository for you whose name started with homework-00-, and you cloned it onto the CS 70 server. That repository included a file called Readme.txt, a file called written-answers.md, and some additional files whose names started with a . (period) that hold settings for git and for editors. (Files whose names start with a . are hidden on *nix systems (including macOS and Linux) unless you tell your file browser or, in a terminal, ls or a similar command to show them.)

Git Actions

Working with git involves a number of high-level concepts. While the terminology might be a bit unfamiliar, most version-control systems use similar ideas. The following sections outline the basic set of operations for using git.

Cloning

To make changes to the files in a repository, you first need to have a local copy of the repository on the computer you’re working on. Copying that repository is called cloning the repository. You will need to create a clone of your repository on every computer that you want to use to work on the assignment. In CS 70 that means cloning it once, into ~/cs70 on the CS 70 server: your clone stays there between sessions, so you do not need to clone it again when you sit down at a different lab machine.

You can get the path for cloning a repository by navigating to it on GitHub, clicking the green <> Code button, and copying the URL that is displayed.

Then, in a terminal, cd to wherever you want the repository to live and run:

git clone url

where url is the URL you copied. Git makes a new folder named after the repository (without the .git at the end) and puts the clone inside it, so you don't need to make the folder yourself.

Committing

git keeps track of different versions of your files, but it only knows about changes when you tell it about them.

To tell it to store a new version of a file or files, you have to commit the changes you've made. When you commit, you should include a brief message that describes how this new version is different from previous versions.

Committing at the command line takes two steps. First tell Git which changes you want to save with git add or git stage, then save them with a message using git commit -m:

git add fontfun.cpp
git commit -m "Fix the off-by-one in the loop bound"

Git then confirms what it did:

[main 4554f70] Fix the off-by-one in the loop bound
 1 file changed, 4 insertions(+)

Always pass -m with your message in quotes.

If you leave it out, Git will try to open a text editor for you to type the message; on the CS 70 server it will open Helix (hx).

Pushing

Committed changes are only stored in your local copy of the repository unless you push them to repository on GitHub.

At the command line, that's just

git push

Git tells you what it's done, which should look something like

To https://github.com/hmc-cs70-fall2026/hw1-alice-bob.git
   9f73dae..28531f4  main -> main

Pulling

The opposite of pushing is pulling, which copies any changes from your GitHub repository into your local repository. Pulling causes Git to copy the remote changes and then merge them into your existing files.

At the command line, run

git pull

Two issues to keep a eye out for:

  • If you have changes checked in to your local repository that affect the same parts of a file that were changed in the upstream repository, you will get a merge conflict.

  • If you have uncommitted changes, git pull will fail with an error about unstaged changes.

Keep reading to learn how to handle these issues.

Merge Conflicts

Merge conflicts occur when you've changed files in your local repository that have also been changed on GitHub. When you pull changes from GitHub into your repository, Git's attempt to merge that code with what you have can result in conflicts—parts of the code you've both changed will be called out in the files, and you have to resolve the conflicts by editing the files to choosing one of the versions of the code to keep.

The best way to avoid merge conflicts is to pull changes into your repository before you start working—that way, you're starting from the most recent version of the project.

Once you're done working on your code, you should push your changes back to GitHub. (If something has changed in the GitHub repository while you were working, you will have to pull those changes, resolve any conflicts, and then push your changes to GitHub.)

Resolving a Conflict at the Command Line

When Git can't merge two sets of changes by itself, it says so and stops:

Auto-merging fontfun.cpp
CONFLICT (content): Merge conflict in fontfun.cpp
Automatic merge failed; fix conflicts and then commit the result.

The merge is now half-finished and git is waiting for you to resolve the conflicts. Running git status will tell you the state of your local repository and what you need to do to resolve any issues. For example,

You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)
    both modified:   fontfun.cpp

Open each file Git listed in Helix; for example,

hx fontfun.cpp

You will find that Git has written both versions into it, fenced off with marker lines:

line 41 (unchanged, so no conflict here)
<<<<<<< HEAD
    int total = count + 1;
=======
    int total = count;
>>>>>>> 9f73dae622268391be1dcb74909af2a06eac8d1a
line 43 (also unchanged)
  • Between <<<<<<< HEAD and ======= is your version.
  • Between ======= and >>>>>>> is the version you just pulled from GitHub.
  • The jumble of letters and numbers after >>>>>>> is the commit id it came from.

To resolve the conflict, edit the file until it says what you want it to say, and delete all three marker lines. You may choose to keep your version, keep their versions, or write something new that combines or replaces both—git has no opinion, it just wants the markers gone and the code to be what you intend it to be.

Note that there can be more than one conflict in a file, so you'll need to search for the marker strings to make sure you've resolved everything before continuing.

When you're happy with the state of the file, you can tell Git you've dealt with it, and continue the merge:

--no-edit accepts the merge message git has already written for you (“Merge branch 'main' of …”), which saves you a trip through a text editor for a message nobody will read.

git add fontfun.cpp
git commit --no-edit

If there are conflicts in multiple files, fix those, stage them, and commit them in the same way. You may need to use git merge --continue to complete the merge. (git status will tell you if so.)

Once you've resolved all the conflicts and completed the merge, run

git push

to push your changes back up to GitHub.

If have problems resolving the conflicts, you can always start over!

Until you commit the merge, git merge --abort puts everything back exactly as it was before you pulled—your work is safe while you are in the middle of a conflict.

  • Goat speaking

    So the scary-looking arrows in my file are just… text?

  • LHS Cow speaking

    Just text. Git has no special way of marking up a file, so it writes the two versions into the file itself and trusts you to sort them out. Deleting the markers is not a Git command, it's just editing the file.

If you find yourself with a merge conflict you can't resolve, a prof or grutor will be happy to help you resolve it.

Unstaged Files

Git is all about keeping your work safe. If you have uncommitted changes in your working directory, Git will stop you from overwriting those changes during a pull. Git will print a message similar to the following:

error: cannot pull with rebase, you have unstaged changes.
error: Please commit or stash them.

As the message tells you, you can either commit the changes to your local repository, and then run git pull again, or you can stash your changes, finish the pull (which might include resolving merge conflicts), and then reapply the changes you stashed.

Stashing is easy. Just run

git stash

and you'll see a message similar to

Saved working directory and index state WIP on main: db7e871 Finish implementation of get

If you run git status, you'll see something like

On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

When you're done pulling the changed code into your repository, you can get your changes back with

git stash pop

which should print a message like

On branch main
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   get-it.cpp
    modified:   git-it.hpp

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (fc33f301e5f23718de093ccfaa3fbbd2c352577d)

By using pop, Git cleans up the stash you created, but there are other ways of restoring stashed work. See the documentation (e.g., git help stash) for more information.

Rolling Back Changes

Sometimes you commit a new version of your code, then realize that you wish you’d kept an older version! If that happens, you can roll back to a previous version of your code. There are lots of options here, and we recommend that you check with a prof or grutor if you don’t feel comfortable finding the right approach on your own. We’re happy to help!

A Basic Glossary of Git Jargon

This part of the glossary defines some common Git/GitHub-related terms that you will definitely encounter in the course of your work for CS 70. (There's also a list of terms you're less likely to need to know.)

(Some definitions were taken from https://help.github.com/articles/github-glossary/.)

Common Terminology

Add (verb) or Stage (verb)
Add new files or changes to tracked files in the queue (the index) for Git to save with git add filename or git stage filename. The file is queued as it is at that moment, which means that if you change the file again after adding it to the queue, you will need to git add the file again to include those additional changes in what will be committed.
Clone (verb)
Copy the contents of a remote repository, including change tracking information, to a directory on your computer. (git clone url)
Clone (noun)
A clone is a copy of a repository that lives on your computer instead of on a website’s server somewhere. Changing the clone does not change the original repository. (See also working tree.)
Commit (verb)
Save your staged changes to your local repo. (git commit -m "message")
Commit (noun)
A set of changes that is saved in a repository. (E.g. “The second commit contains all the work we did on the second task.”). (See Commit ID.)
Commit Message
A message that describes the changes made to the repository by a commit (e.g., Added header file. or Finished writing function 1.). You can add more information with multiple -m arguments or by using a text editor. (git commit -m "message" or git commit to open an editor.)
Git
A version control system (a program) that runs on your computer.
GitHub
A website that provides a variety of services around projects using Git as the repository format. (There are other alternatives.)
Helix
The text editor CS 70 uses on the course server to write your CS 70 code. See Surviving Helix for how to drive it.
Local
Stored on your computer. You can change local files or repositories by navigating to your project's directory and adding, deleting, or changing material.
Markdown (md)
A simple markup language for formatting text. GitHub allows you to use Markdown in readme files, comments, issues, and other places, and renders the text appropriately on the website. Other tools may render Markdown or display it as plain text.
Merge (verb)
Incorporate a set of changes into another branch or repository. Used by git pull and other commands, but you can also explicitly merge things with git merge.
Origin
The (default) remote source of a cloned repository. If you change a clone, the version on its origin remains unchanged until you push your changes..
Pull
Download changes from a remote repository that aren't in your local repository and merge them into your local repository. You should run git pull at the beginning of every work session.
Push
Send changes in your local repo to GitHub (or another remote). (git push)
README.md
A Markdown file that provides information about a project. If a project has a README file, it's generally a good idea to check it out before doing anything else. READMEs often include information about what the project does, why it was created, as well as more pragmatic things such as instructions for building the software, other software packages you need, and so on. GitHub will nicely render the content of a README.md file on the home page for the repository containing the project.
Remote

In general, something stored elsewhere (e.g., on GitHub). To make changes to a remote repository, you first need to create your own local clone, make changes there, and push them upstream.

Git also uses remote to define remote locations for tracking repository branches. “origin” is commonly used for the default remote, but you can have multiple remotes with different names, and pull or push changes to those remotes independently of one another.

Repo[sitory]
A collection of files that share a change log and a list of people who can access them. Typically, all the files associated with one project will be located in a single repository. You can think of a repository as a folder or a directory that you access with a computer.
Staged
Refers to changes that git will commit the next time the command git commit is run.
Tracking
A branch in your local repository can be set to use a remote branch as the target for git push and the source for git pull. A cloned repository will typically put you in a branch called main, with a remote called origin, and main will be set to track origin/main.
Unstaged

Any changes you've made that have not been staged will not be included in a commit command.

You can “unstage” staged changes on the command line using git reset path-to-file.

Version Control System
A tool that allows you to keep track of different versions of a codebase. CS 70 uses Git; other VCSs include Bazaar, CVS, Darcs, Mercurial, Jujutsu, RCS, and Subversion.
Visual Studio Code
An integrated development environment (IDE) produced by Microsoft that incorporates a text editor and a variety of tools to help developers write software.

CS 70 has used Visual Studio Code in previous semesters, but in Fall 2026, we'll be using the terminal-based editor Helix on the course server instead.

Working Directory/Tree

Can mean several things, including

  • Shorthand for the directory your project lives in.
  • The “current” (or “present”) working directory”—the directory you're currently in. (Try running pwd at a shell prompt.)

More Git Terminology

This part of the glossary defines some additional Git and GitHub-related terms and terms that you may encounter when searching through GitHub (and other) documentation. You won't need to worry about these when completing CS 70 assignments, but knowing them might be useful for personal projects or later work.

Branch (verb)
Create a new branch with git branch.
Branch (noun)

A separate set of changes included in a repository. Each branch can be edited independently and can track a different upstream repository. (git branch/git switch) Changes can be copied from one branch to another with git merge or git rebase.

Branches are useful for doing work you don't want mixed in with other work; for example, you might create a new branch to work on fixing a bug or trying out some experiments. Meanwhile, you can keep working on the main version of the code you're working on without being affected by anything in your other branches.

The default branch is usually called “main” (or, for older repos, “master”). Unless you've created a branch, you're probably working on main.

Commit ID
A unique hash identifying the changes included in a commit. You will sometimes need this hash (or a truncated version of it) to refer to a specific commit.
Config[uration] (File)
A collection of settings in a text file that allow you to set various default behaviors for Git, such as what text editor should be used when writing commit messages, or the name and email address you want associated with your work. Can be modified from the command line using git config, or by opening the configuration file in an editor. (Typical locations for Git's configuration files are ~/.git/config, ~/.gitconfig, ~/.config/git/config. The default configuration for a Linux or macOS system can be found in /etc/gitconfig.)

Changes you make on one system are not magically propagated to other machines, so if you make a change for one machine that you also want on another, you'll have to rerun the same git config commands on that other system or copy the configuration file from one machine to another.

Diff
A visualization of the differences between two commits or branches. Running git diff in a directory within your repository will show you any changes that have been made since the last commit (i.e., changes for files marked as modified in the output of git status).
Index

The queue of files that will be included in the changeset defined by the next git commit command. Files are added to the index with git add or removed with git reset. Sometimes called “the stage”.

It's possible to add some changes within a file or files while leaving others unstaged, but doing so easily generally requires the use of some additional tool or editor support.

Init (git init)

Command to convert a directory, with or without contents, into a Git repository.

After initializing the repository, you need to add files to track with git add and commit them with git commit. Making the repository available on GitHub is an exercise left to the reader.

Insertion
A line that was added to a file. Git will tell you how many insertions (and deletions) were made each time you commit your changes.
Issue
A suggested improvement, task, or question related to the repository—a “bug report”. You can view issues by navigating to the main page of a repository on GitHub with a web browser, and then clicking on the ⊙ Issues tab in the page header. Each issue has its own discussion forum on GitHub, and issues can be labeled (with, e.g., “bug”, “question”, “wontfix”) or assigned to a particular user for them to address.
Main
See master, below.
Master

The traditional (and problematic) name for the main branch of a repository, containing the original code or the already-working code.

The “master” branch is now usually called the “main” branch, and new repositories will usually use “main”. It's also possible to rename a branch, so changing from “master” to “main” is easily done.

Pull Request
A message asking the owner and collaborators of a repository you don't own to consider accepting changes you've made into their repository. Pull requests are usually associated with a particular issue—for example, they might address a bug or add a feature.
Rollback
Revert to an earlier version of your repository. You may want to roll back your code if you have made several mistakes in a current version of your repository. Rolling back your code in your local repository is unlikely to cause any problems for your collaborators, but if you've already pushed your changes up to GitHub, your collaborators may end up with conflicts when they next pull from the repo. GitHub warns you about “changing history” and requires you to jump through some hoops, but you can still make those changes if you know what you're doing and you coordinate with your collaborators.

Deeper Dive: More Information about Git and GitHub

This page is just a brief introduction to Git—it should be enough to get you started working on assignments in CS 70, but there's much, much more to learn if you're interested.

Git

You can find out about any git command by adding help before the subcommand; for example, git help commit will show the man page for git commit.

You can also just run man yourself, but the manpages for git subcommands are named git-subcommand, so, for example, man git-commit will get you the manpage for the commit subcommand. (Without the dash, you'll just get the manpage for git itself.)

GitHub

Using Git on Your Own Machine

The CS 70 server has been set up with some defaults to make your work easier (like using hx as its default editor). If you want to work on your own machine, you might find that your Git won't work quite the same as it does on the CS 70 server.

You're welcome to ask for help from profs or grutors (or fellow students), but remember that we're expecting you to do your work on the server.

(When logged in, completion status appears here.)