First steps with git: exercises


Exercise 1 - your first commit [20 min]

Objectives: learn to initialize new git repositories, add files to it and make commits.

Welcome to the first exercise of the git course! This is the warm-up, so you will be guided step-by-step on exactly what you need to do.

  1. Change directory into /exercise1 and list its content. You will see that it contains (parts of) the source code of the R package stringr.

  2. Create a new empty git repository at the root of the exercise1 directory, so that we can then version control our R code.

  3. Run the git status command. What do you observe?

  4. Add all files to the git repository, except for test_results.out and personal_notes.txt.

  5. Run the git status command again to make sure the staged content is correct before proceeding with the commit.

  6. Make a first commit in the repo with the message Initial commit for stringr package. Then run the git log command to have a look at your commit.

  7. Run the git status command. Are there any untracked files left? hint: there should be.

  8. If you have done things correctly there should be 2 untracked files at this point: test_results.out and personal_notes.txt. To stop these files to appear as untracked, add them to the correct ignore files so that:

    • test_results.out is ignored by all copies of the repo (in case it is e.g. shared with someone else).
    • personal_notes.txt is ignored only by your local copy of the repository.
      hint: use the .gitignore and .git/info/exclude files.
  9. Run the git status command. You should see that you still have an untracked file!
    Question: how should you deal with this untracked file? Should it be added to the repo, or added to the ignore list?

  10. If you look at the content of the README.md file, you will see that it contains the string MISSING on two different lines. Edit the README.md file to replace the "MISSING" values by their correct content:

    • the author of the stringr package: "Hadley Wickham"
    • the URL of the package: https://cran.r-project.org/web/packages/stringr
  11. Run the git status command. You should see that the README.md file is now marked as "modified".

  12. Add the changes you just made to README.md the git repo with the git add command. Remeber that each time you edit a file, and want to include these changes into your next commit, you have to git add this file again.

  13. Commit your changes with the message README: add author and URL.

  14. Display the (modest) history of your git repo with the following variations of the git log command:

    • git log
    • git log --pretty=oneline
    • git log --all --decorate --oneline --graph
  15. Since the git log --all --decorate --oneline --graph command is very handy, let's create a git shortcut for it:
    git config --global alias.adog "log --all --decorate --oneline --graph"
    After creating it, test you new shortcut: git adog

Solution:

cd exercise1

# Create a new git repository. Add content to it and make a first commit:
git init
git status  # we can see that all files are currently untracked. So we have to add some of the
            # files to the git index so they can then be committed.
git add R/ tests/ DESCRIPTION LICENSE README.md
git status  # now the files that we just added are displayed as "new file". They are now added to
            # the index and ready to be committed.
git commit -m "Initial commit for stringr package"
git status  # There are now only 2 untracked files left.

# Add the untracked files to the correct igrnore list. "test_results.out" should be ignored by all
# copies of the repo, therefore the correct location to exclude it is in '.gitignore'.
# "personal_notes.txt" should only be ignored by the local instance of the git repo, and should
# thus be excluded via .git/info/exclude.
echo "test_results.out" >> .gitignore
echo "personal_notes.txt" >> .git/info/exclude
git status

# After adding content of to the two ignore list files, we still have one untracked file: the
# .gitignore file itself. This file is meant to be tracked in git, so we add it to the git index
# and then commit it.
git add .gitignore
git commit -m ""
git status   # now there are no more untracked files displayed.

# Edit the README file to add the package author and URL information. Then commit the changes:
vim README.md
git add README.md
git commit -m "README: add author and URL info"
# shortcut for add + commit: git commit -m "README: add author and URL info" README.md

# Explore different ways to display a git repo's history:
git log
git log --pretty=oneline
git log --all --decorate --oneline --graph

# Create an 'adog' alias git command:
git config --global alias.adog "log --all --decorate --oneline --graph"
git adog



Exercise 2 - the git reference web page [30 min].

Objectives: learn to use branches when adding new features and bug fixes to a code base.

