Git is a
This document describes a minimal set of commands for using Git in this course to submit assignments and acquire skeleton files. It is not any kind of tutorial or introduction to Git. Consult this Git documentation for an overview of Git and details of its various commands.
If you are working from your own machine, be sure to install Git, if it is not already installed. There are downloads available for various systems on this site.
Git terminology uses the term repository to mean an organized
collection of versions (called commits) of a directory structure;
plus a checked-out copy of the one of those commits
(a working directory), possibly in the process of modification; plus
a staging area (called the index) used to track what goes
into the next commit.
Usually,
the set of commits and the index are
stored in a directory named .git
at the
top level of the working directory. The term bare repository refers
to a directory containing only the set of commits (what would be a
.git
directory in an ordinary repository, but with no index).
Typically, we use bare repositories as central copies of versions that will be
shared by several repositories.
Each student has a bare central repository that we maintain for you on the instructional servers under the account cs61b-ta. You, the staff, and the autograding software all have access to this repository. In addition, we've set up for you one local repository under your cs61b instructional account in a directory called repo. It is a clone of your central repository, together with a checked-out working directory from one of its commits (generally your latest). You are free to set up other such local clones (say on your personal laptop or home computer). The central repository will serve to keep them all in sync with each other (at least if you follow the instructions here), so that you can work on any of several machines.
This section refers to setting up a local repository on any machine. You can skip it if you use only the instructional machines. Generally, you will not use these instructions on the instructional machines; we've already done it for you, and you are liable to mess something up. Of course, if you manage to destroy the local repository on the instructional machines, you may want to use these instructions to restore it from whatever version you last pushed.
First install the appropriate ssh private key for access to your central repository. Get an instructional account for CS61B if you don't already have one. There, you'll find a directory ~/.ssh, with files id_rsa and id_rsa.pub, which contain, respectively, the private and public ssh keys used by our repositories. For non-Windows systems, copy id_rsa to your home computer's .ssh directory, giving it a unique name other than id_rsa (for example, cs61b_id_rsa.) Otherwise, you are liable to overwrite a secret key file of that name that you might have created for your own purposes. You can get ssh to use this key when appropriate by adding a line
IdentityFile ~/.ssh/cs61b_id_rsato the file .ssh/config (creating that file if it does not already exist.) Again, we've already done this on your instructional account.
In what follows, we'll consider a student named Fred with login cs61b-xx. Having installed Git, Fred first performs some general configuration that will apply to all repositories used from his account (for this course or elsewhere):
$ git config --global user.name "Fred Student" $ git config --global user.email "fred.student@somemail.com" $ git config --global push.default simpleThe first two lines set the name and email that Git will record in commits and logs. The last line is a safety measure that affects the
git push
command described later.
Fred initially establishes a working directory containing a local clone of his repository in a directory ~/repo (actually, any name works; repo is the name we use in your instructional account):
$ cd $ git clone cs61b-ta@ashby.cs.berkeley.edu:students/cs61b-xx repoThis will copy the contents of Fred's personal bare repository on cs61b-ta into the new local working directory repo as repo/.git, and will then check out its head version into repo as well. Initially, this head version is the branch master and is empty.
There will be various resources that we provide, including skeleton (starter) files for projects and assignments. Fred can add a reference to these resources to his repository with the commands
$ cd ~/repo $ git remote add shared cs61b-ta@ashby.cs.berkeley.edu:sharedWe'll see how to use this remote reference later.
Keep each assignment or project, ASSGN, in a subdirectory of that name in your working directory. Typically, we provide an initial set of files for each assignment. You can initialize an assignment directory, say for hw3, like this:
$ cd ~/repo $ git fetch shared $ git checkout -b hw3 shared/hw3 $ git push -u origin hw3This fetches the staff's hw3 skeleton files from
cs61b-ta
, then
checks out a copy of that hw3 into your local repository as a new Git branch
named hw3
. Finally, it copies that branch back to your bare
repository on cs61b-ta
and arranges to track it
locally. That means that if you work on hw3 from two different local
repositories (say from home and on the instructional machines), you can
bring either local repository up to date with any changes you made
from some other local repository with the command
$ git pull --rebase
In general, you'll keep the files for a given assignment in a
subdirectory of the same name (thus, your work on hw3 will be
in ~/repo/hw3 in a branch that is also called hw3).
Work on hw3 now proceeds as a sequence of edits and commits. After editing,
adding, and deleting files, you first inform Git of any new files that it
should start tracking. For example, if when working on hw3, you create
files test1.inp
and test1.out
, you would use the
command
$ git add test1.inp test1.out(from inside the directory
~/repo/hw3
).
Or, if these files are stored in a new subdirectory called
hw3/testing
, you can use the command
$ git add testingto add all the files in the testing directory. Once you add any new files, you can create a new commit (snapshot) for
hw3
with
$ git commit -aThis command will prompt you to write a log entry for the new commit. Descriptive log entries are generally a good idea, since they help you identify commits when using the git log command to list the commits you have made. In later courses (and real life), they are especially useful for complex team projects where one is trying to keep other team members informed of what changes you've made and why.
Periodically, you will want to transmit your work to your central
repository on cs61b-ta
(from which your local
repository was cloned).
This is especially true when you intend to hand it in
or do further work on it from a different local
repository. Also, pushing to the central repository provides you an
additional backup of your work—one that you cannot accidentally erase.
After the initial push for hw3 (the one that
had -u
in it) the command to push to your central
repository is just
$ git pushwhich (assuming you've used the procedures described in this document for configuration and for creating assignments) will by default push the current branch (e.g., hw3) to the central repository that it is tracking. He can also write it out the command more explicitly as
$ git push origin hw3
Don't try to push, however, without first committing any outstanding changes.
Git's distributed nature means that you can create an arbitrarily long
sequence of commits before pushing them. It's not necessary to be connected to
the cs61b-ta
repositories (or indeed, the Internet) to use
Git's version-control features.
The staff does not immediately see changes to your local repositories.
That is, when you
modify, add, or delete a file or when you execute git commit
, we
do not see these changes, since your repository
under cs61b-ta
is not changed. To be seen by us (or our
testing software)
your commits must be pushed, as described in the preceding section.
Furthermore, we don't treat all your commits, even when pushed, as submissions until you mark them as such. To submit one of your committed versions, create (and subsequently push) an appropriately named tag. For example, when you first want to submit hw3, first commit any changes in your hw3 directory, and then do this:
$ git tag hw3-1A tag is a named reference to a particular commit. After using git tag on a commit, you can later check out that commit by name. For example,
$ git checkout hw3-1Submission is not complete until you push the work to us:
$ git push # To push the hw3 branch (if not yet done) $ git push --tags # To push hw3-1 (and any other tags)
Subsequent submissions should be named hw3-2
, hw3-3
,
etc. We take the highest-numbered tag your final submission.
You can submit at any time, even when you have many intervening
commits. For example, if he have submitted hw3-1
and
hw3-2
and decide that the last submission is bogus, and the first
one was better, you can execute
$ git tag hw3-3 hw3-1which makes
hw3-3
, the latest submission,
as a synonym for hw3-1
. In fact, if the commit you want to
submit was not previously tagged, you can
find its unique id using git log
and then tag that. For example,
you might see
$ git log commit ff39e11f5e292a0c81f3cb65c2a39c7b301a595a Author: Fred StudentNow to submit the second commit back (from 1/26) as your first submission, executeDate: Tue Jan 27 16:32:17 2015 -0800 Experimentally refactor my solution to problem 3. commit 4f7d9e65744c8b528289746bf911cb81ded7c5e2 Author: Fred Student Date: Wed Jan 26 15:36:28 2015 -0800 Add tests. No errors detected so far. commit 2aea9782d7000bb07277617b9f81bea485374d27 Author: Fred Student Date: Wed Jan 22 15:34:55 2015 -0800 Begin work one hw3.
$ git tag hw3-1 4f7d9e(The unique ids in Git are hexadecimal SHA-1 hashcodes of the contents of the commits. You only need to specify a sufficiently long prefix of the hashcode to uniquely identify which commit you mean.)
Again, after adding any new tags, you must use git push --tags
to push them
to the repository that the staff (and autograder) see.
Submission dates and times will be taken
from the time of the commit tagged by hw3-
n, and
You can delete a tag locally, but we have set up the repository to prevent you
from doing this on cs61b-ta
's repositories. It shouldn't be
necessary in any case, since the autograder will
ignore tags that don't refer to known assignments and you can always
supercede a tag with a higher-numbered one.
The instructions so far have assumed that you store each assignment in a separate branch. This has the advantage of keeping your working directory uncluttered. Should you want to look at an old assignment, you can do so by checking it out. For example:
git checkout hw1will switch you to the
hw1
branch, so that your working directory
will contain just the directory hw1
.
However, you may not mind the clutter and might prefer to keep all your
assignments checked out so that you can refer to them easily. In that case,
you can simply use the standard branch master
for everything.
Our software doesn't mind as long as each assignment is in its own eponymous
directory.
It will work best if you start off by creating the master
branch from the standard
empty commit defined supplied in the shared repository. Assuming you have
executed the recommended git remote
command (see
Setting up Repositories), initialize the branch with
with these commands:
git checkout -b master Empty git push -u origin master
To start a new homework assignment from our skeleton, change the initialization instructions given under Using Your Repository to the following (after first making sure to commit any of your current work, of course):
git merge -m "Start hw3" shared/hw3This will add the subdirectory
hw3
to your working directory.
cs61b-xx
and
team OurTeam
.
$ git config --global user.name "Fred Student" $ git config --global user.email "fred.student@somemail.com" $ git config --global push.default simple # Suggested
repo
and connect it up our shared repository:
$ git clone cs61b-ta@torus.cs.berkeley.edu:students/cs61b-xx repo $ cd repo $ git remote add shared cs61b-ta@torus.cs.berkeley.edu:shared
ASSGN
(e.g., hw3
),
from our template and put it in its own branch with that name:
$ cd repo # If not already there $ git checkout -b ASSGN shared/ASSGN $ git push -u origin ASSGN
$ git statusThe message will tell you how to undo changes from the last commit, should you want to.
$ git add F
$ git commit -aThis does nothing with untracked files.
cs61b-ta
) repository:
$ git push
cs61b-ta
repository that have been
pushed from another local directory (commit current work first):
$ git pull --rebase
$ git tag ASSGN-n $ git push $ git push --tagswhere n is a sequence number larger than those of existing tags. Always commit before you do this.
$ git tag