Solutions - Git first steps
Exercise 1 - Your first commit
- After initializing a new Git repository with
git init, we run
git status: what we can see is that, at this point, all files are untracked. The next step will therefore be to add some of the files to the git index so they can then be committed.
cd exercise_1 # To intialize a new git repository, we must first enter the repository in which # we want to track changes. tree . # This command is just to list the files present in a directory. git init # Create a new Git repository. git status # At this point, all files are untracked.
- Stage all files except
test_results.out, then check the status of the repository again.
git add R/ tests/ DESCRIPTION LICENSE README.md git status # Files that we just added are displayed as "new file". # They have been added to the Git index (aka, "staging area") # and are ready to be committed.
- Make a first commit.
git commit -m "Initial commit for fake stringr package" git log # Shows commit history. git show # Shows content of the last commit. git status # There is now only 1 untracked files left: test_results.out
- Since we want the
test_results.outfile to be ignored by all copies of the repository, the correct location to exclude it is in
.gitignore. After having created a new
.gitignorefile that contains the text "test_results.out", we still have one untracked file: the
.gitignorefile itself! This file is meant to be tracked by Git, so that it can be shared with others. Therefore we add it to the git index and then commit it.
echo "test_results.out" >> .gitignore git status # There is still one untracked # file left: .gitignore !! git add .gitignore # Stage the .gitignore file. git commit -m "Add gitignore file" 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 # Edit author and URL manually. git add README.md git commit -m "README: add author and URL info" # Shortcut for the above 2 lines: # git commit -m "README: add author and URL info" README.md
- Explore different ways to display a Git repository's history:
git log git log --pretty=oneline git log --oneline git log --all --decorate --oneline --graph
- Create an "adog" alias Git command and test it:
git config --global alias.adog "log --all --decorate --oneline --graph" git adog
- Run the commands given in the instructions to create 3 new files and modify 2 existing files.
git statusyou should see that 2 files are modified, and 3 are untracked (actually, the entire
large_datadirectory will be shown as untracked).
On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: DESCRIPTION modified: README.md Untracked files: (use "git add <file>..." to include in what will be committed) large_data/ personal_notes.txt no changes added to commit (use "git add" and/or "git commit -a")
- Explore the difference between
git add -uand
git add --all. First let's see what "add -u" does: it updates the Git index with the new version of all files that are already tracked by Git (in our case
README.md), but it does not stage any new, untracked files (in our case,
personal_notes.txtand the files in
git status git add -u git status git reset HEAD # Remove the staged changes for `DESCRIPTION` and `README.md` # so we can test the "add --all" option.
Now let's test what "add -all" does: it updates the Git index with all modified and untracked files. As can be seen, our 5 files (modified and new) have now been staged:
git status git add --all git status Changes to be committed: modified: DESCRIPTION modified: README.md new file: large_data/large_1.csv new file: large_data/large_2.csv new file: personal_notes.txt
The difference between
git add -u (
-u is a shortcut for
git add --all is
--update will only add files that are already tracked in Git, while
add all files (except ignored files), whether they are already tracked (modified) for not
(untracked). In a sense,
--update is safer because it prevents you from adding completely new
files to the Git repo by mistake.
- let's unstage each of our 3 files with one of the possible command to remove content from the git index:
git restore --staged personal_notes.txt git reset HEAD large_data/large_1.csv git rm --cached large_data/large_2.csv
The difference between
git rm --cached and the two other commands is that
git rm --cached
will unstage the entire file, not just the new changes that were made to it since the last
The reason why in this particular case
git rm --cached does exactly the same as
git restore --staged and
git reset HEAD is because the 3 files that we unstaged are new
and have never been added to the Git repo before. There is thus no difference between removing
them completely, or just resetting them back in the index to their version from the latest
commit (since they are all absent from the latest commit).
- Since the content of
large_datashould be ignored by all copies of the repository, we ignore it using the
personal_notes.txt, on the other hand, should only be ignored only by the local instance of the Git repo, and must therefore be added to
echo "large_data" >> .gitignore echo "personal_notes.txt" >> .git/info/exclude git status
- Commit all remaining changes:
git add .gitignore git status git commit -m "Update DESCRIPTION and README" git status git log --oneline
Exercise 2 - The git reference web page
Change into the exercise_2 directory, and look at the current status of the git repository.
cd exercise_2 git log git log --oneline # There are 3 commits in the repo. git branch # There is 1 branch: master. git status # There is one tracked file with # unstaged changes: references.html
A) Fix the broken "ProGit" link.
Make a new commit with any non-committed changes:
git diff git add references.html git commit -m "Add Git logo placeholder to the Git reference webpage" # Shortcut for the above 2 lines: # git commit -m "Add Git logo placeholder to the Git reference webpage" references.html # or # git commit -am "Add Git logo placeholder to the Git reference webpage" git status # There are no more uncommitted changes.
Fix the "ProGit" link in a temporary
fix branch. After testing that the HTML page works
correctly, commit the change.
git branch fix git checkout fix # Alternatively, you can also use "git switch fix" # Shortcut for the above 2 lines: "git checkout -b fix" or "git switch -c fix" vim references.html # Edit the HTML page... then verify # in the browser that it works. git add references.html git commit -m "Fix broken ProGit link" # Shortcut for the above 2 lines: # git commit -m "Fix broken ProGit link" references.html # or # git commit -am "Fix broken ProGit link"
Merge the changes into branch
master and delete branch
git checkout master git merge fix # Note: no additional commit is created by the merge, # because this is a "fast-forward" merge. git log --all --decorate --oneline --graph git branch -d fix # Delete the "fix" branch, as we no longer need it. git branch # Verify "fix" branch is gone. git log --all --decorate --oneline --graph # Show repo history again.
B) Add an image and new links to the HTML page.
Add new links to webpage:
git checkout -b dev # Alternatively, "git switch -c dev". vim references.html # Edit HTML page to add the new links... # After having checked that the two new links are working, stage and commit the changes: git diff git diff --cached git add references.html git diff git diff --cached git commit -m "Add two new links to Git reference page"
Add Git logo to webpage:
vim references.html # Edit HTML page to add logo... git commit -m "Add git logo" references.html
Merge changes into
master, delete branch
git checkout master git merge dev git log --all --decorate --oneline --graph git branch -d dev # Delete "dev" branch.
Exercise 3 - The crazy peak sorter script
Clone the peak sorter project from GitHub, test run the peak sorter script and display the Git repository's history.
cd exercise_3/ git clone https://github.com/sibgit/exercise_3.git cd peak_sorter ./peak_sorter.sh git log --all --decorate --oneline --graph
A) Add a fix to the master branch
Apply Jimmy's fix using cherry-pick on a temporary
git checkout -b hotfix # Alternative: git switch -c hotfix git log --all --decorate --oneline --graph # search for the commit of Jimmy's fix: 1c695d9 git cherry-pick 1c695d9 git log --all --decorate --oneline --graph # Verify the commit was properly cherry-picked. git show HEAD # Have a look at changes introduced by the cherry-pick. ./peak_sorter.sh # Test run the script to verify nothing is broken.
Merge the fix back into
git checkout master git merge hotfix git log --all --decorate --oneline --graph ./peak_sorter.sh # Test run: check the script is still working. git branch -d hotfix # Delete 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
feature-dahu on master. As there are conflicts, we need manually resolve them by opening
the conflicted file in an editor, resolving the conflict, then running
git add peak_sorter.sh and
git rebase --continue.
git rebase master # There are 3 conflicts, so repeat the steps below 3 times. vim peak_sorter.sh # Solve the conflict in an editor. git add peak_sorter.sh git rebase --continue ./peak_sorter.sh # Test run to see if everything is # still working after the rebase.
We are now ready to merge the new feature into
git checkout master git merge feature-dahu # This is now a fast-forward merge. ./peak_sorter.sh # Test run to see if everything is # still working after the merge.
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
A) Organize your team
Clone the repo.
cd exercise_4/ git clone https://github.com/sibgit/sibgit.github.io.git cd sibgit.github.io
The team leader creates the main development branch for the team and pushes it to the remote repository on GitHub. The example here is for the 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
git fetch git checkout yeti-dev
B) Add content for your awesome animal
Each team member creates his personal work branch. The example here is for Alice, working in team
Yeti. She 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. Then she can commit he changes.
git checkout -b yeti-alice git add yeti.html git commit -m "Add habitat and distribution info to yeti page."
C) Merge your branch with your team's animal-dev branch
Each member of the team must now add the changes they made on their personal branch to the team branch 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 she pushes the
yeti-dev branch to the remote.
git checkout yeti-dev git merge alice-dev # This is now a simple fast-forward merge. git push -u origin yeti-dev
D) Create a pull request for the top-level management to verify and approve your work.
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], and update their local git repo:
git fetch git checkout yeti-dev git pull git checkout master git pull