PS5: Error handling and Git integration in VSCodium
The goal of this session is to understand the following points:
Exercise 1: Error handling¶
Disclaimer
In this exercise, we will focus on writing and understanding error handlers without worrying about code reorganization, file management, or automatic compilation.
Create a directory
error-handling
insidePS5
, then add the following files:level1
,level2
,level3
, andplay.cpp
.In
play.cpp
, copy the following code:
#include <iostream>
#include <string>
#include <fstream>
int getLevelFromUser() {
int userInput;
std::cout << "Enter a game level: ";
std::cin >> userInput;
return userInput;
}
std::string getLevelData(int level) {
std::string filepath = "level" + std::to_string(level);
std::ifstream file(filepath);
std::string levelData;
levelData.assign((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
file.close();
return levelData;
}
void play() {
int level = getLevelFromUser();
getLevelData(level);
std::cout << "You are playing level " + std::to_string(level) + ".\n";
}
int main() {
play();
return 0;
}
What does this code do?
We are simulating part of a game where:
getLevelFromUser
retrieves the game level from user input.getLevelData(int level)
loads the resources for levellevel
by opening the corresponding file (e.g.,level1
iflevel
is1
). The content oflevel1
is then copied intostring levelData
usingassign
. The file is then closed withfile.close()
, andlevelData
is returned.play
retrieves the level number and its resources, then simulates gameplay with the messageYou are playing level 1.
(iflevel
is 1).
For this simulation, the fileslevel1
,level2
, andlevel3
must simply exist.
Compile and execute the code to observe its behavior based on user input.
In
getLevelFromUser
, implement an input validator that allows only 3 attempts, with an integer betweenfirstLevel
andlastLevel
(e.g., from 1 to 5). After 3 failed attempts, the function should throw an exception.
We will not handle this error immediately because we want to return to the game’s main menu, which should not be accessible from getLevelFromUser
. Error handling without terminating the program is always preferable to stopping execution with an error code.
Catch the error in
play
and simulate returning to the main menu by displayingReturning to main menu.
In
getLevelData
, check if the corresponding level file exists. If it does not (if(!file) {...}
), return the message"Resources not found for level <level number>."
and terminate the program withEXIT_FAILURE
.
This is an example of local error handling, which avoids throwing an exception that needs to be handled elsewhere, simplifying the code logic.
Exercise 2: Git integration¶
Create a directory git-integration
.
Git without IDE¶
First, we will learn to use the following commands in the terminal.
log¶
- Run
git log --oneline
to display the repository history, where each commit appears on a single line, starting with a commit hash followed by the commit message.
q
q
Reminder: Press q
to exit the log view.
- Run
git log --oneline --graph
to visualize the commit history as a graph (drawn in ASCII), where each commit is represented by a star.
Your graph should be mostly linear, except where conflicts created divergent branches.
alias¶
When managing multiple branches, you can add --decorate
(to show branch names) and --all
(to display all branches) to git log --oneline --graph
.
- Define
git graph
as an alias using:
git config --global alias.graph "log --oneline --graph --decorate --all"
- Run
git graph
.
show¶
- View details of a specific commit using
git show <commit hash>
.
checkout¶
We can navigate through different vertices in this graph, meaning we can return to different states of our repository as recorded by commits.
- Run
git checkout <commit hash>
with the hash of a previous commit. For example, your command could look likegit checkout abc0123
.
Observe the state of your (old) repository.
Return to the most recent commit (and exit the detached HEAD state) by running
git checkout main
.
git checkout -
git checkout -
The command git checkout -
allows you to switch back to the last visited commit before the current HEAD position.
revert¶
Create a file named
revert.txt
containing the lineHello World!
and commit this change.Add a second line to
revert.txt
containingHi!
and commit this change.
Now, imagine that adding the second line was a mistake. We will revert this commit while keeping the commit history intact. This is useful because the erroneous commit might contain valuable information or may have already been pushed to the remote repository.
- Run
git revert HEAD --no-edit
, then check the content ofrevert.txt
.
You will see that a new commit has been created with the default message Revert "<message of the reverted commit>"
. You could also use git revert HEAD -m "<message>"
to provide a custom message instead of the default one.
We can also revert multiple commits at once. Each reverted commit will have its own revert commit.
- Run
git revert HEAD~3..HEAD --no-edit
to revert the last three commits.
You can omit the --no-edit
option if you want to add a message to each reverted commit. Alternatively, you could use git revert -n HEAD~3..HEAD
, which does not create separate revert commits immediately. Then, you can run git commit -m "<message>"
to create a single commit (instead of three) with your custom message.
reset¶
Create a file
reset.txt
containingHello World!
and commit this change without pushing.Add a second line to
reset.txt
sayingHi!
and commit this change without pushing.
The git reset
command works similarly to git revert
, but instead of creating a new commit to undo the changes, it removes commit A
from the history.
- Run
git reset HEAD~1
to remove the last commit.
You can also use git reset HEAD~<number>
to remove the last <number>
commits.
Git with IDE¶
Now, open your Git repository in VSCodium.
If VSCodium asks if you want to regularly perform git fetch
, you can say yes. If you said no, don’t worry, we will explain git fetch
below.
In the vertical toolbar on the left, you will find Extensions. If you see the error Error while fetching extensions. XHR failed on Debian at the IUT, check the VSCodium support guide to configure the proxy.
Search for and install the Git Graph extension by mhutchie.
log¶
- Open Git Graph by clicking the Git Graph button at the bottom of your screen or by selecting View > Command Palette (shortcut F1 or Ctrl + Shift + P), then type
Git Graph
and choose Git Graph: View Git Graph.
Command Palette
You can perform all Git operations in VSCodium via the Command Palette, including all Git commands.
The graph displayed by the Git Graph extension represents your commit history, with commit hashes on the right.
show¶
Click on a vertex in the graph to view details of the corresponding commit.
Click on a modified file within a commit to see the specific changes (similar to
git diff
).
status¶
- You can view your repository’s status in Source Control (left sidebar).
add¶
Create a new file.
You can stage the new change in Source Control by clicking + next to the change or stage all changes by clicking + at the top.
restore¶
To unstage a change, click - next to a staged change.
To discard untracked changes in a file, click the arrow left of +, labeled Discard Changes.
commit¶
In the Message box at the top of Source Control, write your commit message.
Click Commit to commit your changes.
push¶
- Click Sync Changes to push your changes.
pull¶
In Source Control, hover over ... above the message box to open More Actions.
In this dropdown menu, you will find Pull among other Git commands.
You can also use the Command Palette (F1
), type pull
, and select Git: Pull.
clone¶
- Similar to
pull
, you can clone a repository by entering its URL (with a PAT).
config¶
- In the buttons to the right of Git Graph, you will find Repository Settings, where you can configure repository settings.
fetch/remote update¶
git fetch
is almost the same as git remote update
, but allows you to be more specific by using git fetch <branch>
to retrieve information about a specific branch.
By default, git fetch
only retrieves information from the remote repository named origin
. In the future, if you contribute to existing projects, you will likely need to fork them, creating copies with separate remote and local repositories. In this case, it is useful to fetch changes from multiple remotes, which can be done using git remote update
(or equivalently, git fetch --all
).
- Click Fetch from Remote(s) in the Git Graph buttons.
Sometimes, clicking Refresh is helpful to update the graph view after recent changes.
checkout¶
In Git Graph, right-click on a commit message and choose Checkout.
To return to the latest commit, right-click the
main
branch icon and choose Checkout Branch.
revert¶
- In Git Graph, right-click the most recent commit and choose Revert.
reset¶
- In Git Graph, right-click an older commit, select Reset current branch to this Commit..., and choose Soft, Mixed, or Hard (preferably Soft or Mixed).
Do not reset a pushed commit!
Reminder!
merge¶
Create an empty file named
merge.txt
and synchronize it so that it exists in both repositories.Locally, add
Hello World!
to the first line of the file.On GitLab, use the Web IDE to add
Hi!
to the first line of the file.
GitLab Web IDE
The GitLab Web IDE is based on VSCode/VSCodium, so its Git integration is very similar but without extensions. You can still use the Command Palette.
Perform a fetch in Git Graph and observe the divergent branches.
Right-click on the commit message of the branch from the remote repository and select Merge into current branch... with the No commit option.
Open the
merge.txt
file.You can choose one of the suggested options above the conflict or manually resolve the conflict by writing a new text that replaces both, such as
Bye!
.
You can also select Open in merge editor, which appears in the bottom right corner. This will open three views: two showing the conflicting file versions and a third where you will write the final merged version.
- Complete the synchronization with the merged version.
git merge --abort
git merge --abort
git pull
performs the same actions as git fetch
followed by git merge
. If you forget to check the repository state before pulling or merging, you can use git merge --abort
to cancel the merge.
Go back to the objectives and check off the points you have mastered. If you need help, ask your instructor.