Exercises - Git first steps


Configuring Git

Before starting with the exercises, make sure that you have done the minimal Git configuration by setting your user name and email address in Git:

  • git config --global user.name "First-name Last-name"
  • git config --global user.email "your.email@example.com"

Optionally you can also change the default editor used by Git, e.g. if you are more comfortable with nano than vim:

  • git config --global core.editor nano
  • git config --global core.editor vim


Exercise 1 - Your first commit [30 min]

Objectives: learn to initialize a new Git repository, add files to it and make commits.

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

A) Create a new repo, add content and make commits

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

    • Initialize a new empty Git repository at the root of the exercise_1 directory, so that you can version control its content.
    • Run the git status command. What is the status of the files in your working directory?


  2. Add all files to the Git repository, except for test_results.out. Run the git status command again to make sure the staged content is correct. If you have staged your files correctly, the output of the git status command should look like this:

    Changes to be committed:
        new file:   DESCRIPTION
        new file:   LICENSE
        new file:   R/sort.R
        new file:   R/split.r
        new file:   R/stringr.R
        new file:   README.md
        new file:   tests/testthat.R
        new file:   tests/testthat/test-case.R
    
    Untracked files:
        test_results.out
    


  3. Make a first commit in the repo with the message Initial commit for fake stringr package. Then you should:

    • Run git log to display the repository's history.
    • Run git show to have a look at your commit.
    • Run git status again. Are there any untracked files left?

    Note: depending on how much there is to print, git show will displays the content of a commit with the GNU program "less":

    • Use your keyboard arrow keys to move up/down.
    • Press q to exit and return to the shell.


  4. If you have done things correctly there should be exactly 1 untracked file at this point: test_results.out. To stop this file from appearing as untracked, add it to a Git "ignore file" so that it is ignored by all copies of the repo, in case it is e.g. shared with someone else. hint: use a .gitignore file.

    Now 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?

    Take the appropriate action with the untracked file, and make a new commit if necessary. At the end of this step, you working tree should be "clean": when you run git status, the output should be:

    On branch master
    nothing to commit, working tree clean
    



  5. 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

    Run the git status command again. You should see that the README.md file is now marked as "modified".
    To commit the changes you just made, you should now:

    • Add the changes you just made to README.md the Git repo with the git add command. Remember 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.
    • Commit your changes with the message README: add author and URL.


  6. Display the (modest) history of your Git repo with the following variations of the git log command (observe the difference in how history is displayed by each command):

    • git log
    • git log --pretty=oneline
    • git log --oneline
    • git log --all --decorate --oneline --graph

  7. As you will soon notice, the git log --all --decorate --oneline --graph command is very handy - especially when we will be working with branches later on. So let's create a Git shortcut for it with the following command:

    • git config --global alias.adog "log --all --decorate --oneline --graph"

    Let's test your new shortcut by typing: git adog You should have a history that looks like this (note: the commit ID values will differ):

    * 8b14ba7 (HEAD -> master) README: add author and URL
    * b48e2c1 Add gitignore file
    * cd56e1e Initial commit for fake stringr package
    



Additional tasks (if you have time)
  1. Let's create some additional files at the root of the exercise_1 directory: simply copy-paste the following 6 lines in your terminal (with the working dir set to exercise_1):

    echo "Let's keep this local" > personal_notes.txt
    mkdir large_data
    echo "A large file in the making..." > large_data/large_1.csv
    cp large_data/large_1.csv large_data/large_2.csv
    echo "adding a line" >> DESCRIPTION
    echo "adding a line" >> README.md
    


    This should create a new file named personal_notes.txt, as well as a directory large_data with 2 files in it: large_1.csv and large_2.csv. It will also modify the existing files DESCRIPTION and README.md.

  2. We now want to experiment the difference between the git add --all and git add -u commands. Let's proceed as follows:

    • Run git status, and note the state of each file. You should have both modified and untracked changes.
    • Run git add -u followed by git status: note which files have been added.
    • Run git reset HEAD followed git status. You should see that this command has removed all newly added content from the staging area.
    • Now run git add --all followed by git status: again, note which files have been added. You should now be able to answer the question below:

    Question: what is the difference between git add --all and git add -u?

  3. Unstage the following 3 files: personal_notes.txt, large_data/large_1.csv and large_data/large_2.csv (note: "unstaging" is a synonym for "removing from the git index").
    To unstage a file, you can use either of these 3 commands:

    • git restore --staged <file>
    • git reset HEAD <file>
    • git rm --cached <file>

    Question: the 2 first command are identical, but what is the difference with git rm --cached <file>? Why does git rm --cached <file> give the same result as the first two commands in this particular case?

  4. Run git status to verify that you have successfully unstaged the 3 files (see point 10). They should now appear as "untracked". To stop these files from appearing as untracked, add them to the correct ignore files so that:

    • files in large_data are ignored by all copies of the repo.
    • personal_notes.txt is ignored only by your local copy of the repository.

    hint: use the .gitignore and .git/info/exclude files. Note that .git/info/exclude is a file, not a directory.

  5. Commit the changes to the DESCRIPTION, README.md and .gitignore files with the message "Update DESCRIPTION and README". Your working tree should now be clean - verify it with git status.



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 /exercise_2. 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 commits have already been made in the repo?
    • How many branches are present in the repo? How are they named?
    • Are there any uncommitted changes?

A) Fix the broken "ProGit" link.