To start the exercise, change directory into /exercise2. You will see that it already contains a git repository, as well as an html page named references.html.

  1. Open the references.html page in your web browser.

  2. Explore the content of the git repo using the git log, git status and git branch commands to answer the following questions:

    • How many branches are present in the repo? How are they named?
    • How many commits have already been made in the repo?
    • Are there any un-committed changes?

A) Fix the broken "ProGit" link.

Your first task is to fix the link to the "ProGit" book in the html page (you can try to click on the "ProGit" link in the page open in your browser, it should return an error). Since we want to follow good practices, we will not work on the fix in the master branch. Instead we will create a new branch, fix the link problem, test our fix, and then merge it into master if we are confident the problem is solved.

  1. Before working on our fix in a new branch, we want to make sure that our working tree is clean: Display the uncommitted changes to see what they are: even if you are not familiar with html, it should be easy enough to figure-out what the changes do.

  2. Now that you have figured out what the uncommitted changes do, stage the changes and make a commit with a meaningful message. Verify that your working tree is now clean.

  3. Create a new branch named fix.

  4. In the new branch, edit the references.html file to fix the link to the ProGit book.
    hint: add https:// in front of the URL.

  5. Verify in your browser that the link is now working properly. If it is the case, you can now commit your changes.

  6. Merge your fix branch into master and delete your fix branch as it is no longer needed.

B) Add an image and new links to the html page.

In this second part of the exercise, you are tasked to add couple of new book links. Here are the things you should do:

  1. work in a new branch named dev.

  2. Make a commit that adds the following 2 references at the end of the list in the html page:

    • <li><a href="https://www.manning.com/books/learn-git-in-a-month-of-lunches">Learn git in a month of lunches</a></li>
    • <li><a href="https://www.amazon.com/Git-Porch-Willie-Crawford-2006-02-01/dp/B01K95YGYG">Git Porch</a></li>
  3. When you have added this new feature to the webpage successfully (you can check whether you did a proper job by refreshing the webpage in your browser), merge your dev branch into master.

  4. Try a git log --all --decorate --oneline --graph to display your entire repo's history.

At the end of the exercise, you should reload the references.html and check that all links are working and that that git logo was added.


Solution:

# Change into the exercise2 directory, and look at the current status of the git repository.
cd exercise2
git log
git log --oneline
git branch
git status

### A)
# Make a new commit with any non-committed changes:
git diff
git add references.html
git commit -m "references: add git logo image to webpage"
# one liner: git commit -am "references: add git logo image to webpage"
git status   # now there are no uncommitted changes left.

# Fix the "ProGit" link. We do the fix in a temporary branch, before merging it back to master.
git branch -b fix
# Edit html page...
git add references.html
git commit -m "references: fix the broken ProGit link."
# one liner: git commit -m "references: fix the the broken ProGit link." references.html
git checkout master
git merge fix
git branch -d fix    # delete the now merged "fix" branch, as we no longer need it.

### B)
# Add new book links to the webpage:
git checkout -b dev
# Edit html page to add links...
git add references.html
git commit -m "references: added new links to page."
git checkout master
git merge dev
git branch -d dev



Exercise 3 - the crazy peak sorter script [30 min]

Objectives: learn to apply hotfixes with cherry-pick, rebase branches and solve conflicts.

The stakes are raising! You are now taking the lead developer position of the "peak sorter" project - a mesmerizing bash script that sorts all alpine summits above 4000 meters in order of decreasing elevation (i.e. highest to lowest). It also displays the name and elevation of the highest summit in the Alps when completed.

  • Start the exercise by changing your work directory to the root of your exercise directory (i.e. at the same level as the /exercise1 and /exercise2 directories).

  • Clone the data for exercise3 with the command: git clone https://github.com/sibgit/exercise3.git

  • To see the peak sorter script in action, run ./peak_sorter.sh on the command line.

  • have a look at the history of the git repo with git log --all --decorate --oneline --graph

A) Add a fix to the master branch.

As the new lead developer of the "peak sorter" project, your first task is to add an input data integrity check to the peak_sorter.sh script.
Luckily a former developer of the project, Jimmy, has already worked on this issue and made a commit with the fix in his own branch named dev-jimmy. The message of the commit containing the fix is "peak_sorter: add check that input table has the ALTITUDE and PEAK columns".

Your task is thus to take this commit and apply it to the peak_sorter.sh script. Proceed as follows:

  1. As you don't want to work directly on master, you should first create a new hotfix branch.

  2. Cherry-pick the commit that contains Jimmy's fix onto your hotfix branch.

  3. When the cherry-pick is completed, test run the ./peak_sorter.sh script to make sure nothing was broken. You can also have a look at the changes introduced by the cherry pick with git show HEAD to review the latest commit.

  4. When you are confident things are working as expected, merge your hotfix branch into master.

  5. Delete the hotfix branch.

B) Add the Dahu count feature to the master branch.

Your next task is to add a new feature to the peak_sorter.sh script, which should add the number of dahus observations made on each alpine peak to the output of peak sorter.

Again, you're in luck because this feature has already been developed in a branch on the git repo, aptly named feature-dahu.
Proceed as follows:

  1. Checkout the feature-dahu branch and test whether the new feature has been implemented properly (i.e. run the peak sorter script and check its output for Dahu counts).

  2. Rebase the feature-dahu branch on master. This will result in conflicts that you will have to resolve with the following guidance:

    • In the first conflict, keep the version from the feature branch.
    • In the following conflicts, you can keep the version you prefer.
  3. When you completed the rebase, try to run the peak_sorter.sh script again to make sure it works. It should now also display the number of Dahus observed on the Alps' highest peak.

  4. When you are confident that the new dahu count feature is correctly implemented, you can merge feature-dahu into the master branch.


Solution:

# Change directory to the root of the git exercises.
git clone https://github.com/sibgit/exercise3.git
# Clone the repo for exercise 3 from GitHub, then test run the peak sorter script and display
# the git repo's history.
cd exercise3
./peak_sorter.sh
git log --all --decorate --oneline --graph

### A)
# Apply Jimmy's fix using cherry-pick. We first apply the fix on a temporary "hotfix" branch
# before merging in back into master.
git checkout -b hotfix
git log --all --decorate --oneline --graph  # look for the hash of Jimmy's fix: 1c695d9
git cherry-pick 1c695d9
git show HEAD  # Have a look at the changes introduced by the cherry-pick.
./peak_sorter.sh  # test run
git checkout master
git merge hotfix
./peak_sorter.sh       # test run
git branch -d hotfix   # delete the now merged hotfix branch, as we no longer need it.

### B)
# Add the Dahu count feature to the master branch.
# Checkout the feature-dahu branch. Run the script to test that it works. Then rebase it on master.
git checkout feature-dahu
./peak_sorter.sh
git rebase master
# Solve the conflict in an editor, then continue the rebase with:
git add peak_sorter.sh
git rebase --continue
# Repeat the above 2 more times, as there are 3 conflicts in total.
# Now do a test run to see if everything is still working after the rebase:
./peak_sorter.sh
# We are now ready to merge the new feature into the master branch:
git checkout master
git merge feature-dahu
# Do a test run again to make sure that the dahu count feature was added to the master branch:
./peak_sorter.sh

# Note: trying to delete the local branch feature-dahu with the safe '-d' option will not work
# because changes on the branch have not been pushed to the upstream branch 'origin/feature-dahu'.



Exercise 4 - The awesome animal awareness project [30 min]

Objectives: learn to collaborate with others on a project hosted on GitHub.

Congratulations!!! Your improving git skills have now got you hired by our exciting startup to build a brand new animal awareness website. Building this website is a collaborative effort, and you will be working in teams of 3 people, where each team will contribute a page of the website about a specific awesome animal.
At the end of the exercise, the page that was created by your team will be integrated into the animal awareness website.

Please be mindeful of naming conventions for branches in the project, our company's internal git policies are very strict.

