Practical Git Tutorial For Beginners
A practical approach to learning about git and version control
What is Git ?
Git is the most widely used version control system in the world today. Designed by Linus Torvalds, an enomous amount of projects depend on it for version control. According to the official git website,
git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency
Ok. Now you might be asking, “what is a version control system? And what does distributed mean in this context?”. Let’s go down the rabbit hole a bit starting with “version control system”.
Version control systems are software tools that help software teams or individuals keep track of every change/modification to their software product over time.
A distributed version control system is a type of version control system that doesn’t exist only in one location. This is to say that every member of a software team using git will posses a copy of the history of all the changes made to the project over time.
Why is version control important?
Consider this basic example. Assume you are currently at the job seeking stage of your career and you plan on applying to 10 different organisations with very different application requirements (maybe organisation 1 requires just a cv and organisation 2 requires both cv and cover letter, etc). You also plan on tailoring the different applications for each organisation. This is the likely scenario that would play out.
You create a folder name company1, and put the cv written for company1 inside the folder.
Then you create a second folder named company2, with cv and cover letter for company2.
Then you create a third folder, and a fourth, and a fifth, each containing varying number of files.
You can easily end up having more than 50 files flying around everywhere, at which point, it becomes really painful tracking the changes made to these files. Keep in mind that we only assumed you are the only one working one these files. What happens if you ask a friend to help you review these application documents and maybe make corrections?
This is a very basic example and a relatively harmless one. When you are working with software code-bases, the stakes are a whole lot higher. It even gets nastier when you have many developers working on the same code base, this is exactly the kind out situation where git shines.
This tutorial is designed to be both practical and theoretical in approach. To get the best out of this tutorial, I designed two exercises to help you fully grasp the concept behind git. First try to complete the manual version control exercise, then complete the git version control exercise in parallel with the rest of the tutorial (this tutorial and the “git version control exercise” are designed to compliment each other. With this tutorial being the more theoretical half while the exercise serves as the practical half of the whole tutorial. When you have completed this tutorial, you might want to check out this practical tutorial on how to contribute to open-source projects
Manual Version Control Exercise
- To get the full instruction, fork this repository
- clone the forked repository, open the exercises folder then open the manual_version_control_exercise folder and open the README.md file. At the end of the course, consider testing your knowledge through contributing to this repository by adding your name to first-contributions.md file, following this tutorial. If you didn’t understand any of the things I just said, don’t worry, you will learn all you need to do them in this course.
Git Version Control Exercise
- To get the full instruction, fork this repository
- clone the forked repository, open the exercises folder then open the git_version_control_exercise folder and open the README.md file. At the end of the course, consider testing your knowledge through contributing to this repository by adding your name to first-contributions.md file, following this tutorial . If you didn’t understand any of the things I just said, don’t worry, you will learn all you need to do them in this course.
Before going any deeper into this tutorial, there are a few helpful stuffs you need to be aware of so as not to feel lost.
Staging Area and Commits
- The staging area is place where changes that will be written into the git object database during the next commit are placed.
- Commit is the act of writing recent changes into the git object database
Branches, Head, Tags
- A Branch is a dynamic reference/pointer to a commit
- The Head is a dynamic reference/pointer to the current/active branch
- A Tag is a static reference/pointer to a commit
The difference between a branch and a tag is that while the commit a branch points to can change (the branch can point to another commit), a tag always and forever will point to the same commit
The difference between The Head and a Branch is that while The head can point to either a branch or a commit, a branch will always point to a commit (branches cannot point to fellow branches or tags). Also, while you can have multiple branches in a git repository, you can only have one Head.
Three Golden Rules of Git
- The current branch tracks new commits
- When you move to another commit, git updates your working directory
- Unreachable objects are garbage collected
13 Git Commands Every Developer Must know
1. clone 2. init 3. status 4. log 5. add 6. commit 7. branch 8. checkout 9. Merge 10. remote 11. fetch 12. pull 13. push
The “git clone” command is used to copy a remote repository that is accessible over the internet into your local machine
git clone <remote repository url>
Running the above command effectively creates a copy of the remote repository on your local machine
“git init” is the first git command you run to initiate an empty git repository
Running the above command creates a “.git” folder in your current working directory. This “.git” directory is the git repository
The “git status” command gives us all necessary information about the current branch
With git status, we can know whether there are un-tracked files, Unstaged files, staged files, whether our branch is up to date, etc
The “git log” command shows us the history of our repository branch, commit by commit
The “git add” command is used to add changes made to a file to the staging area. Only changes that have been added to the staging area will be committed to git during the next commit
git add <file_name>
To add all recent changes:
git add .
The command “git commit” does two main things, it stores the changes made to the staged files in the git object database and it creates the commit file that points to those new objects
git commit -m “<your commit message here>”
Always write a clear and concise commit message. It will make your life easier
When you create your first commit, git automatically creates the very first branch that will point to your commit. This branch is the master branch. Note that “head” is not a branch but the reference that keeps track of the current branch just like branches keeps track of commits
The git branch command is the command that is used for creating, listing and deleting branches in git. Syntax to create a new branch:
git branch <branch_name>
Syntax to list all branches:
Syntax to list all branches including remote branches:
git branch -a
Syntax to delete a branch:
git branch -d <branch_name>
The “git checkout” command does two main things, it changes the branch or object the HEAD is pointing to and it updates your working directory to reflect the the state of git based on the content your active commit is pointing to. When I say active commit here, I mean the commit that the branch you checked-out to is pointing at.
git checkout <branch_name>
Note that git checkout can automatically create a new branch and checkout to it at the same time using the command:
git checkout –b <new_branch_name>
In this case, you wouldn’t have to use git branch first to create the branch
Note that you can checkout directly to commit by running:
git checkout <the shaa-1 of the commit>
If you directly checkout to a commit instead of a branch, you git repository enters a “detached head” state. (see the image below for how that looks)
The “git merge” command is used to merge a branch into another. This is useful in cases where you believe your mission for spinning off a new branch was successful and now you want to merge all the changes into the main branch
git merge <branch_to_merge>
Note that to merge branch A into branch B, you should first checkout to branch B, then run “git merge branch A”. The same if you want to merge branch B into branch A.
If you are following the exercise instructions on our Github repo, at this point you are going to have a merge conflict. Don’t panic, its very normal. A merge conflict is what happens when you make changes to the same file in two different branches and try to merge the two branches. Since we have two different versions of the same file in the two branches, git can’t decide which version you want to choose over the other or if you just want to combine the two versions into a single file, so it pauses the merge process and tells you to manually edit the affected file and “git add, git commit –m <commit_message>” it again to complete the merge process
Merge conflict resolution
Merge conflicts doesn’t happen all the time, but when they do, they are annoying. To fix a merge conflict, open the file that has the merge conflict (git is going to point out the file in the merge conflict message). In our case, the file looks something like:
Hello git world!, This is my cv
git is fun!
git is for everybody
To fix the conflict, we have to remove everything we wouldn’t want to see inside the file. In our case, we removed "<<<<<<< HEAD","=======" and ">>>>>>> cv_and_cover-letter“ to have something like this:
Hello git world!, This is my cv
git is fun!
git is for everybody
After removing them, just run “git add .” and “git commit –m <commit_message>” to complete the merge like so:
git add .
git commit -m “fixed a merge conflict”
Note that merge conflicts only happen when you make changes to the same file in the two branches you want to merge.
On a successful merge, the branch you where on when you ran “git merge” command will move to point to the merge commit (commit 3 in our case).
Incase you want to merge master to branch cv_and_cover-letter as well, you can checkout to cv_and_cover-letter branch and run “git merge master”. In this case, we won’t have any merge conflict (we already fixed all merge conflicts when we merged cv_and_cover-letter into master) and cv_and_cover-letter will just be moved to point at the merge commit (commit 3) without doing any further work. This is called fast-forward in git.
The “git remote” command is the command that is used to view information about the remote repositories that we can interact with from our local repository.
To view more information about the remote repositories (like there urls), add the verbose parameter like so:
git remote –v
If your local repository was created from scratch (using git init), the “git remote” command would return nothing. To add a new remote repository to your local repository’s remote, use the command:
git remote add <remote_name> <remote_repo_url>
The “git fetch” command is used to fetch recent changes that are not currently on your current branch, from a branch of a remote repository to your current branch.
git fetch <remote_name> <remote_branch_name>
When you run this command, if there are changes in the remote branch that are not on your local branch, git fetches those changes for you. Now all you have to do is “git add” and “git commit”
Note that you have to be on the branch you want to fetch recent changes into before running the “git fetch” command
The “git pull” command is an extension of the “git fetch” command. It does all the things that the “git fetch” command does, plus it also commits the fetched changes for you without you having to run “git add” and “git commit” again to commit the changes.
git pull <remote_name> <remote_branch_name>
You can as well pull changes from another local branch into your current branch by running the command:
git pull . <local_branch_name>
The “git push” command is like the inverse of “git pull”. It is used to push the changes made to a local branch that is not currently in a remote branch to the remote branch.
git push <remote_name> <remote_repo_branch_name>
If the branch doesn’t already exist on the remote repository, add the “-u” parameter like so:
git push –u <remote_name> <remote_branch_name>
Where to go from here
Now that we are done learning the basics of git and the most important git commands to know, you should consider learning how to make your first contributions to open-source projects by contributing your name to the "first- contributions.md" file of the practice repository we used for this tutorial. Follow this link to get started