Skip to content

Version Control With GitHub

Version control is extremely important for storing CAD files and software files, and is essential when working on a shared project with other people. The most popular version control system is Git, an open-source project, which is often paired using GitHub, developed by Microsoft, as a remote host.

Firstly, we need to check if we have Git installed on our system.

Open the terminal with Ctrl-Alt-t, then run

Terminal window
git -v
# output should be something like:
git version x.xx.x

If the output is not what is specified above, install Git with one of the following commands then follow the instructions.

Terminal window
# Ubuntu/Debian
sudo apt-get install git
# Fedora
sudo dnf install git

Now, you should be able to use Git from any terminal session on your computer.

If you don’t already have a Github account, create one at github.com. Use your personal email to create this account, NOT a school or organization one.

Click on your profile icon in the top right, then click profile

Get to profile

Once inside your personal page, click New Repository. Then enter a name for the repo, and click Create Repository

Create Repo

In the settings menu of your GitHub account, go to Developer Settings->Personal Access Tokens->Tokens(classic).

You should see an option to generate a new token.

Generate PAT

Click on it and select Generate New Token (classic)

Classic mode token gen

You will be prompted for a password, and then will see this screen:

Set Permissions for PAT

Generally, it is best to select only the scopes, or permissions, that you need and are going to use when generating your Personal Access Token (PAT). However, that is beyond the scope of this guide, so for now select all of the scopes (you can change this later), or read about scopes more here.

Once you have selected your scopes, scroll down to the bottom and click Generate Token. Once it is generated, copy it, because it will only be shown to you once.

To safely load our credentials, we use the Github Credential Manager (or this link for Github’s guide to the GCM).

To install the GCM on Linux, we can use the script provided by the GCM repo. You will prompted for your password.

Terminal window
curl -L https://aka.ms/gcm/linux-install-source.sh | sh
git-credential-manager configure

The GCM by default doesn’t save our credentials to disk, so to store them securely (encrypted), we can set the store to use GPG encryption.

Terminal window
git config --global credential.credentialStore gpg

Using GPG as the store, however, requires some additional setup. We need to use the pass utility, which in turns requires a GPG keypair.

Terminal window
# generate GPG keypair
gpg --gen-key

Follow the prompts, and make sure to remember the password you set. The final ouput should be something like this:

public and secret key created and signed.
pub ed25519 yyyy-mm-dd
<GPG-ID>
uid Your-name <Your Email>
sub cv25519 yyy-mm-dd

Then, generate your stored passkey using the GPG-ID outputted.

Terminal window
pass init <GPG-ID>
# you will be prompted for your password.

By default, the GCM with GPG only caches your credentials for a period of 10 minutes, so increase this to 2 hours, find or create the file ~/.gnupg/gpg-agent.conf and add:

default-cache-ttl 7200
max-cache-ttl 7200
allow-loopback-pinentry

Now that the GCM is configured, the next time you do a Git action that requires authentication, such as pushing to a repo on GitHub, you will be prompted for your PAT and accompanying password. The credentials will be stored, and the only thing you will have to do is periodically re-enter your password.

To start, open your projects folder. If you do not have one, it is generally good practice to put it in /home/<user>/Documents/projects. Open the terminal, then navigate to the project folder

Terminal window
mkdir /home/<user>/Documents/projects # if you do not yet have a projects folder
cd /home/<user>/Documents/projects # navigate to the projects folder

From there, clone the repository

Terminal window
git clone https://github.com/<your-username>/hello-repo.git
# this will create a subfolder within your projects folder, so you can navigate as such
cd ./hello-repo

Committing in Git is the act of saving a snapshot of the changes of a project since the previous save.

Terminal window
# this will stage all changes into the commit, which may not always be wanted
git commit -a

Upon entering this command, Git will enter your terminal session into a text editor such as nano or vi. It will prompt you to enter in a commit message, after which you need to exit the text editor and save the buffer.

Some common methods of saving exiting the text editors are:

Nanotype Ctrl-x then Y
Vitype :w then :qa
NotepadSave then exit in top right

Comitting, however, does nothing on its own. First, you need to stage files.

You can think of your GitHub repo as three distinct areas. First you have your working directory, where the moment-to-moment changes you make live. Next is the staging area, where you can pick and choose files to prepare for commit. Finally, we have the repo itself, which keeps tracks of commits, which are bundles of staged changes.

To stage files, you can use the git’s add command.

Terminal window
git add /path/to/file.py
# or to add all unstaged files
git add .

You can see the current staging status of your project as such:

Terminal window
git status

To restore a file to the state of the last commit, you can use the restore command.

Terminal window
git restore /path/to/file.py
# to restore all files
git restore .

If you want to never track or commit a file, keeping it out of a repo, create a file called .gitignore in the top-level directory of your project. On each new line, enter the file pattern which you do not want to track. For example, if you didn’t want to commit build files in build/, or didn’t want to commit your .env file, or didn’t want any json file:

.gitignore

build/
.env
*.json

All of the commits you have done so far have been on your local copy of the repository. You can fetch the latest Git details (such as latest commit on the remote repo) as such:

Terminal window
git fetch origin

Before doing any major git operation, such as pushing, pulling commits, and merging, creating, or deleting branches, it is good practice to fetch from origin.

You can update your local copy with the latest changes by pulling from the repo

Terminal window
# `origin` refers to the remote repo hosted by GitHub
# `main` refers to the fact that the main branch on your local repo is set up to track the main branch on the remote repo.
git pull origin/main

You can update the remote host with your changes by pushing to the repo.

Terminal window
git push origin/main

According to the Git website, branching is the act of diverging from the main line of development to continue to do work without messing with the main line.

In practice, this means that a branch is effectively a copy of a snapshot of another branch at a specific point in time, on which you can commit, push, pull, and do all of the regular Git operations on. This allows multiple different features to be developed independently of each other, and merged when they are ready, as well as enabling CI/CD pipelines.

For our purposes, we can create branches in two ways: using the GitHub remote repo, or purely on the command line.

First, go to the home page of your GitHub repository, then click on the icon which says <num> branches.

Navigate GitHub to find branch menu

This will take you to the branches page, where you can create a branch by clicking on the green button in the top right labeled create new branch. A submenu will pop up asking your for a name for the new branch

Create branch

Now that the new branch is created it only exists on the remote repo, so use Git’s checkout command to set up a local version of the branch,

Terminal window
git fetch origin
git checkout new-branch

Similarily, after a branch is deleted on GitHub, you can delete it locally do as such:

Terminal window
git fetch origin --prune # prune fixes the remote pointers stored in git locally
git branch -D new-branch

Having different branches isn’t much use if they stay separate forever. To solve this issue, we can merge branches together.

For example, if we want to merge a branch new-branch into the branch main, we would do as such:

Terminal window
# switch to main branch
git checkout main
# merge new-branch into main
git merge new-branch

While this merges the changes from new-branch into main, new-branch still exists. There can often be use in leaving the branch alive, however for our purposes we can go ahead and delete this.

When trying to merge a branch, you may see a message that there are conflicts which have prevented the merge, and a list of files which contain conflicts. This is a merge conflict. Merge conflicts occur when the changes in one branch conflict with the changes in another branch since the branches diverged.

To resolve the merge conflict, open the file with the merge conflict in your favourite text editor, such as VSCode, nano, vim, etc.

Conflicts are marked with these markers: <<<<<<<, =======, and >>>>>>>.

This code is from
<<<<<<< HEAD
The branch recieving the merge
=======
The branch being merged
>>>>>>> new-branch

Delete the conflict markers and make the changes you want in the final merge. Once this is done for all files, stage your changes and create a commit to resolve the merge conflicts.