A) Organize your team.

  1. Get together: by now you should have received a card with an animal name on it. Find your team mates - who have the same animal card as you - and sit together so you can communicate with each other.

  2. Clone the project from our GitHub repository.

  3. Among your group, chose a "team leader". The team leader should create a branch for your team. It should be named after your animal's name followed by -dev (e.g. tiger-dev, yeti-dev). After the branch is created, the team leader should push it to the repo on GitHub.

  4. Other team members can now fetch the new branch just pushed by the team leader from GitHub.

  5. Each team member should now creates his/her personal branch, using the following naming scheme: <animal>-<your name>, e.g. tiger-sandra or pallas_cat-tom.

B) Add the content for your animal.

Each team member will now contribute something to the webpage of his team's animal. 1. Switch to your personal branch.

  1. Once you are sure you are on your personal branch, edit the html file corresponding to your animal. The topics that each member of the team has to work on are listed on your card. The ?? mark the positions where you have to add your content.

  2. For the people with the task "Picture": find and download a picture of your animal from internet. Add the image to git and copy the file name into <img src='?? image-filename'>, e.g.
    <img src='tiger_image.png'>

  3. Check the rendering of your html file by opening it with your browser.

  4. Commit your changes.

C) Merge your branch with your team's animal-dev branch.

Each team member should now merge the edits made on his/her personal branch (e.g. tiger-sandra) to the team's main development branch (e.g. tiger-dev), and then push the changes back to the remote repo on GitHub. This is best done as an iterative process, where each member will in turn: 1. Do a git pull on the team's main development branch to make sure his local copy is up-to-date.
2. Rebase his personal branch on the team's main development branch. Note that the first person to add his changes will in principle not have to do this rebase, since his personal branch will already be rooted at the last commit of the team's main development branch. 3. Merge the changes from his personal branch into the team's main development branch.
4. Push the changes back to the repo on GitHub.

At the end of this process, the team's main development branch should contain the work of all 3 team members.


D) Create a pull request for the top-level management to verify and approve your work.

Now that your team's main branch is all merged and clean, your team leader should create a pull request of your branch to be merged into the project's master branch.
hint: you have to do that directly on the project's GitHub repository.

Once the management approved your work and merged it into master, you should be able to see your animal's page on awesome animal awareness website! Well done! Enjoy your success by reading about your animal.


Solution

### A)
# Change directory to the root of the git exercises.
git clone https://github.com/sibgit/sibgit.github.io.git
cd sibgit.github.io
# Team leader: must create the main development branch for the team.
# The example is here for team "yeti".
git checkout -b yeti-dev
git push -u origin yeti-dev    # note: -u is the short option for --set-upstream-to
# Other team members can now pull the new yeti-dev branch and create a local copy of it
# by checking-it out.
git fetch
git checkout yeti-dev

### B)
# Each team member creates his personal work branch. The example here is for Alice, working in
# team Yeti.
git checkout -b yeti-alice
# Alice now edits the yeti.html page in her favorite editor. When she is done, she load the page
# in her browser to make sure the rendering is looking good.
# At this point she is ready to commit:
git add yeti.html
git commit -m "Added distribution information to yeti page."

### C)
# Now each member of the team must add the changes he/she made on her personal branch to the
# Yeti-dev branch. Let's assume that Alice is the last of the team to make changes.
git checkout yeti-dev
git pull
git checkout yeti-alice
git rebase yeti-dev
# Conflicts will appear, so Alice must solve them manually.
git add yeti.html
git rebase --continue
# Now that the rebase is completed, Alice can merge her branch into yeti-dev. Then push the updated
# yeti-dev to GitHub.
git checkout yeti-dev
git merge alice-dev
git push -u origin yeti-dev

### D)
# Now that the yeti page is completed, the team leader can make a pull request to the owner of the
# project on GitHub (i.e. one of the class teachers).
# When the request is accepted, this will merge the changes in yeti-dev into the master branch
# of the project.
# All members of the team can now view their work at [https://sibgit.github.io/tiger.html]
# Members of the team can also update their local git repo:
git fetch
git checkout yeti-dev
git pull
git checkout master
git pull

Last modified: Saturday, 29 February 2020, 1:41 PM