git is version control software.
It is useful for managing code projects, particularly projects with partners.
This guide provides instructions for using git for CS lab and project work with
partners.  It includes setup instructions for using
git repos hosted on Swarthmore's GitHub server, available to all Swarthmore students and faculty. It also covers git commands and tools, troubleshooting errors,
some advanced features, and links to other git resources.
Contents:
- Git Overview
-  Setup and Configuration for cloning and using Swarthmore's GitHub Enterprise
-  Creating ssh-keys  and initial set-up.
-  Cloning a local copy of a repo.
 You can also create your own repo the
the Swarthmore GitHub server.  However, if the repos contains coursework to be graded,  be sure to explicitly make  it a private git repo when you create it.
-  Commands for using a shared repo: add, commit, push, pull, diff, .gitignore
-  Understanding git status
-  List of common commands and git tools
- Troubleshooting some common problems, handling errors with git commands, resolving merge conflicts
- Some advanced git features: branches, tags
- External links to git documentation and resources
 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 push fairly often too).
 
 Setup for using repos on Swarthmore GitHub Enterprise
Many CS courses numbered 31 or higher use 
Swarthmore's GitHub
Enterprise server.  This is very similar to the public 
GitHub.com, but is only visible to Swarthmore students, faculty and staff.  Students in CS courses should follow these steps to clone
their lab git repos.
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.
First Time Set-up and Generating ssh keys
If you have never used Swarthmore's GitHub server or if you forgot your ssh-key password, you will need to complete
the one time 
config steps for
using Swarthmore GitHub before proceeding.  You can create and add public ssh keys for multiple accounts (e.g. one for your CS account and another for your laptop account).
Accessing Course Repos
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-F17 for the Fall 2017 semester of CS31.  From the main GitHub
page, select the organization you want to use.  You can also jump directly to
the organization url, which looks something like https://github.swarthmore.edu/CS31-F17 (your instructor may have a link to it off 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.  For example, suppose two teammates (Grace Hopper,
ghopper1, and Alan Turing, aturing1) are working together.  When Grace
accesses the organization, she would expect to see:
- Lab2: A repository containing starter code for lab 2.  This
repository is read-only to students.
- Lab2-ghopper1-aturing1: This is the remote master repository for
Alan and Grace's lab2 solution that only they can access.
Initially it contains a copy of the starter code, and it will be
updated as Grace and Alan push changes from their local repo to this
remote master.  Also, the professor will pull Grace and Alans's lab2
solution from this remote master repo at the due date of the lab assignment
to collect their solution.  They need to be sure to push their finished solution to this repo before
the lab due date.  
Cloning a local copy of the repository
You and your partner will both create a private local copy, or 
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.
- 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).
On 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.
- 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:
[labs]$ git clone git@github.swarthmore.edu:CS31-F17/Lab2-ghopper1-aturing1.git  ./lab2
 
-  Then cd into your local repo directory and access the files there
[labs]$ cd lab2
[lab2]$ ls
CMakeLists.txt  README.md lab2.cpp
 
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 changes to and pull changes from the github server.
 Commands for using a git repo
 Git basics: the add,commit,push loop 
Git has a lot of commands and a lot of features. But to get started, we'll learn three basic commands for recording changes and submitting your work to the github server for grading.
 git add 
Let's suppose you have a file 
program.cpp that you edit to complete part of your assignment. If you would like to submit this file to the github server the first step is to run the command:
git add program.cpp
This git command informs git that you wish for changes to this file to be included in the next step, called commit. You will need to use 
git add to submit newly created files as well as files that you previously submitted but then modified later.
 git commit 
The 
git commit command records all the changes to recently added files to a local copy of your git history along with a message of your choosing describing the changes.
git commit -m "finished lab assignment"
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. Git will only commit files that have been added to be part of the next commit using the 
git add, which is why it is important to run 
git add prior to running 
git commit.
 git push 
                     The 
git commit command only records your changes locally, but 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, otherwise the instructor(s) and grader(s) will not have access to your work.
 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.
 General workflow 
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 changes to the remote master repo. Your  partner can then 
pull your changes from the remote master into their copy. To get changes from your partner, your partner should first push the changes, and then you should pull. If you are not working with a partner, you will not need to use the 
pull command.
An example of a sequence of common git commands:
 # from within your local private git repo
 cd ~/cs31/labs/lab01/
 # check the status of your repo
 $ git status
 # see the changes to the file (compared to your last local commit):
 $ git diff blah.cpp
 # 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:
 $ vim blah.cpp      # edit with your favorite editor
 $ git add blah.cpp
 # 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 -u 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 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 all kinds
of kooky files to the repo.  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 and git tools
Common 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 master repository
            # (note: the first time you may have to do: push origin master
git status  # see what has changed between your copy and the master version
git pull    # pull changes pushed to remote master 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 master origin/master  # diff between your copy and master's
git branch -a # see all the branches (likely only master)
git visualization tools:
-  gitg and gitk are two gui tools to visualize commit
history and branches.
-  git mergetool can be used to help you fix git merge conflicts. See the Troubleshooting section below for more information about merge conflicts.
 Troubleshooting
	-  git commit: 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"
 
-  git push: sometimes the very first git push fails with
	an error.  If it does, try this:
git push -u origin master
 subsequent calls to git push should work (i.e.
	you should not need to include origin master after this
	first time).
         
-  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, commit and push.
	
 
- git pull with 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 can try running
git mergetool.  It will help step you through the conflicts and
fix them.  You can also fix conflicts by hand in your favorite editor.
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 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, e.g.)  for more commands.
 
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.
See the Git Branch guide for more details.
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 tagged version, but
you can check it out just like any branch).
See the Git Tag guide for more details.
 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, e.g.)
- git cheatsheet – an interactive view of how various git commands modify the state of local and remote repos, along with your working directory.
-  git magic  – a good source of information about more advanced and obscure git functionality
- 
An older version of this guide.