Your first task is to fix the broken 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 this 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 once we are confident the problem is solved.

  1. Before working on our fix in a new branch, we need 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, then run git log --all --decorate --oneline --graph: at this point, the output should look like this (note: commit ID values will differ and your commit messages might be somewhat different):

    * 50a2e7f (HEAD -> master, fix) Fix broken ProGit link
    * e6a6176 Add Git logo placeholder to the Git reference webpage
    * 892ec25 Add Git logo file
    * c99fb57 Add links to Git resources
    * 5b54605 First commit. Add template for the Git reference page
    


  7. Delete your fix branch as it is no longer needed. Run git branch and/or git log --all --decorate --oneline --graph to make sure the fix branch was deleted.


Enjoy your Git reference page: have a look at the different links if you want to learn everything about Git!

Additional tasks (if you have time)

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

In this second part of the exercise, you are tasked to add a 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>

    Note: use git diff and git diff --cached to look at your edits in the HTML file, before and after staging them.

    Note: check whether you did a proper job by refreshing the HTML page in your browser before you commit your changes.


  3. Make a commit that adds the Git logo to the webpage: replace the placeholder line that starts
    with <!-- Add Git logo placeholder by <img src="git_logo.png"> in the HTML file.

    Note: check whether you did a proper job by refreshing the HTML page in your browser before you commit your changes.

  4. When you have added these new features, merge your dev branch into master.

  5. Run git log --all --decorate --oneline --graph to display your entire repository's history. It should look like this (note: commit ID values will differ and commit message my be somewhat different):

    * ba4687a (HEAD -> master, dev) Add git logo
    * 30b149a Add two new links to Git reference page
    * 50a2e7f Fix broken ProGit link
    * e6a6176 Add Git logo placeholder to the Git reference webpage
    * 892ec25 Add Git logo file
    * c99fb57 Add links to Git resources
    * 5b54605 First commit. Add template for the Git reference page
    


  6. Reload references.html in your browser: check that all links are working and that the Git logo was added.
    Delete the dev branch, now that you no longer need it. Verify that is was deleted by running git branch and/or git log --all --decorate --oneline --graph.


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

Objectives: get familiar with cherry-picking, rebasing branches and solving 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 of the Alp's 4000 m summits 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 exercise_3/ - it should be empty.
  • Clone the data for exercise_3 with the command: git clone https://github.com/sibgit/peak_sorter.git.
  • You should now have a new directory named "peak_sorter". Enter it with the command cd peak_sorter.
  • 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 first task is to take this commit and apply it to the peak_sorter.sh script. Proceed as follows:

  1. Create a new hotfix branch (we wouldn't want to work directly on master, wouldn't we?).

  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 manually resolve. In all 3 conflicts, always keep the version that is coming from the feature branch. It's the second version when you open the file to manually solve the conflict (the one that is not coming from HEAD).

  3. When you completed the rebase, try to run ./peak_sorter.sh 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.

    At the end of the exercise, your history (git log --all --decorate --oneline --graph) should look like this (note: some commit ID values will differ):

    * 953de22 (HEAD -> master, feature-dahu) peak_sorter: display highest peak at end of script
    * 337fac8 peak_sorter: added authors as comment to script
    * 98bf029 peak_sorter: improved code commenting
    * 825dccc peak_sorter: add Dahu observation counts to output table
    * 6989be6 README: add more explanation about the added Dahu counts
    * 348e3b6 Add Dahu count table
    * aa3e112 peak_sorter: add check that input table has the ALTITUDE and PEAK columns
    * f6ceaac (origin/master, origin/HEAD) peak_sorter: added authors to script
    * f3d8e22 peak_sorter: display name of highest peak when script completes
    | * fc0b016 (origin/feature-dahu) peak_sorter: display highest peak at end of script
    | * d29958d peak_sorter: added authors as comment to script
    | * 6c0d087 peak_sorter: improved code commenting
    | * 89d201f peak_sorter: add Dahu observation counts to output table
    | * 9da30be README: add more explanation about the added Dahu counts
    | * 58e6152 Add Dahu count table
    |/  
    * cfd30ce Add gitignore file to ignore script output
    * f8231ce Add README file to project
    | * 1c695d9 (origin/dev-jimmy) peak_sorter: add check that input table has the ALTITUDE and PEAK columns
    | * ff85686 Ran script and added output
    |/  
    * 821bcf5 peak_sorter: add +x permission
    * 40d5ad5 Add input table of peaks above 4000m in the Alps
    * a3e9ea6 peak_sorter: add first version of peak sorter script
    




Exercise 4 - The Awesome Animal Awareness Project [60 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 "A3P" (aka, Awesome Animal Awareness Project) to build a new 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, and awesome, animal. At the end of the exercise, the page created by your team will be integrated into the animal awareness website.

Important: please be follow the naming convention for branches tightly, as 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. Change into exercise_4/ and 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 and checkout the new branch just pushed by the team leader.

  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 content for your awesome animal

Each team member will now contribute something to the webpage of his team's animal.

  1. Switch to your personal branch.

  2. 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. In the HTML file, the ?? mark the positions where you have to add your content.

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

  4. Check the rendering of your HTML file by opening it with your browser.

  5. 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 a coordinated, 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 changes will in principle not have to rebase, since his/her 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 remote 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 for your branch to be merged into the project's master branch. Creating such a pull request is done online, in 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 the Awesome Animal Awareness website!

Well done! Enjoy your success by reading about your awesome animal.

Last modified: Tuesday, 26 January 2021, 5:11 PM