p1-stats
Setting Up Version Control
This how-to will walk you through setting up a Git repository and using it to collaborate with a partner.
Prerequisites
We’re assuming that you already have a folder with starter source code in it, e.g., p1-stats/
. You’ve created new files and added function stubs to make the code base compile, e.g., stats.cpp
and main.cpp
. You’ve already set up your visual debugger.
$ pwd
/Users/awdeorio/src/eecs280/p1-stats
$ ls -A
Makefile main_test.out.correct p1_library.h stats_public_test.cpp
main.cpp main_test_data.tsv stats.cpp stats_tests.cpp
main_test.in p1_library.cpp stats.h
You have installed git
. Your version might be different.
$ git --version
git version 2.15.1
Restarting this tutorial
If you tried using this tutorial in the past and want to start over, here’s how to delete the files created by git
and how to remove your repository from GitLab.
First, remove your GitLab repository. Browse to your repository’s project page from https://gitlab.eecs.umich.edu/. Select “Settings” -> “Advanced Settings” -> “Delete Project”.
…
Next, remove the hidden files created by git
. Remember, hidden files start with a dot (.
).
$ pwd
/Users/awdeorio/src/eecs280/p1-stats
$ rm -rf .git/ .gitignore
$ ls -A
Makefile main_test.out.correct p1_library.h stats_public_test.cpp
main.cpp main_test_data.tsv stats.cpp stats_tests.cpp
main_test.in p1_library.cpp stats.h
Confirm that this is no longer a git repository.
$ git status
fatal: Not a git repository (or any of the parent directories): .git
Install
You should already have git
installed after completing the Command line tools tutorial. Verify that git
is installed. Your version might be different.
$ git --version
git version 2.15.1
Configure your name and email
This sets the git
preferences for your local machine. These settings apply to all repos on your computer. You only have to do this once, but repeating these commands won’t hurt anything. Be sure to use your own uniqname and email address
$ git config --global user.name "awdeorio" # Your uniqname
$ git config --global user.email "awdeorio@umich.edu" # Your email
Create a local repository
Navigate to your project directory and clean up any binary files using make clean
. You should see the files we created earlier in the Starter files tutorial.
$ pwd
/Users/awdeorio/src/eecs280/p1-stats
$ make clean
$ ls
Makefile main_test.out.correct p1_library.h stats_public_test.cpp
main.cpp main_test_data.tsv stats.cpp stats_tests.cpp
main_test.in p1_library.cpp stats.h
Next, add a .gitignore
file. This will prevent Git from controlling files like compiled binaries. We have a sample for you to download. It’s a hidden file (starts with a dot .
), so you’ll need to use ls -A
to see it. This sample is pre-configured to work with most C++ projects, so use the same sample file for all EECS 280 projects.
$ wget https://eecs280staff.github.io/p1-stats/dot_gitignore_sample -O .gitignore
.gitignore 100%[===================>] 6.23K --.-KB/s in 0s
2018-01-12 15:15:30 (53.4 MB/s) - ‘.gitignore’ saved [6381/6381]
$ ls -A
.gitignore main_test.in p1_library.cpp stats.h
Makefile main_test.out.correct p1_library.h stats_public_test.cpp
main.cpp main_test_data.tsv stats.cpp stats_tests.cpp
Initialize the repo and make sure that the main branch is named main
. You’ll see that all the files in our directory are currently untracked.
$ git init
Initialized empty Git repository in /Users/awdeorio/src/eecs280/p1-stats/.git/
$ git checkout -b main
Switched to a new branch 'main'
$ git status
On branch main
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
Makefile
main.cpp
main_test.in
main_test.out.correct
main_test_data.tsv
p1_library.cpp
p1_library.h
stats.cpp
stats.h
stats_public_test.cpp
stats_tests.cpp
nothing added to commit but untracked files present (use "git add" to track)
Add existing files to version control
Add all the files in this directory. See that they are ready to be committed.
$ git add .
$ git status
On branch main
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: .gitignore
new file: Makefile
new file: main.cpp
new file: main_test.in
new file: main_test.out.correct
new file: main_test_data.tsv
new file: p1_library.cpp
new file: p1_library.h
new file: stats.cpp
new file: stats.h
new file: stats_public_test.cpp
new file: stats_tests.cpp
Commit the added files to the local repo with the commit message “Initial commit. Starter files with function stubs.”.
$ git commit -m "Initial commit. Starter files with function stubs."
[main (root-commit) c19cc98] Initial commit. Starter files with function stubs.
12 files changed, 776 insertions(+)
create mode 100644 .gitignore
create mode 100644 Makefile
create mode 100644 main.cpp
create mode 100644 main_test.in
create mode 100644 main_test.out.correct
create mode 100644 main_test_data.tsv
create mode 100644 p1_library.cpp
create mode 100644 p1_library.h
create mode 100644 stats.cpp
create mode 100644 stats.h
create mode 100644 stats_public_test.cpp
create mode 100644 stats_tests.cpp
$ git status
On branch main
nothing to commit, working tree clean
View the commit log and see our first commit.
$ git log
commit a13e2521fab6488458c912f598d6d5f89d429484 (HEAD -> main)
Author: Andrew DeOrio <awdeorio@umich.edu>
Date: Fri Jan 12 15:59:25 2018 -0500
Initial commit. Starter files with function stubs.
Create a remote repository
First, log in to https://gitlab.eecs.umich.edu/. It’s a Git server run by the EECS department and all UM students should have a login.
Create a new project
Select “Create blank project”.
Call the new project p1-stats
, mark it as “private”. Then uncheck the “Initialize repository with a README” box. Click “Create”.
Double check that you have selected “private”. Making your project code or test cases publicly available online is a violation of the honor code.
You now have a project page for your remote repo. In this example, awdeorio’s project page is https://gitlab.eecs.umich.edu/awdeorio/p1-stats. You won’t have access to it because it’s private, but your page should look similar.
Connect local repo to remote repo
Browse to your repository’s project page from https://gitlab.eecs.umich.edu/. Click on “Clone”. Under the “Clone with HTTPS” heading, select “Copy URL to clip board”.
Pro-tip: If you want avoid typing a username and password all the time, you can use SSH keys and an SSH URL (instead of HTTPS). Check out the GitHub tutorial on SSH keys. Don’t forget to add your key to GitLab (not GitHub).
Connect your local repo to your remote repo.
$ pwd
/Users/awdeorio/src/eecs280/p1-stats
$ git remote add origin https://gitlab.eecs.umich.edu/awdeorio/p1-stats.git # use your URL
Double-check that your local repo is connected to your remote repo. You’ll see the URL you copied from your remote repo appear.
$ git remote -v
origin https://gitlab.eecs.umich.edu/awdeorio/p1-stats.git (fetch)
origin https://gitlab.eecs.umich.edu/awdeorio/p1-stats.git (push)
Push commits already committed on the local repo to the remote repo.
$ git push -u origin main
Username for 'https://gitlab.eecs.umich.edu': awdeorio
Password for 'https://awdeorio@gitlab.eecs.umich.edu':
Counting objects: 14, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (14/14), 6.97 KiB | 3.48 MiB/s, done.
Total 14 (delta 0), reused 0 (delta 0)
To https://gitlab.eecs.umich.edu/awdeorio/p1-stats.git
* [new branch] main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.
Verify that your local repo is up to date with the remote the repo (AKA origin/main
).
$ git status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
Verify the commit log.
$ git log
commit a13e2521fab6488458c912f598d6d5f89d429484 (HEAD -> main, origin/main)
Author: Andrew DeOrio <awdeorio@umich.edu>
Date: Fri Jan 12 15:59:25 2018 -0500
Initial commit. Starter files with function stubs.
See the commit log on your GitLab project page. Click “History”. (You may need to refresh the page to see this.)
You should see your first commit show up.
Add a new file to version control
Next we’ll add a README, which will show up on the front page of our GitLab repository web page.
$ pwd
/Users/awdeorio/src/eecs280/p1-stats
$ ls
Makefile main_test.out.correct p1_library.h stats_public_test.cpp
main.cpp main_test_data.tsv stats.cpp stats_tests.cpp
main_test.in p1_library.cpp stats.h
We have no modified files and our code is in sync with the code stored on GitLab. In other words, we haven’t changed anything since the last git commit
, and no changes have happened on the GitLab server.
$ git fetch
$ git status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
Add an empty file called README.md
using the command line.
$ touch README.md
$ ls
Makefile main_test.in p1_library.cpp stats.h
README.md main_test.out.correct p1_library.h stats_public_test.cpp
main.cpp main_test_data.tsv stats.cpp stats_tests.cpp
Add the existing file using your visual debugger.
- Add existing files with Xcode
- Add existing files with Visual Studio
- Visual Studio Code adds new files automatically
Now, edit README.md
to look like the following example. Be sure to change the name :)
EECS 280 Project 1 Solution
===========================
Statistics
By Andrew DeOrio <awdeorio@umich.edu>
You can see that the new file shows up as untracked.
$ git status
On branch main
Your branch is up-to-date with 'origin/main'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
README.md
We want to track README.md
, so git add
it.
$ git add README.md
$ git status
On branch main
Your branch is up-to-date with 'origin/main'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README.md
Commit, and you’ll see that the repo has a clean status again.
$ git commit -m "Added README"
[main e016bfa] Added README
1 file changed, 5 insertions(+)
create mode 100644 README.md
$ git status
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
(use "git push" to publish your local commits)
From the previous git status
command, we see that we have added code on our local computer that hasn’t yet been pushed to the remote GitLab server (Your branch is ahead of 'origin/main' by 1 commit.
). Let’s push it now.
NOTE: if you get a rejected
error, see Fixing rejected pushes, below.
$ git push
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 361 bytes | 361.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
To gitlab.eecs.umich.edu:awdeorio/p1-stats.git
350f38e..7fa8093 main -> main
$ git status
On branch main
Your branch is up-to-date with 'origin/main'.
nothing to commit, working tree clean
Browse to your repo’s project page on GitLab and you’ll see a fancy formatted version of your README.
Modify a version controlled file
Let’s practice modifying an existing file. We’ll add to the README. Check that our version controlled files are clean and up to date with the remote repo.
$ pwd
/Users/awdeorio/src/eecs280/p1-stats
$ git fetch
$ git status
On branch main
Your branch is up-to-date with 'origin/main'.
nothing to commit, working tree clean
Edit README.md
to add quick start instructions. We’re using Markdown formatting. It should look this when you’re done:
EECS 280 Project 1 Solution
===========================
Statistics
By Andrew DeOrio <awdeorio@umich.edu>
# Quick start
```console
$ make main.exe
$ ./main.exe
```
We can see that our files are no longer clean.
$ git status
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 checkout -- <file>..." to discard changes in working directory)
modified: README.md
no changes added to commit (use "git add" and/or "git commit -a")
See what’s different. You can see lines added (+
) compared to the last clean committed version of the file.
$ git diff README.md
diff --git a/README.md b/README.md
index 4641b12..b1dde51 100644
--- a/README.md
+++ b/README.md
@@ -3,3 +3,9 @@ EECS 280 Project 1 Solution
Statistics
By Andrew DeOrio <awdeorio@umich.edu>
+
+# Quick start
+```console
+$ make main.exe
+$ ./main.exe
+```
NOTE: On Windows, you may see lines that end with the ^M
character. This is normal; Windows uses a different convention for line endings than other operating systems.
Add, commit, and push.
NOTE: if get a rejected
error, see Fixing rejected pushes, below.
$ git add README.md
$ git commit -m "Added quick start to README"
[main 2fac8d1] Added quick start to README
1 file changed, 6 insertions(+)
$ git push
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 348 bytes | 348.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
To https://gitlab.eecs.umich.edu/awdeorio/p1-stats.git
a80db0b..2fac8d1 main -> main
View the commit history from the command line.
$ git log
commit 4d375b45357b4b39822ad48c62c6988910258370 (HEAD -> main, origin/main)
Author: Andrew DeOrio <awdeorio@umich.edu>
Date: Fri Jan 12 16:14:02 2018 -0500
Added quick start to README
commit e016bfad5a6371097ea00380aedd3e22ee63f754
Author: Andrew DeOrio <awdeorio@umich.edu>
Date: Fri Jan 12 16:07:36 2018 -0500
Added README
commit a13e2521fab6488458c912f598d6d5f89d429484
Author: Andrew DeOrio <awdeorio@umich.edu>
Date: Fri Jan 12 15:59:25 2018 -0500
Initial commit. Starter files with function stubs.
View the commit history on GitLab. Click a commit message to see a graphical diff.
View the diff on GitLab.
Daily work flow with version control
This section describes the work flow for a coding session with git
.
Start with clean files.
$ git status
On branch main
Your branch is up-to-date with 'origin/main'.
nothing to commit, working tree clean
Retrieve any changes from the server. For example, you might have pushed changes while working on another computer, like CAEN Linux.
$ git fetch
$ git rebase
Make changes to files. Add and commit when you’re ready. You can do this several times.
$ git add SOME_FILE
$ git commit -m "Short description goes here"
Push changes to GitLab server.
$ git push
If you get a rejected
error, see Fixing rejected pushes, below.
Next steps
If you’re here from the project 1 tutorial, you can now return to the main set up tutorial.
Version control for a team
Skip this section for project 1, which is individual.
We’ll walk you through a centralized Git workflow. You can find a description with pictures here.
Version control is great for teams working on the same code base. This is an outline of the steps to get started. Do this set up on one partner’s computer.
-
Add your partner as a “Maintainer” on the remote repo by inviting them in the “Members” tab.
GitLab sends a confirmation email to your partner. Your partner clicks accept.
-
Your partner
clone
s the remote repo on their own local machine.Your partner uses the same remote URL that you do. Notice that
akamil
uses a link that hasawdeorio
in it, that’s becauseakamil
is a member of the repo thatawdeorio
created.$ whoami akamil $ pwd /Users/akamil/Documents/eecs280/ $ git clone https://gitlab.eecs.umich.edu/awdeorio/p2-cv.git Cloning into 'p2-cv'...
-
All team members set up their visual debugger.
Remember, other team members don’t need to download the starter files again because those files were already added by the first team member.
-
All team members use the daily work flow with version control.
-
Be sure to read up on resolving conflicts
Resolving conflicts
Note: The following text is copied from https://help.github.com/articles/resolving-merge-conflicts-after-a-git-rebase/
When you perform a git rebase
operation, you’re typically moving commits around. Because of this, you might get into a situation where a merge conflict is introduced. That means that two of your commits modified the same line in the same file, and Git doesn’t know which change to apply.
After you reorder and manipulate commits using git rebase
, should a merge conflict occur, Git will tell you so with the following message printed to the terminal:
error: could not apply fa39187... something to add to patch A
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".
Could not apply fa39187f3c3dfd2ab5faa38ac01cf3de7ce2e841... Change fake file
Here, Git is telling you which commit is causing the conflict (fa39187
).
If you did this by mistake, you can undo the git rebase
with git rebase --abort
.
To fix the conflict, follow this how-to https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/
Fixing rejected
pushes
If you get a rejected
error when using git push
, this probably means you (or your partner) changed your repo using another computer (or the GitLab web interface).
$ git push
To https://gitlab.eecs.umich.edu/awdeorio/p1-stats.git
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'https://gitlab.eecs.umich.edu/awdeorio/p1-stats.git'
Fetch changes from the remote repo.
$ git fetch
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From https://gitlab.eecs.umich.edu/awdeorio/p1-stats
4d375b4..2b9bea7 main -> origin/main
See that the local and remote repos have diverged.
$ git status
On branch main
Your branch and 'origin/main' have diverged,
and have 1 and 1 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
nothing to commit, working tree clean
Reapply your local commits on top of your remote commits, combining them into one sequence of commits.
$ git rebase
First, rewinding head to replay your work on top of it...
Applying: Local update to README.
Divergence between local and remote is fixed. You’re good to push.
$ git status
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
$ git push
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 318 bytes | 318.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
To https://gitlab.eecs.umich.edu/awdeorio/p1-stats.git
2b9bea7..63a5d0b main -> main
$ git status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean