flowchart LR
A[Version 1] --> B[Version 2] --> C[Version 3]--> D[...]
gitgit repositorygit implements the main features of version controlVersion control is an approach to coding that allows you to keep track of the code evolution.
You may think of coding as a linear process, where a first version is followed by another more advanced version, which is again followed by a successive more refined version and so on.
flowchart LR
A[Version 1] --> B[Version 2] --> C[Version 3]--> D[...]
This is not at all the case. In fact, as we develop our code we tyically try various ideas, similarly to what you would do if you were writing a novel, perform an experiment, or explore an uncharted territory.
flowchart LR
A[Version 1] --> B
B[Version 2] --> C[Version 3]--> D[...]
A-->Aa[Variant 1.a]-->B
A-->Ab[Variant 1.b]-->E[Alternative version 2]-->C
This is even more evident when collaboration is at play: different developers will try different approaches and require a system to keep track of their respective modifications and that helps them with bringing them together into a unified project. In fact, regularly, the various ideas need to come together and merge for the project to keep its unitary structure.
Version control tools serve precisely this purpose, and git is the most popular of such tools.
It is powerful, but its usage can be subtle at times, as illustrated by the following cartoon:

Version control therefore solves two problems:
We are going to focus mostly on the first part, but it is important to realise that git is an essential tool for code development in large projects.
Version control use repositories. These are a database of code versions, stored in an efficient manner, focusing on the changes between a version and another.
Each user of the repository has their own working copy of all the files (any kinds of files) of the project. This clone of the repository is typically stored on the local machine.
Changes to the local clone are not reflected in the repository unless the users explicitly require this to be the case.
In distribute version control each user has a complete copy of the repository, and they can perform their changes independently from other users, work locally and offline and eventually do collaborative work by merging their own versions with the one of others.
In principle, this can be done without a central server (e.g. peer to peer). In practice, one often uses some form of online repository, e.g. Github, Gitlab etc.
Branching in git allow you to explore various ideas in parallel, developing in different directions and experimenting new features. Branching is a backbone ides in git.
A repository typically has a main branch where the functional code is stored. When we want to develop our code we create new feature branches
%%{init: { 'logLevel': 'debug', 'theme': 'default' , 'themeVariables': {
'git0': '#ff0000',
'git1': '#00ff00',
'git2': '#0000ff',
'git3': '#ff00ff',
'git4': '#00ffff',
'git5': '#ffff00',
'git6': '#ff00ff',
'git7': '#00ffff'
} } }%%
gitGraph
commit id: "main"
branch feature
commit id: "main work"
checkout feature
commit id: "feature work"
checkout main
commit id: "more main work"
merge feature
On every branch, we can store out individual advancements as commits (see below). Eventually, when we are happy for our feature to be integrated with the main branche, we merge the feature branch with the main branch.
When you want a change to be registered in the repository’s database, your commit your changes to the repository. This means that a new entry in the database is added, keeping track of a timestamp associated with your changes and (often) an explanatory description of what the modification entails.
If you also have a remote repository (e.g. on GitHub), you can synchronise the changes between the local branch and the remote branch via the push operation.
Fetch allows you to retrieve the changes from a remote repository, see them and decide whether to merge such changes with your local repository (or not).
Pulling is simply fetching, followed by automatic merging.
An efficient way to produce a package out of a git repository is to construct a bundle. This is a single file that contains a collection of commits, branches and logs allowing you to transfer or store the repository’s content without requiring access to a remote server.
git works, adapted from https://homes.cs.washington.edu/~mernst/advice/version-control.html ↗️gitWe start off working locally and creating a local project.
Previously, you should have created a project folder with a README.md file. We now want to setup our local git repository.
Task 1: initialise the repository
Go to the project folder vicsek-cpp and initialise the git repository.
Use the information above or git --help to find the correct command to use.
Task 2: create a .gitignore file and add it to the staging area
We want to tell git not to keep track of specifc files. For, example we want to ignore hidden files that are specific to MacOS. A hidden file/folder haas a name that starts with . .
To provide git with a list of files to ignore, we create a (hidden) configuration file inside vicsek-cpp called .gitignore.
Create such file and enter the following string
.DS_Store
Then add the .gitignore file to the staging area.
Check git status to see if your .gitignore is ready to be committed and then commit it with a suitable comment.
You should also get a message concerning your README.md file. What os the best course of action here?
Task 3: ignoring files and directly committing the changes
Suppose now that we also want to ignore all files that end with .txt. The .gitignore file accepts the wildcard *.
Modify the .gitignore to ignore all .txt files. With a suitable option to the git commit command, stage and commit the changes in a single go.
Then create two new files:
notes.txt filenotes.md fileAdd all new files in the current folder with git add ., commit your changes to the repository and then check the files added to the repository with git ls-files.
Is notes.txt in your list?
Task 4: branching
We want to now start developing our code. For this purpose, we create a new branch called develop. To do so we use the command
To check which branches now exist in your repository just type
A * should appear on the branch you are on (which should be main). You leave the view using theQ key on your keyboard.
To switch to the develop branch use
Check that you are on the right branch now (see above).
Once you are on your develop branch, create a new folder src where we will put the C++ code (do not remember how to create a folder? go back to Using the shell).
Inside src, create our C++ main file main.cpp, e.g. using a suitable editor (e.g. nano , pico or vim).
The minimal content should be the following
Now, add the src folder with its content to the git repository and commit the changes.
Switch back to the main branch: what happened to the src folder?
Task 4: merging
Now that you have your develop branch set up, attempt to merge it back with the main branch using the git merge command. If you are not sure about how to use it, check the documentation with git merge --help.
Task 5: bundling
Use now the command
to create a single bundle file conatining all of the repository. Move it to another folder (or even another machine with git, e.g. your Noteable account) and unpack it with
Can you check the branch structure? and the status?