- What is Version Control?
- What is Git?
- What is Github?
- What is a Repository?
- Installing Git on your Computer
- Creating SSH Keys
- Git Help
- Cloning a Repository
- Creating a new Repository
- Opening the Repository
- Creating a branch
- Making a change to the repository
- Committing the change
- Reversing a commit (Reverting)
- Merging a branch
- Pushing / Pulling Changes
- Conflicts
- Gitignore
- Practicing
- Resources
Version Control is something we use on a regular basis. It is how when ever we make a mistake we can go back to a previous version of the file.
This is the most basic form of version control. It is also the type we are most familiar with. Let's think of us writing an essay with a pencil and paper. We write the first draft, while reading we find a paragraph that didn't make too much sense. We erase the paragraph and rewrite it. We have just used version control.
We have one simple problem with 1-Dimensional Version Control. We can not go back to our first draft as we had erased it and written over it.
This is the exact same as when we are writing a word document or code. You can always Ctrl+Z to go back in the timeline. Once you edit a previous point in the timeline, the following points are erased.
This is the problem that 2-Dimensional Version Control solves. A simple solution most people do is create a copy of the file. This is a simple solution, but it is not a good solution. You end up with folders full of files that are all similar, but slightly different and all named.
What if instead of making copies we instead create a branch in the timeline. This allows us to go back to the previous point in the timeline, while also being able to go back to the current point in the timeline. With the added benefit of being able to merge the two timelines together at a later point.
Git is a version control system. It does pretty much the exact same thing we just talked about.
- We have a timeline of our project.
- We can create branches in the timeline.
- We can merge branches together.
- We can go back to previous points in the timeline.
Github is a website that hosts git repositories. It is a place where we can upload our timeline and branches. This allows us to share and collaborate on projects.
Github is not the only website that hosts git repositories. (Gitlab, Bitbucket, etc.)
A repository is a folder that contains all the files for a project. It also contains the timeline and branches for the project.
On Github you can see your repositories by clicking on your profile picture in the top right corner and clicking on "Your repositories".
You should be able to run the command:
git --version
If you get an error, you need to install git. You can download git from here. They also offer a tutorial on how to install git on your computer.
SSH Keys are used to identify your computer to Github. You can think of it as a digital signature. Github has a tutorial on how to create SSH Keys. As the tutorial goes over more than just creating SSH Keys, I will go over the steps here.
ls -la ~/.ssh
If you see a file ending in .pub
, you already have SSH Keys and can skip to Step 4.
You can of course create a separate SSH Key for Github, but it is not necessary.
ssh-keygen -t ed25519 -f "~/.ssh/Github"
Enter a passphrase when prompted. (You can leave it blank if you want.)
Your .ssh
folder should now contain two files:
Github
Github.pub
You will need to add a file called config
to your .ssh
folder.
I will be using the nano text editor, but you can use any text editor you want.
nano ~/.ssh/config
Add the following to the file:
Host github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/Github
If you have other keys and no config
file yet, you can add the other keys configurations too.
If you already have a config
file, you can add the above to the file.
You will need to add your SSH Key to Github.
You can upload your ssh key here.
ssh -T [email protected]
If you get a warning about the authenticity of the host, type yes
to continue.
If you get a message saying "Hi ! You've successfully authenticated, but GitHub does not provide shell access.", you have successfully set up your SSH Key.
You can learn more about the git commands by running the command:
git -h
You can also learn more about a specific command by running the command:
git <command> -h
Cloning a repository is how we download a repository from Github to our computer. This is the first step in working on a project from other people. We first need to get the clone link from Github. You can find the clone link by clicking on the green "Code" button on the repository page. Select the SSH option and copy the link.
Now we can clone the repository.
git clone <link>
As an exercise we will clone this repository.
git clone [email protected]:Nautilus-UUV/github_introduction.git
If you typed a passphrase when creating your SSH Key, you will be prompted to enter it.
You will now have a folder called github_introduction
in your current directory.
Sometimes you don't want to clone a repository.
You want to create a new repository.
On Github click on the New
button on the repositories page.
You can then give the repository a name and select if you want it to be public or private.
Most of our repositories will be private as they contain code we don't want to share with the world.
You can also add a description to the repository.
You can also create a folder on your computer and run the command:
git init
This will start tracking the folder with git. You can then add the remote (server) repository with the command:
git remote add origin <link>
For pushing / pulling changes you can look at this section
You can open the repository in your favourite IDE. I will be using Jetbrains Pycharm, so Pictures will be from Pycharm. Jetbrains IDEs can be downloaded for free with a student email here.
We can now use our first git command.
git log
This will show us the timeline of the repository.
You can use the arrow keys to scroll up and down, and press q
to exit.
With Jetbrains IDEs you can also see the timeline in the bottom left corner under the git
tab.
Each point in this timline is called a commit. A commit is a point in the timeline where we have made a change to the repository.
We can now create a branch.
git branch <branch_name>
We can now switch to the branch.
git checkout <branch_name>
Alternatively we can create and checkout a branch with one command.
git checkout -b <branch_name>
For this exercise create a branch with your name.
In Jetbrains IDEs you can create a branch by clicking on the git
tab in the bottom left corner.
You click the commit you want to branch from and click New Branch
.
In Jetbrains the new branch will automatically be checked out (you can se the checked out branch with the price tag icon).
You can checkout a branch by clicking on the branch name and selecting the branch you want to check out.
You can now see the branch in the bottom left corner.
We can make changes to any of the branches. It is important to note often you will have something called "main" or "master" protection. This means you can not make changes to the main branch. You will need to create a branch and make changes to that branch. This is to prevent people from making changes to the main branch without review, as the main branch is often the branch that is deployed / used.
As an exercise we will be making a new file.
Create a new file called <your_name>.txt
in the github_introduction
repository.
Per default git will not track this file.
We can see this by running the command:
git status
The file should be in the untracked files section.
To add it to the tracked files we can run the command:
git add <file_name>
We can now see the file in the staged files section.
You can also stage all untracked files with the command:
git add .
On Jetbrains IDEs after creating the file you will get a popup asking if you want to add the file to git.
Or you can always later right click on the file and select Git -> Add
.
For any major change we made to the repository we want to create a commit. This includes stuff like:
- Adding a new file
- Deleting a file
- Changing a file
- Fixing a bug
- Adding a feature
- etc. You should always create a commit for each of these changes alone. Do not cluster them together. This makes it easier to find the commit that introduced a bug.
To commit the change we can run the command:
git commit -m "<commit_message>"
The commit message should be a short description of what the commit does. For example:
- "Added <file_name>"
- "Fixed bug in <file_name>"
- "Fixed problem <issue_id> in <file_name>"
- "Added feature <feature_name>"
- etc.
On Jetbrains IDEs you can commit by clicking on the commit
tab in the left side bar.
Here you can see the files that have been changed.
You can select the files you want to commit.
Once you have commited you can check the git log
and you should be able to see your commit.
Sometimes we make a mistake and want to undo a commit. We can either: revert the commit, or, create a new branch starting from a point before the mistake was made.
As you already know how to create a branch, we will go over how to revert a commit.
To revert a commit we first need to find the commit we want to revert. We can look at the log and find the commit we want to revert. We can then copy the commit hash. This is the 8 character long string in the commit message.
We can now revert the commit.
git revert <commit_hash>
This will create a new commit that reverts the changes made in the commit we specified.
In Jetbrains IDEs you can revert a commit by right-clicking on the commit and selecting Revert Commit
.
As an exercise, revert the commit you just made.
Once we are done with the changes we made in a branch, we want to merge it back into the main branch. This is done by creating a pull request. A pull request is a request to merge a branch into another branch. This is done so that someone else can review the changes before they are merged.
A pull request is created on Github.
You can go to the Pull requests
tab on the repository page and click New pull request
.
You can then select the branch you want to merge into the main branch.
You can then add a title and description to the pull request.
You can also add reviewers to the pull request.
Once you are done you can click Create pull request
.
Sometimes we want to merge a branch without a pull request. This is often the case when we are merging a branch into our own branch. For example when we are merging the new bug fix on the main branch into our feature branch.
To merge a branch we first need to checkout the branch we want to merge into. Then we can run the command:
git merge <branch_name>
This will merge the branch into the branch we are currently on.
As an exercise merge your branch into the main branch. So checkout the main branch and merge your branch into the main branch.
Once we have merged the branch we can delete the branch (if we don't need it anymore). As an exercise delete your branch.
git branch -d <branch_name>
Rebasing is a tool to change the history of a given branch.
As an example: If you work for a longer time in a seperate branch, there is the possibility that the master/main branch get updated in the mean time. To keep the branch updated one can use git rebase <branch_name>
to update the commits of the current branch with the commits made on another branch (use git rebase origin/<branch_name>
to update your branch with respect to the remote branch.
As changing the history of a branch somewhat conflicts with the general idea of git versioning. Differing remote and local branches can require git push --force
in order to push the new history to the remote repo. Only force push if you are completly sure about your changes!
We are now done with the changes we made to the repository. We want to upload the changes to Github so that other people can see them. This is done by pushing the changes to Github. We can push the changes by running the command:
git push
This will push the changes to the branch we are currently on. This will make the branch on Github the same as the branch on our computer.
If we want to get changes our colleagues have made we can pull the changes. This is done by running the command:
git pull
On Jetbrains IDEs you can push and pull by clicking the Arrows in the top right corner.
Sometimes when we pull, push or merge we get a conflict. This is no reason to panic. This is a normal part of working with git. A conflict happens when git can not automatically merge the changes. For example when two people have changed the same function in a file.
This means we have to manually select which changes we want to keep. We can do this by opening the file in our favourite text editor. We will see something like this:
<<<<<<< HEAD
This is the change I made
=======
This is the change my colleague made
>>>>>>> <branch_name>
We can now select which change we want to keep.
Once we are happy with the changes we can save the file.
We can then add the file again to git with git add
and commit the changes.
Jetbrains IDEs have a built in tool to help with conflicts.
If you want to see a conflict, create a two new branches.
In both branches create a new file called conflict.txt
with different content.
Merge one branch into the other branch.
You should now have a conflict.
Once you have resolved the conflict, push the changes to Github.
The timeline should now look something like this:
If you want to see some conflicts while pushing. Have a colleague push some changes to the same file you are pushing to.
Sometimes we have files we don't want to track with git. For example:
- Files that are created when we run our code (Like log files).
- Files that contain sensitive information.
- Files that are created by our IDE.
- etc.
We can tell git to ignore these files by creating a .gitignore
file.
The exact syntax of this file can be found here.
If you want to practice even more there are some resources I can recommend:
this is a showcase