Git Integration (Source Control)¶
Now we will see how Git is integrated into the VSCodium interface. IDEs with Git integration often work in a similar way.
init¶
Your repository is already a Git repository, so there is no need to initialize it.
To initialize a new repository, simply click on the Source Control tab in the left sidebar, then click Initialize Repository.
clone¶
You do not need to re-clone your repository.
To clone a repository, you can select View > Command Palette (shortcut F1 or Ctrl + Shift + P), then type clone, choose Git: Clone, and enter the repository URL (with a PAT for example).
Command Palette
You can perform all actions in VSCodium through the Command Palette, including all Git commands.
status¶
You can view the status of your repository in Source Control, in Explorer, in the editor, and in the Source Control tab.
For example:
When you add a new file, a U appears next to its name to indicate Untracked.
When you modify a file that has already been tracked (
git add), an M appears next to its name to indicate Modified.Changes that are not yet staged appear in the Changes section of the Source Control tab in the left sidebar.
add¶
You can add a change from Changes to the Staging Area in Source Control by clicking + next to the change, or add all changes by clicking + next to Changes.
rm¶
You can delete a file in Explorer, then stage this change from Changes in Source Control.
restore¶
To unstage a change, you can click - next to a staged change.
To discard new untracked changes in a file, you can click the arrow to the left of +, labeled Discard Changes.
commit¶
In the Message box at the top of Source Control, you can write your commit message and click the Commit button to create the commit.
log¶
Search for and install the Git Graph extension by mhutchie.
Open Git Graph by clicking the Git Graph button at the bottom of your screen, or by typing
Git Graphin the Command Palette and selecting Git Graph: View Git Graph.
The graph displayed by the Git Graph extension represents your log, with commit hashes on the right. A version of this graph can be displayed in Source Control (if you do not see it, click the three dots at the top next to SOURCE CONTROL, then click Graph), but the extension allows you to perform more Git commands through the UI.
config && remote¶
In the buttons on the right side of Git Graph, you will find a Repository Settings button where you can configure your repository settings and view associated remote repositories.
fetch¶
You can click the Fetch from Remote(s) button among the buttons on the right side of Git Graph, or Fetch From All Remotes next to the Source Control graph.
Sometimes it is useful to click Refresh to update the graph view if changes have occurred recently.
push¶
You can click the Push button among the buttons on the right side of the Source Control graph.
pull¶
You can click the Pull button among the buttons on the right side of the Source Control graph.
show && diff¶
You can click on a commit in the graph (in Git Graph or Source Control) to view all details of the corresponding commit.
You can click on a modified file in a commit to see the specific changes (similar to git diff).
stash¶
You can click the More Actions... button (three dots) that appears when you hover over CHANGES, then choose Stash. You can also use it for other commands we have seen previously.
checkout && branch¶
In the Git Graph extension, you can right-click on a commit message and choose Checkout or Checkout (Detached) in the Source Control graph.
Return to the most recent commit by right-clicking on the main branch icon (next to the most recent commit) in the Git Graph extension.
You can create branches by right-clicking on the commit from which you want to create the branch.
You can view all branches or a specific branch using the Branches option at the top of the Git Graph extension.
revert && reset¶
In the Git Graph extension, you can right-click on a commit message and choose Revert... or Reset current branch to this Commit....
Do not reset a synchronized commit!
Reminder!
merge¶
Create a
Lab11/directory and an emptyLab11/merge.txtfile, then synchronize this file so that it exists in both repositories.Locally, add
Hello World!on the first line of the file.On GitLab, use the Web IDE to add
Hi!on 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 and observe the diverging branches.
Right-click on the commit message from the remote branch and choose Merge into current branch... with the No commit option.
Open the
merge.txtfile.You can choose one of the options displayed above the conflict, or choose none and resolve the conflict yourself by replacing both versions with your own text, such as
Bye!.
You can also choose Open in merge editor, which appears at the bottom right. This will open three panels: two with the conflicting versions of the file and a third with the final version you will write.
Complete the synchronization with the merged version.
git merge --abort
git merge --abortgit pull performs the same operation as git fetch followed by git merge. If you forget to check the repository state before performing a pull or a merge, you can use git merge --abort to cancel the merge.
This option is not available in the VSCodium UI, so you must use the terminal.
Delete
merge.txtand synchronize your repositories.
Run and Debug¶
Why use a debugger?
When we try to understand an error in our code, we often manually add breakpoints in the code to:
display messages,
inspect variable values,
pause the program to understand how it works.
The problem with these manual breakpoints is that the code becomes polluted with code that does not contribute to the program’s execution (and that we must later remove), and that can potentially alter its behavior. Additionally, it is not easy to simulate a step-by-step execution of the program to understand how it works.
A debugger allows you to set breakpoints and observe the execution step by step without polluting the code.
Create the
Lab11/directory with the following files and contents.
Lab11/
├── include/
│ └── cesar-encoding.h
├── source/
│ ├── cesar-encoding.cpp
│ └── main.cpp
├── compile_flags.txt
└── makefile#ifndef CESAR_ENCODING_H
#define CESAR_ENCODING_H
#include <string>
class CesarEncoding {
public:
std::string encode(const std::string& message);
private:
int mKey = 3;
char encodeLetter(char letter);
};
#endif#include <string>
#include "cesar-encoding.h"
std::string CesarEncoding::encode(const std::string& message) {
std::string encodedMessage = "";
for (char letter : message) {
encodedMessage += encodeLetter(letter);
}
return encodedMessage;
}
char CesarEncoding::encodeLetter(char letter) {
letter += mKey;
return letter;
}#include <iostream>
#include "cesar-encoding.h"
int main() {
std::string message = "A message to encode";
CesarEncoding encoding;
std::cout << encoding.encode(message) << std::endl;
return 0;
}-xc++
-std=c++17
-IincludeEXECUTABLE = cesar-encoding
CXX = g++
CXXFLAGS = -std=c++17 -Iinclude
DEBUG_FLAGS = -g -O0
SOURCES = $(wildcard source/*.cpp)
OBJECTS = $(patsubst source/%.cpp,build/objects/%.o,$(SOURCES))
DEPENDENCIES = $(patsubst source/%.cpp,build/dependencies/%.d,$(SOURCES))
all: build/binaries/$(EXECUTABLE)
debug: clean
$(MAKE) all CXXFLAGS="$(CXXFLAGS) $(DEBUG_FLAGS)"
build:
mkdir -p build/objects build/dependencies build/binaries
build/binaries/$(EXECUTABLE): $(OBJECTS) | build
$(CXX) $(OBJECTS) -o build/binaries/$(EXECUTABLE)
build/objects/%.o: source/%.cpp | build
$(CXX) $(CXXFLAGS) -MMD -MF build/dependencies/$*.d -c $< -o $@
clean:
rm -rf build
run:
./build/binaries/$(EXECUTABLE)
.PHONY: all debug build clean run
-include $(DEPENDENCIES)To understand this code, we will use the Run and Debug mode in VSCodium.
make debug
make debugWe reused the same makefile as in Lab7 (without tests) and added the following lines:
DEBUG_FLAGS = -g -O0
debug: clean
$(MAKE) all CXXFLAGS="$(CXXFLAGS) $(DEBUG_FLAGS)"The -g and -O0 options are useful for the debugger:
-gcompiles the binary with additional information, such as line numbers, variable names, class structures, functions, etc.Compilers try to optimize the code, which means the structure of the compiled binary may differ from the source code. The
-O0option disables optimizations to preserve behavior consistent with the source code.
We also added the debug target, which first runs clean, since the entire code needs to be recompiled with DEBUG_FLAGS. It then runs make all while adding DEBUG_FLAGS to the compilation options CXXFLAGS.
Create a “Debug” task in
.vscode/tasks.jsonthat takeslabWithDebugas input, containing only["Lab11"]for now.Install the CodeLLDB extension by vadimcn.
CodeLLDB
This extension is a debugger mainly used for C++ and languages that rely on similar compilers.
Create the
.vscode/launch.jsonfile (which will be used by the extension) with the following content.
{
"version": "0.2.0",
"configurations": [
{
"name": "Lab11",
"type": "lldb",
"request": "launch",
"program": "${workspaceRoot}/Lab11/build/binaries/cesar-encoding",
"args": [],
"cwd": "${workspaceRoot}/Lab11",
"preLaunchTask": "Debug",
"terminal": "integrated"
}
]
}Run and Debug
In the Run and Debug tab in the left sidebar, you can now run the code for Lab11 by clicking the green Lab11 button. This button will launch the Debug task, which runs make debug, then executes the cesar-encoding binary with debugging information.
Create a breakpoint at line 7 of
cesar-encoding.cpp(encodedMessage += encodeLetter(letter);) by clicking the red dot that appears when you hover over the line number.Click the green Lab11 button next to RUN AND DEBUG (or press the shortcut F5) and select Lab11 when the Debug task is launched.
You will see the different VARIABLES appear on the left: you now have access to the inside of the encode function. Only the Local section is relevant for this exercise.
You can see the type of these variables by hovering over the variable name.
Debugger navigation
The program execution is now paused; you can control it using the debug toolbar:
The Continue button (F5) resumes execution, which will pause again when it reaches a breakpoint.
The Step Over button (F10) executes the program instruction by instruction.
The Step Into button (F11) steps into the execution of called (sub-)functions line by line (unlike Step Over, which executes
encodeLetter(letter)as a single instruction).The Step Out button (Shift + F11) exits the function you entered with Step Into.
The Restart button (Ctrl + Shift + F5) restarts execution.
The Stop button (Shift + F5) stops execution.
Answer the quiz questions using these navigation buttons.
On the left, you can see a WATCH section. Here, you can add expressions computed from the variables available in VARIABLES.
Add the expression
letter+mKeyto WATCH using the+button (Add Expression), then answer the quiz questions using this expression.
Conditional breakpoints
It is possible to make breakpoints conditional, since we do not always want to press Continue until execution reaches the moment of interest.
Right-click on the breakpoint and select Edit Breakpoint.... A drop-down menu provides several options:
Expression allows you to add a condition. Execution will pause at this breakpoint only if the condition evaluates to true.
Hit Count allows you to activate the breakpoint only after it has been hit a certain number of times.
Log Message displays a message in the DEBUG CONSOLE each time execution passes this point (called a logpoint). Unlike a breakpoint, execution does not stop. It behaves like a
print, which you are used to using for debugging. You can also display computed values using{}: for example,letter+mKey = {letter+mKey}will display “letter+mKey = <value>” each time execution passes this point.Wait for Breakpoint allows you to activate a breakpoint only after another breakpoint has been hit.
Use Expression, Hit Count, and Log Message to answer the quiz questions.
Additional information about breakpoints
You can of course combine conditions on breakpoints to debug your program. A few additional details:
You can right-click in the code to add an inline breakpoint, which is more precise than placing a breakpoint on a line.
You can right-click a breakpoint to disable it (Disable Breakpoint). You can also manage breakpoints in the BREAKPOINTS section of the left sidebar by checking or unchecking them (their location is shown on the right).
Finally, have you understood what this code does?
letter is a character, but you can add an integer to it because it also corresponds to a position in the ASCII table. Similarly, it is possible to convert an integer into a character (if it corresponds to a valid position in this table).
Breakpoint usage in a debugger.